[LSASRV][MSV1_0]
[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 VOID
98 NTAPI
99 LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr);
100
101 /* GLOBALS *****************************************************************/
102
103 static LIST_ENTRY PackageListHead;
104 static ULONG PackageId;
105 static LSA_DISPATCH_TABLE DispatchTable;
106
107 #define CONST_LUID(x1, x2) {x1, x2}
108 static const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0);
109 static const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0);
110 static const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0);
111
112
113 /* FUNCTIONS ***************************************************************/
114
115 static
116 NTSTATUS
117 NTAPI
118 LsapAddAuthPackage(IN PWSTR ValueName,
119 IN ULONG ValueType,
120 IN PVOID ValueData,
121 IN ULONG ValueLength,
122 IN PVOID Context,
123 IN PVOID EntryContext)
124 {
125 PAUTH_PACKAGE Package = NULL;
126 UNICODE_STRING PackageName;
127 STRING ProcName;
128 PULONG Id;
129 NTSTATUS Status = STATUS_SUCCESS;
130
131 TRACE("LsapAddAuthPackage()\n");
132
133 PackageName.Length = (USHORT)ValueLength - sizeof(WCHAR);
134 PackageName.MaximumLength = (USHORT)ValueLength;
135 PackageName.Buffer = ValueData;
136
137 Id = (PULONG)Context;
138
139 Package = RtlAllocateHeap(RtlGetProcessHeap(),
140 HEAP_ZERO_MEMORY,
141 sizeof(AUTH_PACKAGE));
142 if (Package == NULL)
143 return STATUS_INSUFFICIENT_RESOURCES;
144
145 Status = LdrLoadDll(NULL,
146 NULL,
147 &PackageName,
148 &Package->ModuleHandle);
149 if (!NT_SUCCESS(Status))
150 {
151 TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status);
152 goto done;
153 }
154
155 RtlInitAnsiString(&ProcName, "LsaApInitializePackage");
156 Status = LdrGetProcedureAddress(Package->ModuleHandle,
157 &ProcName,
158 0,
159 (PVOID *)&Package->LsaApInitializePackage);
160 if (!NT_SUCCESS(Status))
161 {
162 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
163 goto done;
164 }
165
166 RtlInitAnsiString(&ProcName, "LsaApCallPackage");
167 Status = LdrGetProcedureAddress(Package->ModuleHandle,
168 &ProcName,
169 0,
170 (PVOID *)&Package->LsaApCallPackage);
171 if (!NT_SUCCESS(Status))
172 {
173 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
174 goto done;
175 }
176
177 RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough");
178 Status = LdrGetProcedureAddress(Package->ModuleHandle,
179 &ProcName,
180 0,
181 (PVOID *)&Package->LsaApCallPackagePassthrough);
182 if (!NT_SUCCESS(Status))
183 {
184 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
185 goto done;
186 }
187
188 RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted");
189 Status = LdrGetProcedureAddress(Package->ModuleHandle,
190 &ProcName,
191 0,
192 (PVOID *)&Package->LsaApCallPackageUntrusted);
193 if (!NT_SUCCESS(Status))
194 {
195 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
196 goto done;
197 }
198
199 RtlInitAnsiString(&ProcName, "LsaApLogonTerminated");
200 Status = LdrGetProcedureAddress(Package->ModuleHandle,
201 &ProcName,
202 0,
203 (PVOID *)&Package->LsaApLogonTerminated);
204 if (!NT_SUCCESS(Status))
205 {
206 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
207 goto done;
208 }
209
210 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2");
211 Status = LdrGetProcedureAddress(Package->ModuleHandle,
212 &ProcName,
213 0,
214 (PVOID *)&Package->LsaApLogonUserEx2);
215 if (!NT_SUCCESS(Status))
216 {
217 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx");
218 Status = LdrGetProcedureAddress(Package->ModuleHandle,
219 &ProcName,
220 0,
221 (PVOID *)&Package->LsaApLogonUserEx);
222 if (!NT_SUCCESS(Status))
223 {
224 RtlInitAnsiString(&ProcName, "LsaApLogonUser");
225 Status = LdrGetProcedureAddress(Package->ModuleHandle,
226 &ProcName,
227 0,
228 (PVOID *)&Package->LsaApLogonUser);
229 if (!NT_SUCCESS(Status))
230 {
231 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
232 goto done;
233 }
234 }
235 }
236
237 /* Initialize the current package */
238 Status = Package->LsaApInitializePackage(*Id,
239 &DispatchTable,
240 NULL,
241 NULL,
242 &Package->Name);
243 if (!NT_SUCCESS(Status))
244 {
245 TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status);
246 goto done;
247 }
248
249 TRACE("Package Name: %s\n", Package->Name->Buffer);
250
251 Package->Id = *Id;
252 (*Id)++;
253
254 InsertTailList(&PackageListHead, &Package->Entry);
255
256 done:
257 if (!NT_SUCCESS(Status))
258 {
259 if (Package != NULL)
260 {
261 if (Package->ModuleHandle != NULL)
262 LdrUnloadDll(Package->ModuleHandle);
263
264 if (Package->Name != NULL)
265 {
266 if (Package->Name->Buffer != NULL)
267 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer);
268
269 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name);
270 }
271
272 RtlFreeHeap(RtlGetProcessHeap(), 0, Package);
273 }
274 }
275
276 return Status;
277 }
278
279
280 static
281 PAUTH_PACKAGE
282 LsapGetAuthenticationPackage(IN ULONG PackageId)
283 {
284 PLIST_ENTRY ListEntry;
285 PAUTH_PACKAGE Package;
286
287 ListEntry = PackageListHead.Flink;
288 while (ListEntry != &PackageListHead)
289 {
290 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
291
292 if (Package->Id == PackageId)
293 {
294 return Package;
295 }
296
297 ListEntry = ListEntry->Flink;
298 }
299
300 return NULL;
301 }
302
303
304 static
305 PVOID
306 NTAPI
307 LsapAllocateHeap(IN ULONG Length)
308 {
309 return RtlAllocateHeap(RtlGetProcessHeap(),
310 HEAP_ZERO_MEMORY,
311 Length);
312 }
313
314
315 static
316 VOID
317 NTAPI
318 LsapFreeHeap(IN PVOID Base)
319 {
320 RtlFreeHeap(RtlGetProcessHeap(),
321 0,
322 Base);
323 }
324
325
326 static
327 NTSTATUS
328 NTAPI
329 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
330 IN ULONG LengthRequired,
331 OUT PVOID *ClientBaseAddress)
332 {
333 PLSAP_LOGON_CONTEXT LogonContext;
334 ULONG Length;
335
336 *ClientBaseAddress = NULL;
337
338 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
339
340 Length = LengthRequired;
341 return NtAllocateVirtualMemory(LogonContext->ClientProcessHandle,
342 ClientBaseAddress,
343 0,
344 &Length,
345 MEM_COMMIT,
346 PAGE_READWRITE);
347 }
348
349
350 static
351 NTSTATUS
352 NTAPI
353 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
354 IN PVOID ClientBaseAddress)
355 {
356 PLSAP_LOGON_CONTEXT LogonContext;
357 ULONG Length;
358
359 if (ClientBaseAddress == NULL)
360 return STATUS_SUCCESS;
361
362 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
363
364 Length = 0;
365 return NtFreeVirtualMemory(LogonContext->ClientProcessHandle,
366 &ClientBaseAddress,
367 &Length,
368 MEM_RELEASE);
369 }
370
371
372 static
373 NTSTATUS
374 NTAPI
375 LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
376 IN ULONG Length,
377 IN PVOID ClientBaseAddress,
378 IN PVOID BufferToCopy)
379 {
380 PLSAP_LOGON_CONTEXT LogonContext;
381
382 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
383
384 return NtWriteVirtualMemory(LogonContext->ClientProcessHandle,
385 ClientBaseAddress,
386 BufferToCopy,
387 Length,
388 NULL);
389 }
390
391
392 static
393 NTSTATUS
394 NTAPI
395 LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
396 IN ULONG Length,
397 IN PVOID BufferToCopy,
398 IN PVOID ClientBaseAddress)
399 {
400 PLSAP_LOGON_CONTEXT LogonContext;
401
402 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
403
404 return NtReadVirtualMemory(LogonContext->ClientProcessHandle,
405 ClientBaseAddress,
406 BufferToCopy,
407 Length,
408 NULL);
409 }
410
411
412 NTSTATUS
413 LsapInitAuthPackages(VOID)
414 {
415 RTL_QUERY_REGISTRY_TABLE AuthPackageTable[] = {
416 {LsapAddAuthPackage, 0, L"Authentication Packages", NULL, REG_NONE, NULL, 0},
417 {NULL, 0, NULL, NULL, REG_NONE, NULL, 0}};
418
419 NTSTATUS Status;
420
421 InitializeListHead(&PackageListHead);
422 PackageId = 0;
423
424 /* Initialize the dispatch table */
425 DispatchTable.CreateLogonSession = &LsapCreateLogonSession;
426 DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession;
427 DispatchTable.AddCredential = NULL;
428 DispatchTable.GetCredentials = NULL;
429 DispatchTable.DeleteCredential = NULL;
430 DispatchTable.AllocateLsaHeap = &LsapAllocateHeap;
431 DispatchTable.FreeLsaHeap = &LsapFreeHeap;
432 DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
433 DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
434 DispatchTable.CopyToClientBuffer = &LsapCopyToClientBuffer;
435 DispatchTable.CopyFromClientBuffer = &LsapCopyFromClientBuffer;
436
437 /* Add registered authentication packages */
438 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
439 L"Lsa",
440 AuthPackageTable,
441 &PackageId,
442 NULL);
443
444 return Status;
445 }
446
447
448 NTSTATUS
449 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg,
450 PLSAP_LOGON_CONTEXT LogonContext)
451 {
452 PLIST_ENTRY ListEntry;
453 PAUTH_PACKAGE Package;
454 ULONG PackageNameLength;
455 PCHAR PackageName;
456
457 TRACE("(%p %p)\n", RequestMsg, LogonContext);
458
459 PackageNameLength = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength;
460 PackageName = RequestMsg->LookupAuthenticationPackage.Request.PackageName;
461
462 TRACE("PackageName: %s\n", PackageName);
463
464 ListEntry = PackageListHead.Flink;
465 while (ListEntry != &PackageListHead)
466 {
467 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
468
469 if ((PackageNameLength == Package->Name->Length) &&
470 (_strnicmp(PackageName, Package->Name->Buffer, Package->Name->Length) == 0))
471 {
472 RequestMsg->LookupAuthenticationPackage.Reply.Package = Package->Id;
473 return STATUS_SUCCESS;
474 }
475
476 ListEntry = ListEntry->Flink;
477 }
478
479 return STATUS_NO_SUCH_PACKAGE;
480 }
481
482
483 NTSTATUS
484 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
485 PLSAP_LOGON_CONTEXT LogonContext)
486 {
487 PAUTH_PACKAGE Package;
488 PVOID LocalBuffer = NULL;
489 ULONG PackageId;
490 NTSTATUS Status;
491
492 TRACE("(%p %p)\n", RequestMsg, LogonContext);
493
494 PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
495
496 /* Get the right authentication package */
497 Package = LsapGetAuthenticationPackage(PackageId);
498 if (Package == NULL)
499 {
500 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
501 return STATUS_NO_SUCH_PACKAGE;
502 }
503
504 if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0)
505 {
506 LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
507 HEAP_ZERO_MEMORY,
508 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength);
509 if (LocalBuffer == NULL)
510 {
511 return STATUS_INSUFFICIENT_RESOURCES;
512 }
513
514 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
515 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
516 LocalBuffer,
517 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
518 NULL);
519 if (!NT_SUCCESS(Status))
520 {
521 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
522 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
523 return Status;
524 }
525 }
526
527 Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext,
528 LocalBuffer,
529 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
530 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
531 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
532 &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
533 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
534 if (!NT_SUCCESS(Status))
535 {
536 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
537 }
538
539 if (LocalBuffer != NULL)
540 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
541
542 return Status;
543 }
544
545
546 static
547 NTSTATUS
548 LsapCopyLocalGroups(
549 IN PLSAP_LOGON_CONTEXT LogonContext,
550 IN PTOKEN_GROUPS ClientGroups,
551 IN ULONG ClientGroupsCount,
552 OUT PTOKEN_GROUPS *TokenGroups)
553 {
554 ULONG LocalGroupsLength = 0;
555 PTOKEN_GROUPS LocalGroups = NULL;
556 ULONG SidHeaderLength = 0;
557 PSID SidHeader = NULL;
558 PSID SrcSid, DstSid;
559 ULONG SidLength;
560 ULONG AllocatedSids = 0;
561 ULONG i;
562 NTSTATUS Status;
563
564 LocalGroupsLength = sizeof(TOKEN_GROUPS) +
565 (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
566 LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
567 HEAP_ZERO_MEMORY,
568 LocalGroupsLength);
569 if (LocalGroups == NULL)
570 {
571 TRACE("RtlAllocateHeap() failed\n");
572 return STATUS_INSUFFICIENT_RESOURCES;
573 }
574
575 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
576 ClientGroups,
577 LocalGroups,
578 LocalGroupsLength,
579 NULL);
580 if (!NT_SUCCESS(Status))
581 goto done;
582
583
584 SidHeaderLength = RtlLengthRequiredSid(0);
585 SidHeader = RtlAllocateHeap(RtlGetProcessHeap(),
586 HEAP_ZERO_MEMORY,
587 SidHeaderLength);
588 if (SidHeader == NULL)
589 {
590 Status = STATUS_INSUFFICIENT_RESOURCES;
591 goto done;
592 }
593
594 for (i = 0; i < ClientGroupsCount; i++)
595 {
596 SrcSid = LocalGroups->Groups[i].Sid;
597
598 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
599 SrcSid,
600 SidHeader,
601 SidHeaderLength,
602 NULL);
603 if (!NT_SUCCESS(Status))
604 goto done;
605
606 SidLength = RtlLengthSid(SidHeader);
607 TRACE("Sid %lu: Length %lu\n", i, SidLength);
608
609 DstSid = RtlAllocateHeap(RtlGetProcessHeap(),
610 HEAP_ZERO_MEMORY,
611 SidLength);
612 if (DstSid == NULL)
613 {
614 Status = STATUS_INSUFFICIENT_RESOURCES;
615 goto done;
616 }
617
618 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
619 SrcSid,
620 DstSid,
621 SidLength,
622 NULL);
623 if (!NT_SUCCESS(Status))
624 {
625 RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid);
626 goto done;
627 }
628
629 LocalGroups->Groups[i].Sid = DstSid;
630 AllocatedSids++;
631 }
632
633 *TokenGroups = LocalGroups;
634
635 done:
636 if (SidHeader != NULL)
637 RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
638
639 if (!NT_SUCCESS(Status))
640 {
641 if (LocalGroups != NULL)
642 {
643 for (i = 0; i < AllocatedSids; i++)
644 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
645
646 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
647 }
648 }
649
650 return Status;
651 }
652
653
654 static
655 NTSTATUS
656 LsapAddLocalGroups(
657 IN PVOID TokenInformation,
658 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
659 IN PTOKEN_GROUPS LocalGroups)
660 {
661 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
662 PTOKEN_GROUPS Groups;
663 ULONG Length;
664 ULONG i;
665 ULONG j;
666
667 if (LocalGroups == NULL || LocalGroups->GroupCount == 0)
668 return STATUS_SUCCESS;
669
670 if (TokenInformationType == LsaTokenInformationV1)
671 {
672 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
673
674 if (TokenInfo1->Groups != NULL)
675 {
676 Length = sizeof(TOKEN_GROUPS) +
677 (LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
678
679 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
680 if (Groups == NULL)
681 {
682 ERR("Group buffer allocation failed!\n");
683 return STATUS_INSUFFICIENT_RESOURCES;
684 }
685
686 Groups->GroupCount = LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount;
687
688 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
689 {
690 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
691 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
692 }
693
694 for (j = 0; j < LocalGroups->GroupCount; i++, j++)
695 {
696 Groups->Groups[i].Sid = LocalGroups->Groups[j].Sid;
697 Groups->Groups[i].Attributes = LocalGroups->Groups[j].Attributes;
698 LocalGroups->Groups[j].Sid = NULL;
699 }
700
701 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
702
703 TokenInfo1->Groups = Groups;
704 }
705 else
706 {
707 Length = sizeof(TOKEN_GROUPS) +
708 (LocalGroups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
709
710 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
711 if (Groups == NULL)
712 {
713 ERR("Group buffer allocation failed!\n");
714 return STATUS_INSUFFICIENT_RESOURCES;
715 }
716
717 Groups->GroupCount = LocalGroups->GroupCount;
718
719 for (i = 0; i < LocalGroups->GroupCount; i++)
720 {
721 Groups->Groups[i].Sid = LocalGroups->Groups[i].Sid;
722 Groups->Groups[i].Attributes = LocalGroups->Groups[i].Attributes;
723 }
724
725 TokenInfo1->Groups = Groups;
726 }
727 }
728 else
729 {
730 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
731 return STATUS_NOT_IMPLEMENTED;
732 }
733
734 return STATUS_SUCCESS;
735 }
736
737 static
738 NTSTATUS
739 LsapAddDefaultGroups(
740 IN PVOID TokenInformation,
741 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
742 IN SECURITY_LOGON_TYPE LogonType)
743 {
744 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
745 PTOKEN_GROUPS Groups;
746 ULONG i, Length;
747 PSID SrcSid;
748
749 if (TokenInformationType == LsaTokenInformationV1)
750 {
751 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
752
753 if (TokenInfo1->Groups != NULL)
754 {
755 Length = sizeof(TOKEN_GROUPS) +
756 (TokenInfo1->Groups->GroupCount + 2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
757
758 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
759 if (Groups == NULL)
760 {
761 ERR("Group buffer allocation failed!\n");
762 return STATUS_INSUFFICIENT_RESOURCES;
763 }
764
765 Groups->GroupCount = TokenInfo1->Groups->GroupCount;
766
767 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
768 {
769 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
770 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
771 }
772
773 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
774
775 TokenInfo1->Groups = Groups;
776
777 }
778 else
779 {
780 Length = sizeof(TOKEN_GROUPS) +
781 (2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
782
783 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
784 if (Groups == NULL)
785 {
786 ERR("Group buffer allocation failed!\n");
787 return STATUS_INSUFFICIENT_RESOURCES;
788 }
789
790 TokenInfo1->Groups = Groups;
791 }
792
793 /* Append the World SID (aka Everyone) */
794 Length = RtlLengthSid(LsapWorldSid);
795 Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
796 HEAP_ZERO_MEMORY,
797 Length);
798 if (Groups->Groups[Groups->GroupCount].Sid == NULL)
799 return STATUS_INSUFFICIENT_RESOURCES;
800
801 RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
802 LsapWorldSid,
803 Length);
804
805 Groups->Groups[Groups->GroupCount].Attributes =
806 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
807
808 Groups->GroupCount++;
809
810 /* Append the logon type SID */
811 switch (LogonType)
812 {
813 case Interactive:
814 SrcSid = LsapInteractiveSid;
815 break;
816
817 case Network:
818 SrcSid = LsapNetworkSid;
819 break;
820
821 case Batch:
822 SrcSid = LsapBatchSid;
823 break;
824
825 case Service:
826 SrcSid = LsapServiceSid;
827 break;
828
829 default:
830 FIXME("LogonType %d is not supported!\n", LogonType);
831 return STATUS_NOT_IMPLEMENTED;
832 }
833
834 Length = RtlLengthSid(SrcSid);
835 Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
836 HEAP_ZERO_MEMORY,
837 Length);
838 if (Groups->Groups[Groups->GroupCount].Sid == NULL)
839 return STATUS_INSUFFICIENT_RESOURCES;
840
841 RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
842 SrcSid,
843 Length);
844
845 Groups->Groups[Groups->GroupCount].Attributes =
846 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
847
848 Groups->GroupCount++;
849 }
850 else
851 {
852 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
853 return STATUS_NOT_IMPLEMENTED;
854 }
855
856 return STATUS_SUCCESS;
857 }
858
859
860 static
861 NTSTATUS
862 LsapSetTokenOwner(
863 IN PVOID TokenInformation,
864 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
865 {
866 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
867 PSID OwnerSid = NULL;
868 ULONG i, Length;
869
870 if (TokenInformationType == LsaTokenInformationV1)
871 {
872 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
873
874 if (TokenInfo1->Owner.Owner != NULL)
875 return STATUS_SUCCESS;
876
877 OwnerSid = TokenInfo1->User.User.Sid;
878 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
879 {
880 if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
881 {
882 OwnerSid = LsapAdministratorsSid;
883 break;
884 }
885 }
886
887 Length = RtlLengthSid(OwnerSid);
888 TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length);
889 if (TokenInfo1->Owner.Owner == NULL)
890 return STATUS_INSUFFICIENT_RESOURCES;
891
892 RtlCopyMemory(TokenInfo1->Owner.Owner,
893 OwnerSid,
894 Length);
895 }
896
897 return STATUS_SUCCESS;
898 }
899
900
901 static
902 NTSTATUS
903 LsapAddTokenDefaultDacl(
904 IN PVOID TokenInformation,
905 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
906 {
907 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
908 PACL Dacl = NULL;
909 ULONG Length;
910
911 if (TokenInformationType == LsaTokenInformationV1)
912 {
913 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
914
915 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
916 return STATUS_SUCCESS;
917
918 Length = sizeof(ACL) +
919 (2 * sizeof(ACCESS_ALLOWED_ACE)) +
920 RtlLengthSid(TokenInfo1->Owner.Owner) +
921 RtlLengthSid(LsapLocalSystemSid);
922
923 Dacl = DispatchTable.AllocateLsaHeap(Length);
924 if (Dacl == NULL)
925 return STATUS_INSUFFICIENT_RESOURCES;
926
927 RtlCreateAcl(Dacl, Length, ACL_REVISION);
928
929 RtlAddAccessAllowedAce(Dacl,
930 ACL_REVISION,
931 GENERIC_ALL,
932 TokenInfo1->Owner.Owner);
933
934 /* SID: S-1-5-18 */
935 RtlAddAccessAllowedAce(Dacl,
936 ACL_REVISION,
937 GENERIC_ALL,
938 LsapLocalSystemSid);
939
940 TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
941 }
942
943 return STATUS_SUCCESS;
944 }
945
946
947 static
948 NTSTATUS
949 LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
950 PLSAPR_LUID_AND_ATTRIBUTES Privilege)
951 {
952 PTOKEN_PRIVILEGES LocalPrivileges;
953 ULONG Length, TokenPrivilegeCount, i;
954 NTSTATUS Status = STATUS_SUCCESS;
955
956 if (*TokenPrivileges == NULL)
957 {
958 Length = sizeof(TOKEN_PRIVILEGES) +
959 (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
960 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
961 0,
962 Length);
963 if (LocalPrivileges == NULL)
964 return STATUS_INSUFFICIENT_RESOURCES;
965
966 LocalPrivileges->PrivilegeCount = 1;
967 LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
968 LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
969 }
970 else
971 {
972 TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
973
974 for (i = 0; i < TokenPrivilegeCount; i++)
975 {
976 if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
977 return STATUS_SUCCESS;
978 }
979
980 Length = sizeof(TOKEN_PRIVILEGES) +
981 (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
982 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
983 0,
984 Length);
985 if (LocalPrivileges == NULL)
986 return STATUS_INSUFFICIENT_RESOURCES;
987
988 LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
989 for (i = 0; i < TokenPrivilegeCount; i++)
990 {
991 LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
992 LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
993 }
994
995 LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
996 LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
997
998 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
999 }
1000
1001 *TokenPrivileges = LocalPrivileges;
1002
1003 return Status;
1004 }
1005
1006 static
1007 NTSTATUS
1008 LsapSetPrivileges(
1009 IN PVOID TokenInformation,
1010 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1011 {
1012 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1013 LSAPR_HANDLE PolicyHandle = NULL;
1014 LSAPR_HANDLE AccountHandle = NULL;
1015 PLSAPR_PRIVILEGE_SET Privileges = NULL;
1016 ULONG i, j;
1017 NTSTATUS Status;
1018
1019 if (TokenInformationType == LsaTokenInformationV1)
1020 {
1021 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1022
1023 Status = LsarOpenPolicy(NULL,
1024 NULL,
1025 0,
1026 &PolicyHandle);
1027 if (!NT_SUCCESS(Status))
1028 return Status;
1029
1030 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1031 {
1032 Status = LsarOpenAccount(PolicyHandle,
1033 TokenInfo1->Groups->Groups[i].Sid,
1034 ACCOUNT_VIEW,
1035 &AccountHandle);
1036 if (NT_SUCCESS(Status))
1037 {
1038 Status = LsarEnumeratePrivilegesAccount(AccountHandle,
1039 &Privileges);
1040 if (NT_SUCCESS(Status))
1041 {
1042 for (j = 0; j < Privileges->PrivilegeCount; j++)
1043 {
1044 Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
1045 &(Privileges->Privilege[j]));
1046 if (!NT_SUCCESS(Status))
1047 return Status;
1048 }
1049
1050 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1051 Privileges = NULL;
1052 }
1053 }
1054
1055 LsarClose(&AccountHandle);
1056 }
1057
1058 LsarClose(&PolicyHandle);
1059
1060 if (TokenInfo1->Privileges != NULL)
1061 {
1062 for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
1063 {
1064 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
1065 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
1066 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
1067 {
1068 TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
1069 }
1070 }
1071 }
1072 }
1073
1074 return STATUS_SUCCESS;
1075 }
1076
1077
1078 NTSTATUS
1079 LsapLogonUser(PLSA_API_MSG RequestMsg,
1080 PLSAP_LOGON_CONTEXT LogonContext)
1081 {
1082 PAUTH_PACKAGE Package;
1083 OBJECT_ATTRIBUTES ObjectAttributes;
1084 SECURITY_QUALITY_OF_SERVICE Qos;
1085 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
1086 PVOID TokenInformation = NULL;
1087 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
1088 PUNICODE_STRING AccountName = NULL;
1089 PUNICODE_STRING AuthenticatingAuthority = NULL;
1090 PUNICODE_STRING MachineName = NULL;
1091 PVOID LocalAuthInfo = NULL;
1092 PTOKEN_GROUPS LocalGroups = NULL;
1093 HANDLE TokenHandle = NULL;
1094 ULONG i;
1095 ULONG PackageId;
1096 SECURITY_LOGON_TYPE LogonType;
1097 NTSTATUS Status;
1098
1099 TRACE("(%p %p)\n", RequestMsg, LogonContext);
1100
1101 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
1102 LogonType = RequestMsg->LogonUser.Request.LogonType;
1103
1104 /* Get the right authentication package */
1105 Package = LsapGetAuthenticationPackage(PackageId);
1106 if (Package == NULL)
1107 {
1108 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
1109 return STATUS_NO_SUCH_PACKAGE;
1110 }
1111
1112 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
1113 {
1114 /* Allocate the local authentication info buffer */
1115 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1116 HEAP_ZERO_MEMORY,
1117 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
1118 if (LocalAuthInfo == NULL)
1119 {
1120 ERR("RtlAllocateHeap() failed\n");
1121 return STATUS_INSUFFICIENT_RESOURCES;
1122 }
1123
1124 /* Read the authentication info from the callers adress space */
1125 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
1126 RequestMsg->LogonUser.Request.AuthenticationInformation,
1127 LocalAuthInfo,
1128 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1129 NULL);
1130 if (!NT_SUCCESS(Status))
1131 {
1132 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
1133 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1134 return Status;
1135 }
1136 }
1137
1138 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
1139 {
1140 Status = LsapCopyLocalGroups(LogonContext,
1141 RequestMsg->LogonUser.Request.LocalGroups,
1142 RequestMsg->LogonUser.Request.LocalGroupsCount,
1143 &LocalGroups);
1144 if (!NT_SUCCESS(Status))
1145 {
1146 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
1147 goto done;
1148 }
1149
1150 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
1151 }
1152
1153 if (Package->LsaApLogonUserEx2 != NULL)
1154 {
1155 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
1156 RequestMsg->LogonUser.Request.LogonType,
1157 LocalAuthInfo,
1158 RequestMsg->LogonUser.Request.AuthenticationInformation,
1159 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1160 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1161 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1162 &RequestMsg->LogonUser.Reply.LogonId,
1163 &RequestMsg->LogonUser.Reply.SubStatus,
1164 &TokenInformationType,
1165 &TokenInformation,
1166 &AccountName,
1167 &AuthenticatingAuthority,
1168 &MachineName,
1169 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
1170 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
1171 }
1172 else if (Package->LsaApLogonUserEx != NULL)
1173 {
1174 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
1175 RequestMsg->LogonUser.Request.LogonType,
1176 LocalAuthInfo,
1177 RequestMsg->LogonUser.Request.AuthenticationInformation,
1178 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1179 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1180 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1181 &RequestMsg->LogonUser.Reply.LogonId,
1182 &RequestMsg->LogonUser.Reply.SubStatus,
1183 &TokenInformationType,
1184 &TokenInformation,
1185 &AccountName,
1186 &AuthenticatingAuthority,
1187 &MachineName);
1188 }
1189 else
1190 {
1191 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
1192 RequestMsg->LogonUser.Request.LogonType,
1193 LocalAuthInfo,
1194 RequestMsg->LogonUser.Request.AuthenticationInformation,
1195 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1196 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1197 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1198 &RequestMsg->LogonUser.Reply.LogonId,
1199 &RequestMsg->LogonUser.Reply.SubStatus,
1200 &TokenInformationType,
1201 &TokenInformation,
1202 &AccountName,
1203 &AuthenticatingAuthority);
1204 }
1205
1206 if (!NT_SUCCESS(Status))
1207 {
1208 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
1209 goto done;
1210 }
1211
1212 if (LocalGroups->GroupCount > 0)
1213 {
1214 /* Add local groups to the token information */
1215 Status = LsapAddLocalGroups(TokenInformation,
1216 TokenInformationType,
1217 LocalGroups);
1218 if (!NT_SUCCESS(Status))
1219 {
1220 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status);
1221 goto done;
1222 }
1223 }
1224
1225 Status = LsapAddDefaultGroups(TokenInformation,
1226 TokenInformationType,
1227 LogonType);
1228 if (!NT_SUCCESS(Status))
1229 {
1230 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status);
1231 goto done;
1232 }
1233
1234 Status = LsapSetTokenOwner(TokenInformation,
1235 TokenInformationType);
1236 if (!NT_SUCCESS(Status))
1237 {
1238 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
1239 goto done;
1240 }
1241
1242 Status = LsapAddTokenDefaultDacl(TokenInformation,
1243 TokenInformationType);
1244 if (!NT_SUCCESS(Status))
1245 {
1246 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
1247 goto done;
1248 }
1249
1250 Status = LsapSetPrivileges(TokenInformation,
1251 TokenInformationType);
1252 if (!NT_SUCCESS(Status))
1253 {
1254 ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
1255 goto done;
1256 }
1257
1258 if (TokenInformationType == LsaTokenInformationV1)
1259 {
1260 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1261
1262 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1263 Qos.ImpersonationLevel = SecurityImpersonation;
1264 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
1265 Qos.EffectiveOnly = FALSE;
1266
1267 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1268 ObjectAttributes.RootDirectory = NULL;
1269 ObjectAttributes.ObjectName = NULL;
1270 ObjectAttributes.Attributes = 0;
1271 ObjectAttributes.SecurityDescriptor = NULL;
1272 ObjectAttributes.SecurityQualityOfService = &Qos;
1273
1274 /* Create the logon token */
1275 Status = NtCreateToken(&TokenHandle,
1276 TOKEN_ALL_ACCESS,
1277 &ObjectAttributes,
1278 TokenPrimary,
1279 &RequestMsg->LogonUser.Reply.LogonId,
1280 &TokenInfo1->ExpirationTime,
1281 &TokenInfo1->User,
1282 TokenInfo1->Groups,
1283 TokenInfo1->Privileges,
1284 &TokenInfo1->Owner,
1285 &TokenInfo1->PrimaryGroup,
1286 &TokenInfo1->DefaultDacl,
1287 &RequestMsg->LogonUser.Request.SourceContext);
1288 if (!NT_SUCCESS(Status))
1289 {
1290 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
1291 goto done;
1292 }
1293 }
1294 else
1295 {
1296 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1297 Status = STATUS_NOT_IMPLEMENTED;
1298 goto done;
1299 }
1300
1301 /* Duplicate the token handle into the client process */
1302 Status = NtDuplicateObject(NtCurrentProcess(),
1303 TokenHandle,
1304 LogonContext->ClientProcessHandle,
1305 &RequestMsg->LogonUser.Reply.Token,
1306 0,
1307 0,
1308 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
1309 if (!NT_SUCCESS(Status))
1310 {
1311 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
1312 goto done;
1313 }
1314
1315 TokenHandle = NULL;
1316
1317 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
1318 if (!NT_SUCCESS(Status))
1319 {
1320 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
1321 goto done;
1322 }
1323
1324 done:
1325 if (!NT_SUCCESS(Status))
1326 {
1327 if (TokenHandle != NULL)
1328 NtClose(TokenHandle);
1329 }
1330
1331 /* Free the local groups */
1332 if (LocalGroups != NULL)
1333 {
1334 for (i = 0; i < LocalGroups->GroupCount; i++)
1335 {
1336 if (LocalGroups->Groups[i].Sid != NULL)
1337 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
1338 }
1339
1340 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
1341 }
1342
1343 /* Free the local authentication info buffer */
1344 if (LocalAuthInfo != NULL)
1345 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1346
1347 /* Free the token information */
1348 if (TokenInformation != NULL)
1349 {
1350 if (TokenInformationType == LsaTokenInformationV1)
1351 {
1352 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1353
1354 if (TokenInfo1 != NULL)
1355 {
1356 if (TokenInfo1->User.User.Sid != NULL)
1357 LsapFreeHeap(TokenInfo1->User.User.Sid);
1358
1359 if (TokenInfo1->Groups != NULL)
1360 {
1361 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1362 {
1363 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
1364 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
1365 }
1366
1367 LsapFreeHeap(TokenInfo1->Groups);
1368 }
1369
1370 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
1371 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
1372
1373 if (TokenInfo1->Privileges != NULL)
1374 LsapFreeHeap(TokenInfo1->Privileges);
1375
1376 if (TokenInfo1->Owner.Owner != NULL)
1377 LsapFreeHeap(TokenInfo1->Owner.Owner);
1378
1379 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1380 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
1381
1382 LsapFreeHeap(TokenInfo1);
1383 }
1384 }
1385 else
1386 {
1387 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1388 }
1389 }
1390
1391 /* Free the account name */
1392 if (AccountName != NULL)
1393 {
1394 if (AccountName->Buffer != NULL)
1395 LsapFreeHeap(AccountName->Buffer);
1396
1397 LsapFreeHeap(AccountName);
1398 }
1399
1400 /* Free the authentication authority */
1401 if (AuthenticatingAuthority != NULL)
1402 {
1403 if (AuthenticatingAuthority != NULL)
1404 LsapFreeHeap(AuthenticatingAuthority->Buffer);
1405
1406 LsapFreeHeap(AuthenticatingAuthority);
1407 }
1408
1409 /* Free the machine name */
1410 if (MachineName != NULL)
1411 {
1412 if (MachineName->Buffer != NULL)
1413 LsapFreeHeap(MachineName->Buffer);
1414
1415 LsapFreeHeap(MachineName);
1416 }
1417
1418 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
1419
1420 return Status;
1421 }
1422
1423 /* EOF */