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