[LSASRV]
[reactos.git] / reactos / dll / win32 / lsasrv / authpackage.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/lsasrv/authpackage.c
5 * PURPOSE: Authenticaton package management routines
6 * COPYRIGHT: Copyright 2013 Eric Kohl
7 */
8
9 #include "lsasrv.h"
10
11 typedef enum _LSA_TOKEN_INFORMATION_TYPE
12 {
13 LsaTokenInformationNull,
14 LsaTokenInformationV1
15 } LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;
16
17 typedef struct _LSA_TOKEN_INFORMATION_V1
18 {
19 LARGE_INTEGER ExpirationTime;
20 TOKEN_USER User;
21 PTOKEN_GROUPS Groups;
22 TOKEN_PRIMARY_GROUP PrimaryGroup;
23 PTOKEN_PRIVILEGES Privileges;
24 TOKEN_OWNER Owner;
25 TOKEN_DEFAULT_DACL DefaultDacl;
26 } LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1;
27
28 typedef PVOID PLSA_CLIENT_REQUEST;
29
30 typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID);
31 typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID);
32
33 typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG);
34 typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID);
35 typedef NTSTATUS (NTAPI *PLSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, PVOID*);
36 typedef NTSTATUS (NTAPI *PLSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, PVOID);
37 typedef NTSTATUS (NTAPI *PLSA_COPY_TO_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG,
38 PVOID, PVOID);
39 typedef NTSTATUS (NTAPI *PLSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,
40 ULONG, PVOID, PVOID);
41
42 typedef struct LSA_DISPATCH_TABLE
43 {
44 PLSA_CREATE_LOGON_SESSION CreateLogonSession;
45 PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
46 PVOID /*PLSA_ADD_CREDENTIAL */ AddCredential;
47 PVOID /*PLSA_GET_CREDENTIALS */ GetCredentials;
48 PVOID /*PLSA_DELETE_CREDENTIAL */ DeleteCredential;
49 PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
50 PLSA_FREE_LSA_HEAP FreeLsaHeap;
51 PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
52 PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
53 PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;
54 PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
55 } LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;
56
57
58 typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PLSA_DISPATCH_TABLE,
59 PLSA_STRING, PLSA_STRING, PLSA_STRING *);
60 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_INTERNAL)(PLSA_CLIENT_REQUEST, PVOID, PVOID,
61 ULONG, PVOID *, PULONG, PNTSTATUS);
62 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_PASSTHROUGH)(PLSA_CLIENT_REQUEST,
63 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
64 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_UNTRUSTED)(PLSA_CLIENT_REQUEST,
65 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
66 typedef VOID (NTAPI *PLSA_AP_LOGON_TERMINATED)(PLUID);
67 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX2)(PLSA_CLIENT_REQUEST,
68 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
69 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
70 PUNICODE_STRING *, PVOID /*PSECPKG_PRIMARY_CRED*/, PVOID /*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/);
71 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX)(PLSA_CLIENT_REQUEST,
72 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
73 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
74 PUNICODE_STRING *);
75
76 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_INTERNAL)(PLSA_CLIENT_REQUEST, SECURITY_LOGON_TYPE,
77 PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, PLSA_TOKEN_INFORMATION_TYPE,
78 PVOID *, PUNICODE_STRING *, PUNICODE_STRING *);
79
80 typedef struct _AUTH_PACKAGE
81 {
82 LIST_ENTRY Entry;
83 PSTRING Name;
84 ULONG Id;
85 PVOID ModuleHandle;
86
87 PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage;
88 PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage;
89 PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough;
90 PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted;
91 PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated;
92 PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2;
93 PLSA_AP_LOGON_USER_EX LsaApLogonUserEx;
94 PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser;
95 } AUTH_PACKAGE, *PAUTH_PACKAGE;
96
97
98 /* GLOBALS *****************************************************************/
99
100 static LIST_ENTRY PackageListHead;
101 static ULONG PackageId;
102 static LSA_DISPATCH_TABLE DispatchTable;
103
104
105 /* FUNCTIONS ***************************************************************/
106
107 static
108 NTSTATUS
109 NTAPI
110 LsapAddAuthPackage(IN PWSTR ValueName,
111 IN ULONG ValueType,
112 IN PVOID ValueData,
113 IN ULONG ValueLength,
114 IN PVOID Context,
115 IN PVOID EntryContext)
116 {
117 PAUTH_PACKAGE Package = NULL;
118 UNICODE_STRING PackageName;
119 STRING ProcName;
120 PULONG Id;
121 NTSTATUS Status = STATUS_SUCCESS;
122
123 TRACE("LsapAddAuthPackage()\n");
124
125 PackageName.Length = (USHORT)ValueLength - sizeof(WCHAR);
126 PackageName.MaximumLength = (USHORT)ValueLength;
127 PackageName.Buffer = ValueData;
128
129 Id = (PULONG)Context;
130
131 Package = RtlAllocateHeap(RtlGetProcessHeap(),
132 HEAP_ZERO_MEMORY,
133 sizeof(AUTH_PACKAGE));
134 if (Package == NULL)
135 return STATUS_INSUFFICIENT_RESOURCES;
136
137 Status = LdrLoadDll(NULL,
138 NULL,
139 &PackageName,
140 &Package->ModuleHandle);
141 if (!NT_SUCCESS(Status))
142 {
143 TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status);
144 goto done;
145 }
146
147 RtlInitAnsiString(&ProcName, "LsaApInitializePackage");
148 Status = LdrGetProcedureAddress(Package->ModuleHandle,
149 &ProcName,
150 0,
151 (PVOID *)&Package->LsaApInitializePackage);
152 if (!NT_SUCCESS(Status))
153 {
154 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
155 goto done;
156 }
157
158 RtlInitAnsiString(&ProcName, "LsaApCallPackage");
159 Status = LdrGetProcedureAddress(Package->ModuleHandle,
160 &ProcName,
161 0,
162 (PVOID *)&Package->LsaApCallPackage);
163 if (!NT_SUCCESS(Status))
164 {
165 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
166 goto done;
167 }
168
169 RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough");
170 Status = LdrGetProcedureAddress(Package->ModuleHandle,
171 &ProcName,
172 0,
173 (PVOID *)&Package->LsaApCallPackagePassthrough);
174 if (!NT_SUCCESS(Status))
175 {
176 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
177 goto done;
178 }
179
180 RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted");
181 Status = LdrGetProcedureAddress(Package->ModuleHandle,
182 &ProcName,
183 0,
184 (PVOID *)&Package->LsaApCallPackageUntrusted);
185 if (!NT_SUCCESS(Status))
186 {
187 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
188 goto done;
189 }
190
191 RtlInitAnsiString(&ProcName, "LsaApLogonTerminated");
192 Status = LdrGetProcedureAddress(Package->ModuleHandle,
193 &ProcName,
194 0,
195 (PVOID *)&Package->LsaApLogonTerminated);
196 if (!NT_SUCCESS(Status))
197 {
198 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
199 goto done;
200 }
201
202 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2");
203 Status = LdrGetProcedureAddress(Package->ModuleHandle,
204 &ProcName,
205 0,
206 (PVOID *)&Package->LsaApLogonUserEx2);
207 if (!NT_SUCCESS(Status))
208 {
209 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx");
210 Status = LdrGetProcedureAddress(Package->ModuleHandle,
211 &ProcName,
212 0,
213 (PVOID *)&Package->LsaApLogonUserEx);
214 if (!NT_SUCCESS(Status))
215 {
216 RtlInitAnsiString(&ProcName, "LsaApLogonUser");
217 Status = LdrGetProcedureAddress(Package->ModuleHandle,
218 &ProcName,
219 0,
220 (PVOID *)&Package->LsaApLogonUser);
221 if (!NT_SUCCESS(Status))
222 {
223 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
224 goto done;
225 }
226 }
227 }
228
229 /* Initialize the current package */
230 Status = Package->LsaApInitializePackage(*Id,
231 &DispatchTable,
232 NULL,
233 NULL,
234 &Package->Name);
235 if (!NT_SUCCESS(Status))
236 {
237 TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status);
238 goto done;
239 }
240
241 TRACE("Package Name: %s\n", Package->Name->Buffer);
242
243 Package->Id = *Id;
244 (*Id)++;
245
246 InsertTailList(&PackageListHead, &Package->Entry);
247
248 done:
249 if (!NT_SUCCESS(Status))
250 {
251 if (Package != NULL)
252 {
253 if (Package->ModuleHandle != NULL)
254 LdrUnloadDll(Package->ModuleHandle);
255
256 if (Package->Name != NULL)
257 {
258 if (Package->Name->Buffer != NULL)
259 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer);
260
261 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name);
262 }
263
264 RtlFreeHeap(RtlGetProcessHeap(), 0, Package);
265 }
266 }
267
268 return Status;
269 }
270
271
272 static
273 PAUTH_PACKAGE
274 LsapGetAuthenticationPackage(IN ULONG PackageId)
275 {
276 PLIST_ENTRY ListEntry;
277 PAUTH_PACKAGE Package;
278
279 ListEntry = PackageListHead.Flink;
280 while (ListEntry != &PackageListHead)
281 {
282 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
283
284 if (Package->Id == PackageId)
285 {
286 return Package;
287 }
288
289 ListEntry = ListEntry->Flink;
290 }
291
292 return NULL;
293 }
294
295
296 static
297 PVOID
298 NTAPI
299 LsapAllocateHeap(IN ULONG Length)
300 {
301 return RtlAllocateHeap(RtlGetProcessHeap(),
302 HEAP_ZERO_MEMORY,
303 Length);
304 }
305
306
307 static
308 VOID
309 NTAPI
310 LsapFreeHeap(IN PVOID Base)
311 {
312 RtlFreeHeap(RtlGetProcessHeap(),
313 0,
314 Base);
315 }
316
317
318 static
319 NTSTATUS
320 NTAPI
321 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
322 IN ULONG LengthRequired,
323 OUT PVOID *ClientBaseAddress)
324 {
325 PLSAP_LOGON_CONTEXT LogonContext;
326 ULONG Length;
327
328 *ClientBaseAddress = NULL;
329
330 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
331
332 Length = LengthRequired;
333 return NtAllocateVirtualMemory(LogonContext->ClientProcessHandle,
334 ClientBaseAddress,
335 0,
336 &Length,
337 MEM_COMMIT,
338 PAGE_READWRITE);
339 }
340
341
342 static
343 NTSTATUS
344 NTAPI
345 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
346 IN PVOID ClientBaseAddress)
347 {
348 PLSAP_LOGON_CONTEXT LogonContext;
349 ULONG Length;
350
351 if (ClientBaseAddress == NULL)
352 return STATUS_SUCCESS;
353
354 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
355
356 Length = 0;
357 return NtFreeVirtualMemory(LogonContext->ClientProcessHandle,
358 &ClientBaseAddress,
359 &Length,
360 MEM_RELEASE);
361 }
362
363
364 static
365 NTSTATUS
366 NTAPI
367 LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
368 IN ULONG Length,
369 IN PVOID ClientBaseAddress,
370 IN PVOID BufferToCopy)
371 {
372 PLSAP_LOGON_CONTEXT LogonContext;
373
374 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
375
376 return NtWriteVirtualMemory(LogonContext->ClientProcessHandle,
377 ClientBaseAddress,
378 BufferToCopy,
379 Length,
380 NULL);
381 }
382
383
384 static
385 NTSTATUS
386 NTAPI
387 LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
388 IN ULONG Length,
389 IN PVOID BufferToCopy,
390 IN PVOID ClientBaseAddress)
391 {
392 PLSAP_LOGON_CONTEXT LogonContext;
393
394 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
395
396 return NtReadVirtualMemory(LogonContext->ClientProcessHandle,
397 ClientBaseAddress,
398 BufferToCopy,
399 Length,
400 NULL);
401 }
402
403
404 NTSTATUS
405 LsapInitAuthPackages(VOID)
406 {
407 RTL_QUERY_REGISTRY_TABLE AuthPackageTable[] = {
408 {LsapAddAuthPackage, 0, L"Authentication Packages", NULL, REG_NONE, NULL, 0},
409 {NULL, 0, NULL, NULL, REG_NONE, NULL, 0}};
410
411 NTSTATUS Status;
412
413 InitializeListHead(&PackageListHead);
414 PackageId = 0;
415
416 /* Initialize the dispatch table */
417 DispatchTable.CreateLogonSession = &LsapCreateLogonSession;
418 DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession;
419 DispatchTable.AddCredential = NULL;
420 DispatchTable.GetCredentials = NULL;
421 DispatchTable.DeleteCredential = NULL;
422 DispatchTable.AllocateLsaHeap = &LsapAllocateHeap;
423 DispatchTable.FreeLsaHeap = &LsapFreeHeap;
424 DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
425 DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
426 DispatchTable.CopyToClientBuffer = &LsapCopyToClientBuffer;
427 DispatchTable.CopyFromClientBuffer = &LsapCopyFromClientBuffer;
428
429 /* Add registered authentication packages */
430 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
431 L"Lsa",
432 AuthPackageTable,
433 &PackageId,
434 NULL);
435
436 return Status;
437 }
438
439
440 NTSTATUS
441 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg,
442 PLSAP_LOGON_CONTEXT LogonContext)
443 {
444 PLIST_ENTRY ListEntry;
445 PAUTH_PACKAGE Package;
446 ULONG PackageNameLength;
447 PCHAR PackageName;
448
449 TRACE("(%p %p)\n", RequestMsg, LogonContext);
450
451 PackageNameLength = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength;
452 PackageName = RequestMsg->LookupAuthenticationPackage.Request.PackageName;
453
454 TRACE("PackageName: %s\n", PackageName);
455
456 ListEntry = PackageListHead.Flink;
457 while (ListEntry != &PackageListHead)
458 {
459 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
460
461 if ((PackageNameLength == Package->Name->Length) &&
462 (_strnicmp(PackageName, Package->Name->Buffer, Package->Name->Length) == 0))
463 {
464 RequestMsg->LookupAuthenticationPackage.Reply.Package = Package->Id;
465 return STATUS_SUCCESS;
466 }
467
468 ListEntry = ListEntry->Flink;
469 }
470
471 return STATUS_NO_SUCH_PACKAGE;
472 }
473
474
475 NTSTATUS
476 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
477 PLSAP_LOGON_CONTEXT LogonContext)
478 {
479 PAUTH_PACKAGE Package;
480 PVOID LocalBuffer = NULL;
481 ULONG PackageId;
482 NTSTATUS Status;
483
484 TRACE("(%p %p)\n", RequestMsg, LogonContext);
485
486 PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
487
488 /* Get the right authentication package */
489 Package = LsapGetAuthenticationPackage(PackageId);
490 if (Package == NULL)
491 {
492 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
493 return STATUS_NO_SUCH_PACKAGE;
494 }
495
496 if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0)
497 {
498 LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
499 HEAP_ZERO_MEMORY,
500 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength);
501 if (LocalBuffer == NULL)
502 {
503 return STATUS_INSUFFICIENT_RESOURCES;
504 }
505
506 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
507 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
508 LocalBuffer,
509 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
510 NULL);
511 if (!NT_SUCCESS(Status))
512 {
513 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
514 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
515 return Status;
516 }
517 }
518
519 Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext,
520 LocalBuffer,
521 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
522 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
523 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
524 &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
525 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
526 if (!NT_SUCCESS(Status))
527 {
528 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
529 }
530
531 if (LocalBuffer != NULL)
532 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
533
534 return Status;
535 }
536
537
538 static
539 NTSTATUS
540 LsapCopyLocalGroups(
541 IN PLSAP_LOGON_CONTEXT LogonContext,
542 IN PTOKEN_GROUPS ClientGroups,
543 IN ULONG ClientGroupsCount,
544 OUT PTOKEN_GROUPS *TokenGroups)
545 {
546 ULONG LocalGroupsLength = 0;
547 PTOKEN_GROUPS LocalGroups = NULL;
548 ULONG SidHeaderLength = 0;
549 PSID SidHeader = NULL;
550 PSID Sid;
551 ULONG SidLength;
552 ULONG CopiedSids = 0;
553 ULONG i;
554 NTSTATUS Status;
555
556 LocalGroupsLength = sizeof(TOKEN_GROUPS) +
557 (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
558 LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
559 HEAP_ZERO_MEMORY,
560 LocalGroupsLength);
561 if (LocalGroups == NULL)
562 {
563 TRACE("RtlAllocateHeap() failed\n");
564 return STATUS_INSUFFICIENT_RESOURCES;
565 }
566
567 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
568 ClientGroups,
569 LocalGroups,
570 LocalGroupsLength,
571 NULL);
572 if (!NT_SUCCESS(Status))
573 goto done;
574
575
576 SidHeaderLength = RtlLengthRequiredSid(0);
577 SidHeader = RtlAllocateHeap(RtlGetProcessHeap(),
578 HEAP_ZERO_MEMORY,
579 SidHeaderLength);
580 if (SidHeader == NULL)
581 {
582 Status = STATUS_INSUFFICIENT_RESOURCES;
583 goto done;
584 }
585
586 for (i = 0; i < ClientGroupsCount; i++)
587 {
588 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
589 LocalGroups->Groups[i].Sid,
590 SidHeader,
591 SidHeaderLength,
592 NULL);
593 if (!NT_SUCCESS(Status))
594 goto done;
595
596 SidLength = RtlLengthSid(SidHeader);
597 TRACE("Sid %lu: Length %lu\n", i, SidLength);
598
599 Sid = RtlAllocateHeap(RtlGetProcessHeap(),
600 HEAP_ZERO_MEMORY,
601 SidLength);
602 if (SidHeader == NULL)
603 {
604 Status = STATUS_INSUFFICIENT_RESOURCES;
605 goto done;
606 }
607
608 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
609 LocalGroups->Groups[i].Sid,
610 Sid,
611 SidLength,
612 NULL);
613 if (!NT_SUCCESS(Status))
614 {
615 RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
616 goto done;
617 }
618
619 LocalGroups->Groups[i].Sid = Sid;
620 CopiedSids++;
621 }
622
623 *TokenGroups = LocalGroups;
624
625 done:
626 if (SidHeader != NULL)
627 RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
628
629 if (!NT_SUCCESS(Status))
630 {
631 if (LocalGroups != NULL)
632 {
633 for (i = 0; i < CopiedSids; i++)
634 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
635
636 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
637 }
638 }
639
640 return Status;
641 }
642
643
644 NTSTATUS
645 LsapLogonUser(PLSA_API_MSG RequestMsg,
646 PLSAP_LOGON_CONTEXT LogonContext)
647 {
648 PAUTH_PACKAGE Package;
649 OBJECT_ATTRIBUTES ObjectAttributes;
650 SECURITY_QUALITY_OF_SERVICE Qos;
651 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
652 PVOID TokenInformation = NULL;
653 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
654 PUNICODE_STRING AccountName = NULL;
655 PUNICODE_STRING AuthenticatingAuthority = NULL;
656 PUNICODE_STRING MachineName = NULL;
657 PVOID LocalAuthInfo = NULL;
658 PTOKEN_GROUPS LocalGroups = NULL;
659 HANDLE TokenHandle = NULL;
660 ULONG i;
661 ULONG PackageId;
662 NTSTATUS Status;
663
664 TRACE("(%p %p)\n", RequestMsg, LogonContext);
665
666 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
667
668 /* Get the right authentication package */
669 Package = LsapGetAuthenticationPackage(PackageId);
670 if (Package == NULL)
671 {
672 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
673 return STATUS_NO_SUCH_PACKAGE;
674 }
675
676 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
677 {
678 /* Allocate the local authentication info buffer */
679 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
680 HEAP_ZERO_MEMORY,
681 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
682 if (LocalAuthInfo == NULL)
683 {
684 TRACE("RtlAllocateHeap() failed\n");
685 return STATUS_INSUFFICIENT_RESOURCES;
686 }
687
688 /* Read the authentication info from the callers adress space */
689 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
690 RequestMsg->LogonUser.Request.AuthenticationInformation,
691 LocalAuthInfo,
692 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
693 NULL);
694 if (!NT_SUCCESS(Status))
695 {
696 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
697 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
698 return Status;
699 }
700 }
701
702 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
703 {
704 Status = LsapCopyLocalGroups(LogonContext,
705 RequestMsg->LogonUser.Request.LocalGroups,
706 RequestMsg->LogonUser.Request.LocalGroupsCount,
707 &LocalGroups);
708 if (!NT_SUCCESS(Status))
709 goto done;
710
711 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
712 }
713
714 if (Package->LsaApLogonUserEx2 != NULL)
715 {
716 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
717 RequestMsg->LogonUser.Request.LogonType,
718 LocalAuthInfo,
719 RequestMsg->LogonUser.Request.AuthenticationInformation,
720 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
721 &RequestMsg->LogonUser.Reply.ProfileBuffer,
722 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
723 &RequestMsg->LogonUser.Reply.LogonId,
724 &RequestMsg->LogonUser.Reply.SubStatus,
725 &TokenInformationType,
726 &TokenInformation,
727 &AccountName,
728 &AuthenticatingAuthority,
729 &MachineName,
730 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
731 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
732 }
733 else if (Package->LsaApLogonUserEx != NULL)
734 {
735 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
736 RequestMsg->LogonUser.Request.LogonType,
737 LocalAuthInfo,
738 RequestMsg->LogonUser.Request.AuthenticationInformation,
739 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
740 &RequestMsg->LogonUser.Reply.ProfileBuffer,
741 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
742 &RequestMsg->LogonUser.Reply.LogonId,
743 &RequestMsg->LogonUser.Reply.SubStatus,
744 &TokenInformationType,
745 &TokenInformation,
746 &AccountName,
747 &AuthenticatingAuthority,
748 &MachineName);
749 }
750 else
751 {
752 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
753 RequestMsg->LogonUser.Request.LogonType,
754 LocalAuthInfo,
755 RequestMsg->LogonUser.Request.AuthenticationInformation,
756 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
757 &RequestMsg->LogonUser.Reply.ProfileBuffer,
758 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
759 &RequestMsg->LogonUser.Reply.LogonId,
760 &RequestMsg->LogonUser.Reply.SubStatus,
761 &TokenInformationType,
762 &TokenInformation,
763 &AccountName,
764 &AuthenticatingAuthority);
765 }
766
767 if (!NT_SUCCESS(Status))
768 {
769 TRACE("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
770 goto done;
771 }
772
773 if (TokenInformationType == LsaTokenInformationV1)
774 {
775 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
776
777 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
778 Qos.ImpersonationLevel = SecurityImpersonation;
779 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
780 Qos.EffectiveOnly = FALSE;
781
782 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
783 ObjectAttributes.RootDirectory = NULL;
784 ObjectAttributes.ObjectName = NULL;
785 ObjectAttributes.Attributes = 0;
786 ObjectAttributes.SecurityDescriptor = NULL;
787 ObjectAttributes.SecurityQualityOfService = &Qos;
788
789 /* Create the logon token */
790 Status = NtCreateToken(&TokenHandle,
791 TOKEN_ALL_ACCESS,
792 &ObjectAttributes,
793 TokenPrimary,
794 &RequestMsg->LogonUser.Reply.LogonId,
795 &TokenInfo1->ExpirationTime,
796 &TokenInfo1->User,
797 TokenInfo1->Groups,
798 TokenInfo1->Privileges,
799 &TokenInfo1->Owner,
800 &TokenInfo1->PrimaryGroup,
801 &TokenInfo1->DefaultDacl,
802 &RequestMsg->LogonUser.Request.SourceContext);
803 if (!NT_SUCCESS(Status))
804 {
805 TRACE("NtCreateToken failed (Status 0x%08lx)\n", Status);
806 goto done;
807 }
808 }
809 else
810 {
811 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
812 Status = STATUS_NOT_IMPLEMENTED;
813 goto done;
814 }
815
816 /* Duplicate the token handle into the client process */
817 Status = NtDuplicateObject(NtCurrentProcess(),
818 TokenHandle,
819 LogonContext->ClientProcessHandle,
820 &RequestMsg->LogonUser.Reply.Token,
821 0,
822 0,
823 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
824 if (!NT_SUCCESS(Status))
825 {
826 TRACE("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
827 goto done;
828 }
829
830 TokenHandle = NULL;
831
832 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
833 if (!NT_SUCCESS(Status))
834 {
835 TRACE("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
836 goto done;
837 }
838
839 done:
840 if (!NT_SUCCESS(Status))
841 {
842 if (TokenHandle != NULL)
843 NtClose(TokenHandle);
844 }
845
846 /* Free the local groups */
847 if (LocalGroups != NULL)
848 {
849 for (i = 0; i < LocalGroups->GroupCount; i++)
850 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
851
852 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
853 }
854
855 /* Free the local authentication info buffer */
856 if (LocalAuthInfo != NULL)
857 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
858
859 /* Free the token information */
860 if (TokenInformation != NULL)
861 {
862 if (TokenInformationType == LsaTokenInformationV1)
863 {
864 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
865
866 if (TokenInfo1 != NULL)
867 {
868 if (TokenInfo1->User.User.Sid != NULL)
869 LsapFreeHeap(TokenInfo1->User.User.Sid);
870
871 if (TokenInfo1->Groups != NULL)
872 {
873 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
874 {
875 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
876 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
877 }
878
879 LsapFreeHeap(TokenInfo1->Groups);
880 }
881
882 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
883 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
884
885 if (TokenInfo1->Privileges != NULL)
886 LsapFreeHeap(TokenInfo1->Privileges);
887
888 if (TokenInfo1->Owner.Owner != NULL)
889 LsapFreeHeap(TokenInfo1->Owner.Owner);
890
891 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
892 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
893
894 LsapFreeHeap(TokenInfo1);
895 }
896 }
897 else
898 {
899 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
900 }
901 }
902
903 /* Free the account name */
904 if (AccountName != NULL)
905 {
906 if (AccountName->Buffer != NULL)
907 LsapFreeHeap(AccountName->Buffer);
908
909 LsapFreeHeap(AccountName);
910 }
911
912 /* Free the authentication authority */
913 if (AuthenticatingAuthority != NULL)
914 {
915 if (AuthenticatingAuthority != NULL)
916 LsapFreeHeap(AuthenticatingAuthority->Buffer);
917
918 LsapFreeHeap(AuthenticatingAuthority);
919 }
920
921 /* Free the machine name */
922 if (MachineName != NULL)
923 {
924 if (MachineName->Buffer != NULL)
925 LsapFreeHeap(MachineName->Buffer);
926
927 LsapFreeHeap(MachineName);
928 }
929
930 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
931
932 return Status;
933 }
934
935 /* EOF */