xref: /reactos/dll/win32/lsasrv/authport.c (revision e08ae510)
1 /*
2  * PROJECT:     Local Security Authority Server DLL
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        dll/win32/lsasrv/authport.c
5  * PURPOSE:     LsaAuthenticationPort server routines
6  * COPYRIGHT:   Copyright 2009 Eric Kohl
7  */
8 
9 #include "lsasrv.h"
10 
11 #include <ndk/lpcfuncs.h>
12 
13 static LIST_ENTRY LsapLogonContextList;
14 
15 static HANDLE PortThreadHandle = NULL;
16 static HANDLE AuthPortHandle = NULL;
17 
18 
19 /* FUNCTIONS ***************************************************************/
20 
21 static NTSTATUS
22 LsapDeregisterLogonProcess(PLSA_API_MSG RequestMsg,
23                            PLSAP_LOGON_CONTEXT LogonContext)
24 {
25     TRACE("LsapDeregisterLogonProcess(%p %p)\n", RequestMsg, LogonContext);
26 
27     RemoveHeadList(&LogonContext->Entry);
28 
29     NtClose(LogonContext->ClientProcessHandle);
30     NtClose(LogonContext->ConnectionHandle);
31 
32     RtlFreeHeap(RtlGetProcessHeap(), 0, LogonContext);
33 
34     return STATUS_SUCCESS;
35 }
36 
37 
38 static NTSTATUS
39 LsapCheckLogonProcess(PLSA_API_MSG RequestMsg,
40                       PLSAP_LOGON_CONTEXT *LogonContext)
41 {
42     OBJECT_ATTRIBUTES ObjectAttributes;
43     HANDLE ProcessHandle = NULL;
44     PLSAP_LOGON_CONTEXT Context = NULL;
45     NTSTATUS Status;
46 
47     TRACE("LsapCheckLogonProcess(%p)\n", RequestMsg);
48 
49     TRACE("Client ID: %p %p\n", RequestMsg->h.ClientId.UniqueProcess, RequestMsg->h.ClientId.UniqueThread);
50 
51     InitializeObjectAttributes(&ObjectAttributes,
52                                NULL,
53                                0,
54                                NULL,
55                                NULL);
56 
57     Status = NtOpenProcess(&ProcessHandle,
58                            PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE,
59                            &ObjectAttributes,
60                            &RequestMsg->h.ClientId);
61     if (!NT_SUCCESS(Status))
62     {
63         TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
64         return Status;
65     }
66 
67     /* Allocate the logon context */
68     Context = RtlAllocateHeap(RtlGetProcessHeap(),
69                               HEAP_ZERO_MEMORY,
70                               sizeof(LSAP_LOGON_CONTEXT));
71     if (Context == NULL)
72     {
73         NtClose(ProcessHandle);
74         return STATUS_INSUFFICIENT_RESOURCES;
75     }
76 
77     TRACE("New LogonContext: %p\n", Context);
78 
79     Context->ClientProcessHandle = ProcessHandle;
80 
81     *LogonContext = Context;
82 
83     return STATUS_SUCCESS;
84 }
85 
86 
87 static NTSTATUS
88 LsapHandlePortConnection(PLSA_API_MSG RequestMsg)
89 {
90     PLSAP_LOGON_CONTEXT LogonContext = NULL;
91     HANDLE ConnectionHandle = NULL;
92     BOOLEAN Accept;
93     REMOTE_PORT_VIEW RemotePortView;
94     NTSTATUS Status = STATUS_SUCCESS;
95 
96     TRACE("LsapHandlePortConnection(%p)\n", RequestMsg);
97 
98     TRACE("Logon Process Name: %s\n", RequestMsg->ConnectInfo.LogonProcessNameBuffer);
99 
100     if (RequestMsg->ConnectInfo.CreateContext != FALSE)
101     {
102         Status = LsapCheckLogonProcess(RequestMsg,
103                                        &LogonContext);
104 
105         RequestMsg->ConnectInfo.OperationalMode = 0x43218765;
106 
107         RequestMsg->ConnectInfo.Status = Status;
108     }
109 
110     if (NT_SUCCESS(Status))
111     {
112         Accept = TRUE;
113     }
114     else
115     {
116         Accept = FALSE;
117     }
118 
119     RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
120     Status = NtAcceptConnectPort(&ConnectionHandle,
121                                  (PVOID*)LogonContext,
122                                  &RequestMsg->h,
123                                  Accept,
124                                  NULL,
125                                  &RemotePortView);
126     if (!NT_SUCCESS(Status))
127     {
128         ERR("NtAcceptConnectPort failed (Status 0x%lx)\n", Status);
129         return Status;
130     }
131 
132     if (Accept != FALSE)
133     {
134         if (LogonContext != NULL)
135         {
136             LogonContext->ConnectionHandle = ConnectionHandle;
137 
138             InsertHeadList(&LsapLogonContextList,
139                            &LogonContext->Entry);
140         }
141 
142         Status = NtCompleteConnectPort(ConnectionHandle);
143         if (!NT_SUCCESS(Status))
144         {
145             ERR("NtCompleteConnectPort failed (Status 0x%lx)\n", Status);
146             return Status;
147         }
148     }
149 
150     return Status;
151 }
152 
153 
154 NTSTATUS WINAPI
155 AuthPortThreadRoutine(PVOID Param)
156 {
157     PLSAP_LOGON_CONTEXT LogonContext;
158     PLSA_API_MSG ReplyMsg = NULL;
159     LSA_API_MSG RequestMsg;
160     NTSTATUS Status;
161 
162     TRACE("AuthPortThreadRoutine() called\n");
163 
164     Status = STATUS_SUCCESS;
165 
166     for (;;)
167     {
168         TRACE("Reply: %p\n", ReplyMsg);
169         Status = NtReplyWaitReceivePort(AuthPortHandle,
170                                         (PVOID*)&LogonContext,
171                                         (PPORT_MESSAGE)ReplyMsg,
172                                         (PPORT_MESSAGE)&RequestMsg);
173         if (!NT_SUCCESS(Status))
174         {
175             TRACE("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
176             break;
177         }
178 
179         TRACE("Received message\n");
180 
181         switch (RequestMsg.h.u2.s2.Type)
182         {
183             case LPC_CONNECTION_REQUEST:
184                 TRACE("Port connection request\n");
185                 Status = LsapHandlePortConnection(&RequestMsg);
186                 ReplyMsg = NULL;
187                 break;
188 
189             case LPC_PORT_CLOSED:
190                 TRACE("Port closed\n");
191                 ReplyMsg = NULL;
192                 break;
193 
194             case LPC_CLIENT_DIED:
195                 TRACE("Client died\n");
196                 ReplyMsg = NULL;
197                 break;
198 
199             default:
200                 TRACE("Received request (ApiNumber: %lu)\n", RequestMsg.ApiNumber);
201 
202                 switch (RequestMsg.ApiNumber)
203                 {
204                     case LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE:
205                         RequestMsg.Status = LsapCallAuthenticationPackage(&RequestMsg,
206                                                                           LogonContext);
207                         ReplyMsg = &RequestMsg;
208                         break;
209 
210                     case LSASS_REQUEST_DEREGISTER_LOGON_PROCESS:
211 
212                         ReplyMsg = &RequestMsg;
213                         RequestMsg.Status = STATUS_SUCCESS;
214                         NtReplyPort(AuthPortHandle,
215                                     &ReplyMsg->h);
216 
217                         LsapDeregisterLogonProcess(&RequestMsg,
218                                                    LogonContext);
219 
220                         ReplyMsg = NULL;
221                         break;
222 
223                     case LSASS_REQUEST_LOGON_USER:
224                         RequestMsg.Status = LsapLogonUser(&RequestMsg,
225                                                           LogonContext);
226                         ReplyMsg = &RequestMsg;
227                         break;
228 
229                     case LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE:
230                         RequestMsg.Status = LsapLookupAuthenticationPackage(&RequestMsg,
231                                                                             LogonContext);
232                         ReplyMsg = &RequestMsg;
233                         break;
234 
235                     case LSASS_REQUEST_ENUM_LOGON_SESSIONS:
236                         RequestMsg.Status = LsapEnumLogonSessions(&RequestMsg);
237                         ReplyMsg = &RequestMsg;
238                         break;
239 
240                     case LSASS_REQUEST_GET_LOGON_SESSION_DATA:
241                         RequestMsg.Status = LsapGetLogonSessionData(&RequestMsg);
242                         ReplyMsg = &RequestMsg;
243                         break;
244 
245                     case LSASS_REQUEST_POLICY_CHANGE_NOTIFY:
246                         RequestMsg.Status = LsapRegisterNotification(&RequestMsg);
247                         ReplyMsg = &RequestMsg;
248                         break;
249 
250                     default:
251                         RequestMsg.Status = STATUS_INVALID_SYSTEM_SERVICE;
252                         ReplyMsg = &RequestMsg;
253                         break;
254                 }
255 
256                 break;
257         }
258     }
259 
260     return STATUS_SUCCESS;
261 }
262 
263 
264 NTSTATUS
265 StartAuthenticationPort(VOID)
266 {
267     OBJECT_ATTRIBUTES ObjectAttributes;
268     UNICODE_STRING PortName;
269     DWORD ThreadId;
270     UNICODE_STRING EventName;
271     HANDLE EventHandle;
272     NTSTATUS Status;
273 
274     TRACE("StartAuthenticationPort()\n");
275 
276     /* Initialize the logon context list */
277     InitializeListHead(&LsapLogonContextList);
278 
279     RtlInitUnicodeString(&PortName,
280                          L"\\LsaAuthenticationPort");
281 
282     InitializeObjectAttributes(&ObjectAttributes,
283                                &PortName,
284                                0,
285                                NULL,
286                                NULL);
287 
288     Status = NtCreatePort(&AuthPortHandle,
289                           &ObjectAttributes,
290                           sizeof(LSA_CONNECTION_INFO),
291                           sizeof(LSA_API_MSG),
292                           sizeof(LSA_API_MSG) * 32);
293     if (!NT_SUCCESS(Status))
294     {
295         WARN("NtCreatePort() failed (Status %lx)\n", Status);
296         return Status;
297     }
298 
299     RtlInitUnicodeString(&EventName,
300                          L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
301     InitializeObjectAttributes(&ObjectAttributes,
302                                &EventName,
303                                OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
304                                NULL,
305                                NULL);
306     Status = NtOpenEvent(&EventHandle,
307                          EVENT_MODIFY_STATE,
308                          &ObjectAttributes);
309     if (!NT_SUCCESS(Status))
310     {
311         TRACE("NtOpenEvent failed (Status 0x%08lx)\n", Status);
312 
313         Status = NtCreateEvent(&EventHandle,
314                                EVENT_MODIFY_STATE,
315                                &ObjectAttributes,
316                                NotificationEvent,
317                                FALSE);
318         if (!NT_SUCCESS(Status))
319         {
320             WARN("NtCreateEvent failed (Status 0x%08lx)\n", Status);
321             return Status;
322         }
323     }
324 
325     Status = NtSetEvent(EventHandle, NULL);
326     NtClose(EventHandle);
327     if (!NT_SUCCESS(Status))
328     {
329         WARN("NtSetEvent failed (Status 0x%08lx)\n", Status);
330         return Status;
331     }
332 
333     PortThreadHandle = CreateThread(NULL,
334                                     0x1000,
335                                     (LPTHREAD_START_ROUTINE)AuthPortThreadRoutine,
336                                     NULL,
337                                     0,
338                                     &ThreadId);
339 
340 
341     return STATUS_SUCCESS;
342 }
343 
344 /* EOF */
345