xref: /reactos/dll/win32/lsasrv/srm.c (revision 1734f297)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     Local Security Authority Server DLL
4  * FILE:        dll/win32/lsasrv/srm.c
5  * PURPOSE:     Security Reference Monitor Server
6  *
7  * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
8  */
9 
10 /* INCLUDES ****************************************************************/
11 
12 #include "lsasrv.h"
13 #include <ndk/ntndk.h>
14 
15 /* GLOBALS *****************************************************************/
16 
17 HANDLE SeLsaCommandPort;
18 HANDLE SeRmCommandPort;
19 
20 /* FUNCTIONS ***************************************************************/
21 
22 static
23 VOID
24 LsapComponentTest(
25     PLSAP_RM_API_MESSAGE Message)
26 {
27     ERR("Security: LSA Component Test Command Received\n");
28 }
29 
30 static
31 VOID
32 LsapAdtWriteLog(
33     PLSAP_RM_API_MESSAGE Message)
34 {
35     ERR("LsapAdtWriteLog\n");
36 }
37 
38 static
39 VOID
40 LsapAsync(
41     PLSAP_RM_API_MESSAGE Message)
42 {
43     ERR("LsapAsync\n");
44 }
45 
46 static
47 DWORD
48 WINAPI
49 LsapRmServerThread(
50     PVOID StartContext)
51 {
52     LSAP_RM_API_MESSAGE Message;
53     PPORT_MESSAGE ReplyMessage;
54     REMOTE_PORT_VIEW RemotePortView;
55     HANDLE MessagePort, DummyPortHandle;
56     NTSTATUS Status;
57 
58     /* Initialize the port message */
59     Message.Header.u1.s1.TotalLength = sizeof(Message);
60     Message.Header.u1.s1.DataLength = 0;
61 
62     /* Listen on the LSA command port */
63     Status = NtListenPort(SeLsaCommandPort, &Message.Header);
64     if (!NT_SUCCESS(Status))
65     {
66         ERR("LsapRmServerThread - Port Listen failed 0x%lx\n", Status);
67         return Status;
68     }
69 
70     /* Setup the Port View Structure */
71     RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
72     RemotePortView.ViewSize = 0;
73     RemotePortView.ViewBase = NULL;
74 
75     /* Accept the connection */
76     Status = NtAcceptConnectPort(&MessagePort,
77                                  0,
78                                  &Message.Header,
79                                  TRUE,
80                                  NULL,
81                                  &RemotePortView);
82     if (!NT_SUCCESS(Status))
83     {
84         ERR("LsapRmServerThread - Port Accept Connect failed 0x%lx\n", Status);
85         return Status;
86     }
87 
88     /* Complete the connection */
89     Status = NtCompleteConnectPort(MessagePort);
90     if (!NT_SUCCESS(Status))
91     {
92         ERR("LsapRmServerThread - Port Complete Connect failed 0x%lx\n", Status);
93         return Status;
94     }
95 
96     /* No reply yet */
97     ReplyMessage = NULL;
98 
99     /* Start looping */
100     while (TRUE)
101     {
102         /* Wait for a message */
103         Status = NtReplyWaitReceivePort(MessagePort,
104                                         NULL,
105                                         ReplyMessage,
106                                         &Message.Header);
107         if (!NT_SUCCESS(Status))
108         {
109             ERR("LsapRmServerThread - Failed to get message: 0x%lx\n", Status);
110             ReplyMessage = NULL;
111             continue;
112         }
113 
114         /* Check if this is a connection request */
115         if (Message.Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
116         {
117             /* Reject connection request */
118             NtAcceptConnectPort(&DummyPortHandle,
119                                 NULL,
120                                 &Message.Header,
121                                 FALSE,
122                                 NULL,
123                                 NULL);
124 
125             /* Start over */
126             ReplyMessage = NULL;
127             continue;
128         }
129 
130         /* Check if this is an actual request */
131         if (Message.Header.u2.s2.Type == LPC_REQUEST)
132         {
133             ReplyMessage = &Message.Header;
134 
135             switch (Message.ApiNumber)
136             {
137                 case LsapAdtWriteLogApi:
138                     LsapAdtWriteLog(&Message);
139                     break;
140 
141                 case LsapAsyncApi:
142                     LsapAsync(&Message);
143                     break;
144 
145                 case LsapComponentTestApi:
146                     LsapComponentTest(&Message);
147                     break;
148 
149                 default:
150                     ERR("LsapRmServerThread - invalid API number: 0x%lx\n",
151                         Message.ApiNumber);
152                     ReplyMessage = NULL;
153             }
154 
155             continue;
156         }
157 
158         ERR("LsapRmServerThread - unexpected message type: 0x%lx\n",
159             Message.Header.u2.s2.Type);
160 
161         /* Start over */
162         ReplyMessage = NULL;
163     }
164 }
165 
166 NTSTATUS
167 LsapRmInitializeServer(VOID)
168 {
169     UNICODE_STRING Name;
170     OBJECT_ATTRIBUTES ObjectAttributes;
171     SECURITY_QUALITY_OF_SERVICE SecurityQos;
172     HANDLE InitEvent;
173     HANDLE ThreadHandle;
174     DWORD ThreadId;
175     NTSTATUS Status;
176 
177     /* Create the LSA command port */
178     RtlInitUnicodeString(&Name, L"\\SeLsaCommandPort");
179     InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL);
180     Status = NtCreatePort(&SeLsaCommandPort,
181                           &ObjectAttributes,
182                           0,
183                           PORT_MAXIMUM_MESSAGE_LENGTH,
184                           2 * PAGE_SIZE);
185     if (!NT_SUCCESS(Status))
186     {
187         ERR("LsapRmInitializeServer - Port Create failed 0x%lx\n", Status);
188         return Status;
189     }
190 
191     /* Open the LSA init event */
192     RtlInitUnicodeString(&Name, L"\\SeLsaInitEvent");
193     InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL);
194     Status = NtOpenEvent(&InitEvent, 2, &ObjectAttributes);
195     if (!NT_SUCCESS(Status))
196     {
197         ERR("LsapRmInitializeServer - Lsa Init Event Open failed 0x%lx\n", Status);
198         return Status;
199     }
200 
201     /* Signal the kernel, that we are ready */
202     Status = NtSetEvent(InitEvent, 0);
203     if (!NT_SUCCESS(Status))
204     {
205         ERR("LsapRmInitializeServer - Set Init Event failed 0x%lx\n", Status);
206         return Status;
207     }
208 
209     /* Setup the QoS structure */
210     SecurityQos.ImpersonationLevel = SecurityIdentification;
211     SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
212     SecurityQos.EffectiveOnly = TRUE;
213 
214     /* Connect to the kernel server */
215     RtlInitUnicodeString(&Name, L"\\SeRmCommandPort");
216     Status = NtConnectPort(&SeRmCommandPort,
217                            &Name,
218                            &SecurityQos,
219                            NULL,
220                            NULL,
221                            NULL,
222                            NULL,
223                            NULL);
224     if (!NT_SUCCESS(Status))
225     {
226         ERR("LsapRmInitializeServer - Connect to Rm Command Port failed 0x%lx\n", Status);
227         return Status;
228     }
229 
230     /* Create the server thread */
231     ThreadHandle = CreateThread(NULL, 0, LsapRmServerThread, NULL, 0, &ThreadId);
232     if (ThreadHandle == NULL)
233     {
234         ERR("LsapRmInitializeServer - Create Thread  failed 0x%lx\n", Status);
235         return STATUS_INSUFFICIENT_RESOURCES;
236     }
237 
238     /* Close the server thread handle */
239     CloseHandle(ThreadHandle);
240 
241     return STATUS_SUCCESS;
242 }
243 
244 NTSTATUS
245 LsapRmCreateLogonSession(
246     PLUID LogonId)
247 {
248     SEP_RM_API_MESSAGE RequestMessage;
249     SEP_RM_API_MESSAGE ReplyMessage;
250     NTSTATUS Status;
251 
252     TRACE("LsapRmCreateLogonSession(%p)\n", LogonId);
253 
254     RequestMessage.Header.u2.ZeroInit = 0;
255     RequestMessage.Header.u1.s1.TotalLength =
256         (CSHORT)(sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(LUID));
257     RequestMessage.Header.u1.s1.DataLength =
258         RequestMessage.Header.u1.s1.TotalLength -
259         (CSHORT)sizeof(PORT_MESSAGE);
260 
261     RequestMessage.ApiNumber = (ULONG)RmCreateLogonSession;
262     RtlCopyLuid(&RequestMessage.u.LogonLuid, LogonId);
263 
264     ReplyMessage.Header.u2.ZeroInit = 0;
265     ReplyMessage.Header.u1.s1.TotalLength =
266         (CSHORT)(sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS));
267     ReplyMessage.Header.u1.s1.DataLength =
268         ReplyMessage.Header.u1.s1.TotalLength -
269         (CSHORT)sizeof(PORT_MESSAGE);
270 
271     ReplyMessage.u.ResultStatus = STATUS_SUCCESS;
272 
273     Status = NtRequestWaitReplyPort(SeRmCommandPort,
274                                     (PPORT_MESSAGE)&RequestMessage,
275                                     (PPORT_MESSAGE)&ReplyMessage);
276     if (NT_SUCCESS(Status))
277     {
278         Status = ReplyMessage.u.ResultStatus;
279     }
280 
281     return Status;
282 }
283 
284 NTSTATUS
285 LsapRmDeleteLogonSession(
286     PLUID LogonId)
287 {
288     SEP_RM_API_MESSAGE RequestMessage;
289     SEP_RM_API_MESSAGE ReplyMessage;
290     NTSTATUS Status;
291 
292     TRACE("LsapRmDeleteLogonSession(%p)\n", LogonId);
293 
294     RequestMessage.Header.u2.ZeroInit = 0;
295     RequestMessage.Header.u1.s1.TotalLength =
296         (CSHORT)(sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(LUID));
297     RequestMessage.Header.u1.s1.DataLength =
298         RequestMessage.Header.u1.s1.TotalLength -
299         (CSHORT)sizeof(PORT_MESSAGE);
300 
301     RequestMessage.ApiNumber = (ULONG)RmDeleteLogonSession;
302     RtlCopyLuid(&RequestMessage.u.LogonLuid, LogonId);
303 
304     ReplyMessage.Header.u2.ZeroInit = 0;
305     ReplyMessage.Header.u1.s1.TotalLength =
306         (CSHORT)(sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS));
307     ReplyMessage.Header.u1.s1.DataLength =
308         ReplyMessage.Header.u1.s1.TotalLength -
309         (CSHORT)sizeof(PORT_MESSAGE);
310 
311     ReplyMessage.u.ResultStatus = STATUS_SUCCESS;
312 
313     Status = NtRequestWaitReplyPort(SeRmCommandPort,
314                                     (PPORT_MESSAGE)&RequestMessage,
315                                     (PPORT_MESSAGE)&ReplyMessage);
316     if (NT_SUCCESS(Status))
317     {
318         Status = ReplyMessage.u.ResultStatus;
319     }
320 
321     return Status;
322 }
323