xref: /reactos/dll/win32/secur32/lsalpc.c (revision 36873c49)
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     ConnectInfo.Untrusted = TRUE;
178 
179     Status = NtConnectPort(LsaHandle,
180                            &PortName,
181                            &SecurityQos,
182                            NULL,
183                            NULL,
184                            NULL,
185                            &ConnectInfo,
186                            &ConnectInfoLength);
187     if (!NT_SUCCESS(Status))
188     {
189         ERR("NtConnectPort failed (Status 0x%08lx)\n", Status);
190         return Status;
191     }
192 
193     if (!NT_SUCCESS(ConnectInfo.Status))
194     {
195         ERR("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status);
196     }
197 
198     return ConnectInfo.Status;
199 }
200 
201 
202 /*
203  * @implemented
204  */
205 NTSTATUS
206 NTAPI
207 LsaEnumerateLogonSessions(
208     PULONG LogonSessionCount,
209     PLUID *LogonSessionList)
210 {
211     LSA_API_MSG ApiMessage;
212     NTSTATUS Status;
213 
214     TRACE("LsaEnumerateLogonSessions(%p %p)\n", LogonSessionCount, LogonSessionList);
215 
216     Status = LsapOpenLsaPort();
217     if (!NT_SUCCESS(Status))
218         return Status;
219 
220     ApiMessage.ApiNumber = LSASS_REQUEST_ENUM_LOGON_SESSIONS;
221     ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.EnumLogonSessions);
222     ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
223     ApiMessage.h.u2.ZeroInit = 0;
224 
225     Status = NtRequestWaitReplyPort(LsaPortHandle,
226                                     (PPORT_MESSAGE)&ApiMessage,
227                                     (PPORT_MESSAGE)&ApiMessage);
228     if (!NT_SUCCESS(Status))
229     {
230         ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
231         return Status;
232     }
233 
234     if (!NT_SUCCESS(ApiMessage.Status))
235     {
236         ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
237         return ApiMessage.Status;
238     }
239 
240     *LogonSessionCount = ApiMessage.EnumLogonSessions.Reply.LogonSessionCount;
241     *LogonSessionList = ApiMessage.EnumLogonSessions.Reply.LogonSessionBuffer;
242 
243     return Status;
244 }
245 
246 
247 /*
248  * @unimplemented
249  */
250 NTSTATUS
251 NTAPI
252 LsaGetLogonSessionData(
253     PLUID LogonId,
254     PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData)
255 {
256     LSA_API_MSG ApiMessage;
257     PSECURITY_LOGON_SESSION_DATA SessionData;
258     NTSTATUS Status;
259 
260     TRACE("LsaGetLogonSessionData(%p %p)\n", LogonId, ppLogonSessionData);
261 
262     Status = LsapOpenLsaPort();
263     if (!NT_SUCCESS(Status))
264         return Status;
265 
266     ApiMessage.ApiNumber = LSASS_REQUEST_GET_LOGON_SESSION_DATA;
267     ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.GetLogonSessionData);
268     ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
269     ApiMessage.h.u2.ZeroInit = 0;
270 
271     RtlCopyLuid(&ApiMessage.GetLogonSessionData.Request.LogonId,
272                 LogonId);
273 
274     Status = NtRequestWaitReplyPort(LsaPortHandle,
275                                     (PPORT_MESSAGE)&ApiMessage,
276                                     (PPORT_MESSAGE)&ApiMessage);
277     if (!NT_SUCCESS(Status))
278     {
279         ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
280         return Status;
281     }
282 
283     if (!NT_SUCCESS(ApiMessage.Status))
284     {
285         ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
286         return ApiMessage.Status;
287     }
288 
289     SessionData = ApiMessage.GetLogonSessionData.Reply.SessionDataBuffer;
290 
291     TRACE("UserName: %p\n", SessionData->UserName.Buffer);
292     if (SessionData->UserName.Buffer != NULL)
293         SessionData->UserName.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->UserName.Buffer);
294 
295     TRACE("LogonDomain: %p\n", SessionData->LogonDomain.Buffer);
296     if (SessionData->LogonDomain.Buffer != NULL)
297         SessionData->LogonDomain.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->LogonDomain.Buffer);
298 
299     TRACE("AuthenticationPackage: %p\n", SessionData->AuthenticationPackage.Buffer);
300     if (SessionData->AuthenticationPackage.Buffer != NULL)
301         SessionData->AuthenticationPackage.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->AuthenticationPackage.Buffer);
302 
303     TRACE("Sid: %p\n", SessionData->Sid);
304     if (SessionData->Sid != NULL)
305         SessionData->Sid = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->Sid);
306 
307     TRACE("LogonServer: %p\n", SessionData->LogonServer.Buffer);
308     if (SessionData->LogonServer.Buffer != NULL)
309         SessionData->LogonServer.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->LogonServer.Buffer);
310 
311     TRACE("DnsDomainName: %p\n", SessionData->DnsDomainName.Buffer);
312     if (SessionData->DnsDomainName.Buffer != NULL)
313         SessionData->DnsDomainName.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->DnsDomainName.Buffer);
314 
315     TRACE("Upn: %p\n", SessionData->Upn.Buffer);
316     if (SessionData->Upn.Buffer != NULL)
317         SessionData->Upn.Buffer = (LPWSTR)((ULONG_PTR)SessionData + (ULONG_PTR)SessionData->Upn.Buffer);
318 
319     *ppLogonSessionData = SessionData;
320 
321     return Status;
322 }
323 
324 
325 /*
326  * @implemented
327  */
328 NTSTATUS
329 NTAPI
330 LsaRegisterPolicyChangeNotification(
331     POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
332     HANDLE NotificationEventHandle)
333 {
334     LSA_API_MSG ApiMessage;
335     NTSTATUS Status;
336 
337     TRACE("LsaRegisterPolicyChangeNotification(%lu %p)\n",
338           InformationClass, NotificationEventHandle);
339 
340     Status = LsapOpenLsaPort();
341     if (!NT_SUCCESS(Status))
342         return Status;
343 
344     ApiMessage.ApiNumber = LSASS_REQUEST_POLICY_CHANGE_NOTIFY;
345     ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.PolicyChangeNotify);
346     ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
347     ApiMessage.h.u2.ZeroInit = 0;
348 
349     ApiMessage.PolicyChangeNotify.Request.InformationClass = InformationClass;
350     ApiMessage.PolicyChangeNotify.Request.NotificationEventHandle = NotificationEventHandle;
351     ApiMessage.PolicyChangeNotify.Request.Register = TRUE;
352 
353     Status = NtRequestWaitReplyPort(LsaPortHandle,
354                                     (PPORT_MESSAGE)&ApiMessage,
355                                     (PPORT_MESSAGE)&ApiMessage);
356     if (!NT_SUCCESS(Status))
357     {
358         ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
359         return Status;
360     }
361 
362     if (!NT_SUCCESS(ApiMessage.Status))
363     {
364         ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
365         return ApiMessage.Status;
366     }
367 
368     return Status;
369 }
370 
371 
372 /*
373  * @implemented
374  */
375 NTSTATUS
376 NTAPI
377 LsaUnregisterPolicyChangeNotification(
378     POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
379     HANDLE NotificationEventHandle)
380 {
381     LSA_API_MSG ApiMessage;
382     NTSTATUS Status;
383 
384     TRACE("LsaUnregisterPolicyChangeNotification(%lu %p)\n",
385           InformationClass, NotificationEventHandle);
386 
387     Status = LsapOpenLsaPort();
388     if (!NT_SUCCESS(Status))
389         return Status;
390 
391     ApiMessage.ApiNumber = LSASS_REQUEST_POLICY_CHANGE_NOTIFY;
392     ApiMessage.h.u1.s1.DataLength = LSA_PORT_DATA_SIZE(ApiMessage.PolicyChangeNotify);
393     ApiMessage.h.u1.s1.TotalLength = LSA_PORT_MESSAGE_SIZE;
394     ApiMessage.h.u2.ZeroInit = 0;
395 
396     ApiMessage.PolicyChangeNotify.Request.InformationClass = InformationClass;
397     ApiMessage.PolicyChangeNotify.Request.NotificationEventHandle = NotificationEventHandle;
398     ApiMessage.PolicyChangeNotify.Request.Register = FALSE;
399 
400     Status = NtRequestWaitReplyPort(LsaPortHandle,
401                                     (PPORT_MESSAGE)&ApiMessage,
402                                     (PPORT_MESSAGE)&ApiMessage);
403     if (!NT_SUCCESS(Status))
404     {
405         ERR("NtRequestWaitReplyPort() failed (Status 0x%08lx)\n", Status);
406         return Status;
407     }
408 
409     if (!NT_SUCCESS(ApiMessage.Status))
410     {
411         ERR("NtRequestWaitReplyPort() failed (ApiMessage.Status 0x%08lx)\n", ApiMessage.Status);
412         return ApiMessage.Status;
413     }
414 
415     return Status;
416 }
417 
418 /* EOF */
419