xref: /reactos/dll/win32/secur32/lsalpc.c (revision 4567e13e)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS system libraries
4  * FILE:            dll/win32/secur32/lsalpc.c
5  * PURPOSE:         LSA LPC port functions
6  */
7 
8 /* INCLUDES ******************************************************************/
9 
10 #include "precomp.h"
11 
12 #include <ndk/lpctypes.h>
13 #include <ndk/lpcfuncs.h>
14 #include <ndk/mmfuncs.h>
15 #include <ndk/rtlfuncs.h>
16 #include <ndk/obfuncs.h>
17 #include <psdk/ntsecapi.h>
18 #include <lsass/lsass.h>
19 
20 #include <wine/debug.h>
21 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
22 
23 
24 /* GLOBALS *******************************************************************/
25 
26 HANDLE LsaPortHandle;
27 
28 extern HANDLE Secur32Heap;
29 
30 
31 /* FUNCTIONS *****************************************************************/
32 
33 VOID
34 LsapInitLsaPort(VOID)
35 {
36     LsaPortHandle = NULL;
37 }
38 
39 
40 VOID
41 LsapCloseLsaPort(VOID)
42 {
43     if (LsaPortHandle != NULL)
44     {
45         NtClose(LsaPortHandle);
46         LsaPortHandle = NULL;
47     }
48 }
49 
50 
51 NTSTATUS
52 LsapOpenLsaPort(VOID)
53 {
54     UNICODE_STRING PortName;
55     SECURITY_QUALITY_OF_SERVICE SecurityQos;
56     LSA_CONNECTION_INFO ConnectInfo;
57     ULONG ConnectInfoLength;
58     NTSTATUS Status;
59 
60     TRACE("LsapOpenLsaPort()\n");
61 
62     if (LsaPortHandle != NULL)
63         return STATUS_SUCCESS;
64 
65     RtlInitUnicodeString(&PortName,
66                          L"\\LsaAuthenticationPort");
67 
68     SecurityQos.Length              = sizeof(SecurityQos);
69     SecurityQos.ImpersonationLevel  = SecurityIdentification;
70     SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
71     SecurityQos.EffectiveOnly       = TRUE;
72 
73     RtlZeroMemory(&ConnectInfo,
74                   sizeof(ConnectInfo));
75 
76     ConnectInfo.CreateContext = FALSE;
77 
78     ConnectInfoLength = sizeof(LSA_CONNECTION_INFO);
79     Status = NtConnectPort(&LsaPortHandle,
80                            &PortName,
81                            &SecurityQos,
82                            NULL,
83                            NULL,
84                            NULL,
85                            &ConnectInfo,
86                            &ConnectInfoLength);
87     if (!NT_SUCCESS(Status))
88     {
89         TRACE("NtConnectPort failed (Status 0x%08lx)\n", Status);
90     }
91 
92     return Status;
93 /*
94     if (!NT_SUCCESS(ConnectInfo.Status))
95     {
96         DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status);
97     }
98 
99     return ConnectInfo.Status;
100 */
101 }
102 
103 
104 /* PUBLIC FUNCTIONS **********************************************************/
105 
106 /*
107  * @implemented
108  */
109 NTSTATUS
110 NTAPI
111 LsaConnectUntrusted(
112     OUT PHANDLE LsaHandle)
113 {
114     UNICODE_STRING PortName;
115     SECURITY_QUALITY_OF_SERVICE SecurityQos;
116     LSA_CONNECTION_INFO ConnectInfo;
117     ULONG ConnectInfoLength = sizeof(ConnectInfo);
118     OBJECT_ATTRIBUTES ObjectAttributes;
119     UNICODE_STRING EventName;
120     HANDLE EventHandle;
121     NTSTATUS Status;
122 
123     TRACE("LsaConnectUntrusted(%p)\n", LsaHandle);
124 
125     // TODO: we may need to impersonate ourselves before, because we are untrusted!
126 
127     /* Wait for the LSA authentication thread */
128     RtlInitUnicodeString(&EventName,
129                          L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
130     InitializeObjectAttributes(&ObjectAttributes,
131                                &EventName,
132                                OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
133                                NULL,
134                                NULL);
135     Status = NtOpenEvent(&EventHandle,
136                          SYNCHRONIZE,
137                          &ObjectAttributes);
138     if (!NT_SUCCESS(Status))
139     {
140         WARN("NtOpenEvent failed (Status 0x%08lx)\n", Status);
141 
142         Status = NtCreateEvent(&EventHandle,
143                                SYNCHRONIZE,
144                                &ObjectAttributes,
145                                NotificationEvent,
146                                FALSE);
147         if (!NT_SUCCESS(Status))
148         {
149             WARN("NtCreateEvent failed (Status 0x%08lx)\n", Status);
150             return Status;
151         }
152     }
153 
154     Status = NtWaitForSingleObject(EventHandle,
155                                    TRUE,
156                                    NULL);
157     NtClose(EventHandle);
158     if (!NT_SUCCESS(Status))
159     {
160         ERR("NtWaitForSingleObject failed (Status 0x%08lx)\n", Status);
161         return Status;
162     }
163 
164     /* Connect to the authentication port */
165     RtlInitUnicodeString(&PortName,
166                          L"\\LsaAuthenticationPort");
167 
168     SecurityQos.Length              = sizeof(SecurityQos);
169     SecurityQos.ImpersonationLevel  = SecurityIdentification;
170     SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
171     SecurityQos.EffectiveOnly       = TRUE;
172 
173     RtlZeroMemory(&ConnectInfo,
174                   ConnectInfoLength);
175 
176     ConnectInfo.CreateContext = TRUE;
177 
178     Status = NtConnectPort(LsaHandle,
179                            &PortName,
180                            &SecurityQos,
181                            NULL,
182                            NULL,
183                            NULL,
184                            &ConnectInfo,
185                            &ConnectInfoLength);
186     if (!NT_SUCCESS(Status))
187     {
188         ERR("NtConnectPort failed (Status 0x%08lx)\n", Status);
189         return Status;
190     }
191 
192     if (!NT_SUCCESS(ConnectInfo.Status))
193     {
194         ERR("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status);
195     }
196 
197     return ConnectInfo.Status;
198 }
199 
200 
201 /*
202  * @implemented
203  */
204 NTSTATUS
205 NTAPI
206 LsaEnumerateLogonSessions(
207     PULONG LogonSessionCount,
208     PLUID *LogonSessionList)
209 {
210     LSA_API_MSG ApiMessage;
211     NTSTATUS Status;
212 
213     TRACE("LsaEnumerateLogonSessions(%p %p)\n", LogonSessionCount, LogonSessionList);
214 
215     Status = LsapOpenLsaPort();
216     if (!NT_SUCCESS(Status))
217         return Status;
218 
219     ApiMessage.ApiNumber = LSASS_REQUEST_ENUM_LOGON_SESSIONS;
220     ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.EnumLogonSessions);
221     ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
222     ApiMessage.h.u2.ZeroInit = 0;
223 
224     Status = NtRequestWaitReplyPort(LsaPortHandle,
225                                     (PPORT_MESSAGE)&ApiMessage,
226                                     (PPORT_MESSAGE)&ApiMessage);
227     if (!NT_SUCCESS(Status))
228     {
229         ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
230         return Status;
231     }
232 
233     if (!NT_SUCCESS(ApiMessage.Status))
234     {
235         ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
236         return ApiMessage.Status;
237     }
238 
239     *LogonSessionCount = ApiMessage.EnumLogonSessions.Reply.LogonSessionCount;
240     *LogonSessionList = ApiMessage.EnumLogonSessions.Reply.LogonSessionBuffer;
241 
242     return Status;
243 }
244 
245 
246 /*
247  * @unimplemented
248  */
249 NTSTATUS
250 NTAPI
251 LsaGetLogonSessionData(
252     PLUID LogonId,
253     PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData)
254 {
255     LSA_API_MSG ApiMessage;
256     PSECURITY_LOGON_SESSION_DATA SessionData;
257     NTSTATUS Status;
258 
259     TRACE("LsaGetLogonSessionData(%p %p)\n", LogonId, ppLogonSessionData);
260 
261     Status = LsapOpenLsaPort();
262     if (!NT_SUCCESS(Status))
263         return Status;
264 
265     ApiMessage.ApiNumber = LSASS_REQUEST_GET_LOGON_SESSION_DATA;
266     ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.GetLogonSessionData);
267     ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
268     ApiMessage.h.u2.ZeroInit = 0;
269 
270     RtlCopyLuid(&ApiMessage.GetLogonSessionData.Request.LogonId,
271                 LogonId);
272 
273     Status = NtRequestWaitReplyPort(LsaPortHandle,
274                                     (PPORT_MESSAGE)&ApiMessage,
275                                     (PPORT_MESSAGE)&ApiMessage);
276     if (!NT_SUCCESS(Status))
277     {
278         ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
279         return Status;
280     }
281 
282     if (!NT_SUCCESS(ApiMessage.Status))
283     {
284         ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
285         return ApiMessage.Status;
286     }
287 
288     SessionData = ApiMessage.GetLogonSessionData.Reply.SessionDataBuffer;
289 
290     TRACE("UserName: %p\n", SessionData->UserName.Buffer);
291     if (SessionData->UserName.Buffer != NULL)
292         SessionData->UserName.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->UserName.Buffer);
293 
294     TRACE("LogonDomain: %p\n", SessionData->LogonDomain.Buffer);
295     if (SessionData->LogonDomain.Buffer != NULL)
296         SessionData->LogonDomain.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->LogonDomain.Buffer);
297 
298     TRACE("AuthenticationPackage: %p\n", SessionData->AuthenticationPackage.Buffer);
299     if (SessionData->AuthenticationPackage.Buffer != NULL)
300         SessionData->AuthenticationPackage.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->AuthenticationPackage.Buffer);
301 
302     TRACE("Sid: %p\n", SessionData->Sid);
303     if (SessionData->Sid != NULL)
304         SessionData->Sid = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->Sid);
305 
306     TRACE("LogonServer: %p\n", SessionData->LogonServer.Buffer);
307     if (SessionData->LogonServer.Buffer != NULL)
308         SessionData->LogonServer.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->LogonServer.Buffer);
309 
310     TRACE("DnsDomainName: %p\n", SessionData->DnsDomainName.Buffer);
311     if (SessionData->DnsDomainName.Buffer != NULL)
312         SessionData->DnsDomainName.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->DnsDomainName.Buffer);
313 
314     TRACE("Upn: %p\n", SessionData->Upn.Buffer);
315     if (SessionData->Upn.Buffer != NULL)
316         SessionData->Upn.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->Upn.Buffer);
317 
318     *ppLogonSessionData = SessionData;
319 
320     return Status;
321 }
322 
323 
324 /*
325  * @implemented
326  */
327 NTSTATUS
328 NTAPI
329 LsaRegisterPolicyChangeNotification(
330     POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
331     HANDLE NotificationEventHandle)
332 {
333     LSA_API_MSG ApiMessage;
334     NTSTATUS Status;
335 
336     TRACE("LsaRegisterPolicyChangeNotification(%lu %p)\n",
337           InformationClass, NotificationEventHandle);
338 
339     Status = LsapOpenLsaPort();
340     if (!NT_SUCCESS(Status))
341         return Status;
342 
343     ApiMessage.ApiNumber = LSASS_REQUEST_POLICY_CHANGE_NOTIFY;
344     ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.PolicyChangeNotify);
345     ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
346     ApiMessage.h.u2.ZeroInit = 0;
347 
348     ApiMessage.PolicyChangeNotify.Request.InformationClass = InformationClass;
349     ApiMessage.PolicyChangeNotify.Request.NotificationEventHandle = NotificationEventHandle;
350     ApiMessage.PolicyChangeNotify.Request.Register = TRUE;
351 
352     Status = NtRequestWaitReplyPort(LsaPortHandle,
353                                     (PPORT_MESSAGE)&ApiMessage,
354                                     (PPORT_MESSAGE)&ApiMessage);
355     if (!NT_SUCCESS(Status))
356     {
357         ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
358         return Status;
359     }
360 
361     if (!NT_SUCCESS(ApiMessage.Status))
362     {
363         ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
364         return ApiMessage.Status;
365     }
366 
367     return Status;
368 }
369 
370 
371 /*
372  * @implemented
373  */
374 NTSTATUS
375 NTAPI
376 LsaUnregisterPolicyChangeNotification(
377     POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
378     HANDLE NotificationEventHandle)
379 {
380     LSA_API_MSG ApiMessage;
381     NTSTATUS Status;
382 
383     TRACE("LsaUnregisterPolicyChangeNotification(%lu %p)\n",
384           InformationClass, NotificationEventHandle);
385 
386     Status = LsapOpenLsaPort();
387     if (!NT_SUCCESS(Status))
388         return Status;
389 
390     ApiMessage.ApiNumber = LSASS_REQUEST_POLICY_CHANGE_NOTIFY;
391     ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.PolicyChangeNotify);
392     ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
393     ApiMessage.h.u2.ZeroInit = 0;
394 
395     ApiMessage.PolicyChangeNotify.Request.InformationClass = InformationClass;
396     ApiMessage.PolicyChangeNotify.Request.NotificationEventHandle = NotificationEventHandle;
397     ApiMessage.PolicyChangeNotify.Request.Register = FALSE;
398 
399     Status = NtRequestWaitReplyPort(LsaPortHandle,
400                                     (PPORT_MESSAGE)&ApiMessage,
401                                     (PPORT_MESSAGE)&ApiMessage);
402     if (!NT_SUCCESS(Status))
403     {
404         ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
405         return Status;
406     }
407 
408     if (!NT_SUCCESS(ApiMessage.Status))
409     {
410         ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
411         return ApiMessage.Status;
412     }
413 
414     return Status;
415 }
416 
417 /* EOF */
418