Sync with trunk r63647.
[reactos.git] / 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 #include <ndk/mmfuncs.h>
12 #include <ndk/sefuncs.h>
13 #include <ndk/umfuncs.h>
14
15 typedef enum _LSA_TOKEN_INFORMATION_TYPE
16 {
17 LsaTokenInformationNull,
18 LsaTokenInformationV1
19 } LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;
20
21 typedef struct _LSA_TOKEN_INFORMATION_V1
22 {
23 LARGE_INTEGER ExpirationTime;
24 TOKEN_USER User;
25 PTOKEN_GROUPS Groups;
26 TOKEN_PRIMARY_GROUP PrimaryGroup;
27 PTOKEN_PRIVILEGES Privileges;
28 TOKEN_OWNER Owner;
29 TOKEN_DEFAULT_DACL DefaultDacl;
30 } LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1;
31
32 typedef PVOID PLSA_CLIENT_REQUEST;
33
34 typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID);
35 typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID);
36
37 typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG);
38 typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID);
39 typedef NTSTATUS (NTAPI *PLSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, PVOID*);
40 typedef NTSTATUS (NTAPI *PLSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, PVOID);
41 typedef NTSTATUS (NTAPI *PLSA_COPY_TO_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG,
42 PVOID, PVOID);
43 typedef NTSTATUS (NTAPI *PLSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,
44 ULONG, PVOID, PVOID);
45
46 typedef struct LSA_DISPATCH_TABLE
47 {
48 PLSA_CREATE_LOGON_SESSION CreateLogonSession;
49 PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
50 PVOID /*PLSA_ADD_CREDENTIAL */ AddCredential;
51 PVOID /*PLSA_GET_CREDENTIALS */ GetCredentials;
52 PVOID /*PLSA_DELETE_CREDENTIAL */ DeleteCredential;
53 PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
54 PLSA_FREE_LSA_HEAP FreeLsaHeap;
55 PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
56 PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
57 PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;
58 PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
59 } LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;
60
61
62 typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PLSA_DISPATCH_TABLE,
63 PLSA_STRING, PLSA_STRING, PLSA_STRING *);
64 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_INTERNAL)(PLSA_CLIENT_REQUEST, PVOID, PVOID,
65 ULONG, PVOID *, PULONG, PNTSTATUS);
66 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_PASSTHROUGH)(PLSA_CLIENT_REQUEST,
67 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
68 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_UNTRUSTED)(PLSA_CLIENT_REQUEST,
69 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
70 typedef VOID (NTAPI *PLSA_AP_LOGON_TERMINATED)(PLUID);
71 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX2)(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 *, PVOID /*PSECPKG_PRIMARY_CRED*/, PVOID /*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/);
75 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX)(PLSA_CLIENT_REQUEST,
76 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
77 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
78 PUNICODE_STRING *);
79
80 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_INTERNAL)(PLSA_CLIENT_REQUEST, SECURITY_LOGON_TYPE,
81 PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, PLSA_TOKEN_INFORMATION_TYPE,
82 PVOID *, PUNICODE_STRING *, PUNICODE_STRING *);
83
84 typedef struct _AUTH_PACKAGE
85 {
86 LIST_ENTRY Entry;
87 PSTRING Name;
88 ULONG Id;
89 PVOID ModuleHandle;
90
91 PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage;
92 PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage;
93 PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough;
94 PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted;
95 PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated;
96 PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2;
97 PLSA_AP_LOGON_USER_EX LsaApLogonUserEx;
98 PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser;
99 } AUTH_PACKAGE, *PAUTH_PACKAGE;
100
101 VOID
102 NTAPI
103 LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr);
104
105 typedef wchar_t *PSAMPR_SERVER_NAME;
106 typedef void *SAMPR_HANDLE;
107
108 typedef struct _SAMPR_ULONG_ARRAY
109 {
110 unsigned long Count;
111 unsigned long *Element;
112 } SAMPR_ULONG_ARRAY, *PSAMPR_ULONG_ARRAY;
113
114 typedef struct _SAMPR_SID_INFORMATION
115 {
116 PRPC_SID SidPointer;
117 } SAMPR_SID_INFORMATION, *PSAMPR_SID_INFORMATION;
118
119 typedef struct _SAMPR_PSID_ARRAY
120 {
121 unsigned long Count;
122 PSAMPR_SID_INFORMATION Sids;
123 } SAMPR_PSID_ARRAY, *PSAMPR_PSID_ARRAY;
124
125 NTSTATUS
126 NTAPI
127 SamIConnect(
128 PSAMPR_SERVER_NAME ServerName,
129 SAMPR_HANDLE *ServerHandle,
130 ACCESS_MASK DesiredAccess,
131 BOOLEAN Trusted);
132
133 VOID
134 NTAPI
135 SamIFree_SAMPR_ULONG_ARRAY(
136 PSAMPR_ULONG_ARRAY Ptr);
137
138 NTSTATUS
139 __stdcall
140 SamrCloseHandle(
141 SAMPR_HANDLE *SamHandle);
142
143 NTSTATUS
144 __stdcall
145 SamrOpenDomain(
146 SAMPR_HANDLE ServerHandle,
147 ACCESS_MASK DesiredAccess,
148 PRPC_SID DomainId,
149 SAMPR_HANDLE *DomainHandle);
150
151 NTSTATUS
152 __stdcall
153 SamrGetAliasMembership(
154 SAMPR_HANDLE DomainHandle,
155 PSAMPR_PSID_ARRAY SidArray,
156 PSAMPR_ULONG_ARRAY Membership);
157
158
159 /* GLOBALS *****************************************************************/
160
161 static LIST_ENTRY PackageListHead;
162 static ULONG PackageId;
163 static LSA_DISPATCH_TABLE DispatchTable;
164
165 #define CONST_LUID(x1, x2) {x1, x2}
166 static const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0);
167 static const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0);
168 static const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0);
169
170
171 /* FUNCTIONS ***************************************************************/
172
173 static
174 NTSTATUS
175 NTAPI
176 LsapAddAuthPackage(IN PWSTR ValueName,
177 IN ULONG ValueType,
178 IN PVOID ValueData,
179 IN ULONG ValueLength,
180 IN PVOID Context,
181 IN PVOID EntryContext)
182 {
183 PAUTH_PACKAGE Package = NULL;
184 UNICODE_STRING PackageName;
185 STRING ProcName;
186 PULONG Id;
187 NTSTATUS Status = STATUS_SUCCESS;
188
189 TRACE("LsapAddAuthPackage()\n");
190
191 PackageName.Length = (USHORT)ValueLength - sizeof(WCHAR);
192 PackageName.MaximumLength = (USHORT)ValueLength;
193 PackageName.Buffer = ValueData;
194
195 Id = (PULONG)Context;
196
197 Package = RtlAllocateHeap(RtlGetProcessHeap(),
198 HEAP_ZERO_MEMORY,
199 sizeof(AUTH_PACKAGE));
200 if (Package == NULL)
201 return STATUS_INSUFFICIENT_RESOURCES;
202
203 Status = LdrLoadDll(NULL,
204 NULL,
205 &PackageName,
206 &Package->ModuleHandle);
207 if (!NT_SUCCESS(Status))
208 {
209 TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status);
210 goto done;
211 }
212
213 RtlInitAnsiString(&ProcName, "LsaApInitializePackage");
214 Status = LdrGetProcedureAddress(Package->ModuleHandle,
215 &ProcName,
216 0,
217 (PVOID *)&Package->LsaApInitializePackage);
218 if (!NT_SUCCESS(Status))
219 {
220 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
221 goto done;
222 }
223
224 RtlInitAnsiString(&ProcName, "LsaApCallPackage");
225 Status = LdrGetProcedureAddress(Package->ModuleHandle,
226 &ProcName,
227 0,
228 (PVOID *)&Package->LsaApCallPackage);
229 if (!NT_SUCCESS(Status))
230 {
231 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
232 goto done;
233 }
234
235 RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough");
236 Status = LdrGetProcedureAddress(Package->ModuleHandle,
237 &ProcName,
238 0,
239 (PVOID *)&Package->LsaApCallPackagePassthrough);
240 if (!NT_SUCCESS(Status))
241 {
242 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
243 goto done;
244 }
245
246 RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted");
247 Status = LdrGetProcedureAddress(Package->ModuleHandle,
248 &ProcName,
249 0,
250 (PVOID *)&Package->LsaApCallPackageUntrusted);
251 if (!NT_SUCCESS(Status))
252 {
253 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
254 goto done;
255 }
256
257 RtlInitAnsiString(&ProcName, "LsaApLogonTerminated");
258 Status = LdrGetProcedureAddress(Package->ModuleHandle,
259 &ProcName,
260 0,
261 (PVOID *)&Package->LsaApLogonTerminated);
262 if (!NT_SUCCESS(Status))
263 {
264 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
265 goto done;
266 }
267
268 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2");
269 Status = LdrGetProcedureAddress(Package->ModuleHandle,
270 &ProcName,
271 0,
272 (PVOID *)&Package->LsaApLogonUserEx2);
273 if (!NT_SUCCESS(Status))
274 {
275 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx");
276 Status = LdrGetProcedureAddress(Package->ModuleHandle,
277 &ProcName,
278 0,
279 (PVOID *)&Package->LsaApLogonUserEx);
280 if (!NT_SUCCESS(Status))
281 {
282 RtlInitAnsiString(&ProcName, "LsaApLogonUser");
283 Status = LdrGetProcedureAddress(Package->ModuleHandle,
284 &ProcName,
285 0,
286 (PVOID *)&Package->LsaApLogonUser);
287 if (!NT_SUCCESS(Status))
288 {
289 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
290 goto done;
291 }
292 }
293 }
294
295 /* Initialize the current package */
296 Status = Package->LsaApInitializePackage(*Id,
297 &DispatchTable,
298 NULL,
299 NULL,
300 &Package->Name);
301 if (!NT_SUCCESS(Status))
302 {
303 TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status);
304 goto done;
305 }
306
307 TRACE("Package Name: %s\n", Package->Name->Buffer);
308
309 Package->Id = *Id;
310 (*Id)++;
311
312 InsertTailList(&PackageListHead, &Package->Entry);
313
314 done:
315 if (!NT_SUCCESS(Status))
316 {
317 if (Package != NULL)
318 {
319 if (Package->ModuleHandle != NULL)
320 LdrUnloadDll(Package->ModuleHandle);
321
322 if (Package->Name != NULL)
323 {
324 if (Package->Name->Buffer != NULL)
325 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer);
326
327 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name);
328 }
329
330 RtlFreeHeap(RtlGetProcessHeap(), 0, Package);
331 }
332 }
333
334 return Status;
335 }
336
337
338 static
339 PAUTH_PACKAGE
340 LsapGetAuthenticationPackage(IN ULONG PackageId)
341 {
342 PLIST_ENTRY ListEntry;
343 PAUTH_PACKAGE Package;
344
345 ListEntry = PackageListHead.Flink;
346 while (ListEntry != &PackageListHead)
347 {
348 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
349
350 if (Package->Id == PackageId)
351 {
352 return Package;
353 }
354
355 ListEntry = ListEntry->Flink;
356 }
357
358 return NULL;
359 }
360
361
362 static
363 PVOID
364 NTAPI
365 LsapAllocateHeap(IN ULONG Length)
366 {
367 return RtlAllocateHeap(RtlGetProcessHeap(),
368 HEAP_ZERO_MEMORY,
369 Length);
370 }
371
372
373 static
374 VOID
375 NTAPI
376 LsapFreeHeap(IN PVOID Base)
377 {
378 RtlFreeHeap(RtlGetProcessHeap(),
379 0,
380 Base);
381 }
382
383
384 static
385 NTSTATUS
386 NTAPI
387 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
388 IN ULONG LengthRequired,
389 OUT PVOID *ClientBaseAddress)
390 {
391 PLSAP_LOGON_CONTEXT LogonContext;
392 ULONG Length;
393
394 *ClientBaseAddress = NULL;
395
396 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
397
398 Length = LengthRequired;
399 return NtAllocateVirtualMemory(LogonContext->ClientProcessHandle,
400 ClientBaseAddress,
401 0,
402 &Length,
403 MEM_COMMIT,
404 PAGE_READWRITE);
405 }
406
407
408 static
409 NTSTATUS
410 NTAPI
411 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
412 IN PVOID ClientBaseAddress)
413 {
414 PLSAP_LOGON_CONTEXT LogonContext;
415 ULONG Length;
416
417 if (ClientBaseAddress == NULL)
418 return STATUS_SUCCESS;
419
420 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
421
422 Length = 0;
423 return NtFreeVirtualMemory(LogonContext->ClientProcessHandle,
424 &ClientBaseAddress,
425 &Length,
426 MEM_RELEASE);
427 }
428
429
430 static
431 NTSTATUS
432 NTAPI
433 LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
434 IN ULONG Length,
435 IN PVOID ClientBaseAddress,
436 IN PVOID BufferToCopy)
437 {
438 PLSAP_LOGON_CONTEXT LogonContext;
439
440 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
441
442 return NtWriteVirtualMemory(LogonContext->ClientProcessHandle,
443 ClientBaseAddress,
444 BufferToCopy,
445 Length,
446 NULL);
447 }
448
449
450 static
451 NTSTATUS
452 NTAPI
453 LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
454 IN ULONG Length,
455 IN PVOID BufferToCopy,
456 IN PVOID ClientBaseAddress)
457 {
458 PLSAP_LOGON_CONTEXT LogonContext;
459
460 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
461
462 return NtReadVirtualMemory(LogonContext->ClientProcessHandle,
463 ClientBaseAddress,
464 BufferToCopy,
465 Length,
466 NULL);
467 }
468
469
470 NTSTATUS
471 LsapInitAuthPackages(VOID)
472 {
473 RTL_QUERY_REGISTRY_TABLE AuthPackageTable[] = {
474 {LsapAddAuthPackage, 0, L"Authentication Packages", NULL, REG_NONE, NULL, 0},
475 {NULL, 0, NULL, NULL, REG_NONE, NULL, 0}};
476
477 NTSTATUS Status;
478
479 InitializeListHead(&PackageListHead);
480 PackageId = 0;
481
482 /* Initialize the dispatch table */
483 DispatchTable.CreateLogonSession = &LsapCreateLogonSession;
484 DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession;
485 DispatchTable.AddCredential = NULL;
486 DispatchTable.GetCredentials = NULL;
487 DispatchTable.DeleteCredential = NULL;
488 DispatchTable.AllocateLsaHeap = &LsapAllocateHeap;
489 DispatchTable.FreeLsaHeap = &LsapFreeHeap;
490 DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
491 DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
492 DispatchTable.CopyToClientBuffer = &LsapCopyToClientBuffer;
493 DispatchTable.CopyFromClientBuffer = &LsapCopyFromClientBuffer;
494
495 /* Add registered authentication packages */
496 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
497 L"Lsa",
498 AuthPackageTable,
499 &PackageId,
500 NULL);
501
502 return Status;
503 }
504
505
506 NTSTATUS
507 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg,
508 PLSAP_LOGON_CONTEXT LogonContext)
509 {
510 PLIST_ENTRY ListEntry;
511 PAUTH_PACKAGE Package;
512 ULONG PackageNameLength;
513 PCHAR PackageName;
514
515 TRACE("(%p %p)\n", RequestMsg, LogonContext);
516
517 PackageNameLength = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength;
518 PackageName = RequestMsg->LookupAuthenticationPackage.Request.PackageName;
519
520 TRACE("PackageName: %s\n", PackageName);
521
522 ListEntry = PackageListHead.Flink;
523 while (ListEntry != &PackageListHead)
524 {
525 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
526
527 if ((PackageNameLength == Package->Name->Length) &&
528 (_strnicmp(PackageName, Package->Name->Buffer, Package->Name->Length) == 0))
529 {
530 RequestMsg->LookupAuthenticationPackage.Reply.Package = Package->Id;
531 return STATUS_SUCCESS;
532 }
533
534 ListEntry = ListEntry->Flink;
535 }
536
537 return STATUS_NO_SUCH_PACKAGE;
538 }
539
540
541 NTSTATUS
542 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
543 PLSAP_LOGON_CONTEXT LogonContext)
544 {
545 PAUTH_PACKAGE Package;
546 PVOID LocalBuffer = NULL;
547 ULONG PackageId;
548 NTSTATUS Status;
549
550 TRACE("(%p %p)\n", RequestMsg, LogonContext);
551
552 PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
553
554 /* Get the right authentication package */
555 Package = LsapGetAuthenticationPackage(PackageId);
556 if (Package == NULL)
557 {
558 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
559 return STATUS_NO_SUCH_PACKAGE;
560 }
561
562 if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0)
563 {
564 LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
565 HEAP_ZERO_MEMORY,
566 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength);
567 if (LocalBuffer == NULL)
568 {
569 return STATUS_INSUFFICIENT_RESOURCES;
570 }
571
572 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
573 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
574 LocalBuffer,
575 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
576 NULL);
577 if (!NT_SUCCESS(Status))
578 {
579 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
580 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
581 return Status;
582 }
583 }
584
585 Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext,
586 LocalBuffer,
587 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
588 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
589 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
590 &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
591 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
592 if (!NT_SUCCESS(Status))
593 {
594 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
595 }
596
597 if (LocalBuffer != NULL)
598 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
599
600 return Status;
601 }
602
603
604 static
605 NTSTATUS
606 LsapCopyLocalGroups(
607 IN PLSAP_LOGON_CONTEXT LogonContext,
608 IN PTOKEN_GROUPS ClientGroups,
609 IN ULONG ClientGroupsCount,
610 OUT PTOKEN_GROUPS *TokenGroups)
611 {
612 ULONG LocalGroupsLength = 0;
613 PTOKEN_GROUPS LocalGroups = NULL;
614 ULONG SidHeaderLength = 0;
615 PSID SidHeader = NULL;
616 PSID SrcSid, DstSid;
617 ULONG SidLength;
618 ULONG AllocatedSids = 0;
619 ULONG i;
620 NTSTATUS Status;
621
622 LocalGroupsLength = sizeof(TOKEN_GROUPS) +
623 (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
624 LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
625 HEAP_ZERO_MEMORY,
626 LocalGroupsLength);
627 if (LocalGroups == NULL)
628 {
629 TRACE("RtlAllocateHeap() failed\n");
630 return STATUS_INSUFFICIENT_RESOURCES;
631 }
632
633 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
634 ClientGroups,
635 LocalGroups,
636 LocalGroupsLength,
637 NULL);
638 if (!NT_SUCCESS(Status))
639 goto done;
640
641
642 SidHeaderLength = RtlLengthRequiredSid(0);
643 SidHeader = RtlAllocateHeap(RtlGetProcessHeap(),
644 HEAP_ZERO_MEMORY,
645 SidHeaderLength);
646 if (SidHeader == NULL)
647 {
648 Status = STATUS_INSUFFICIENT_RESOURCES;
649 goto done;
650 }
651
652 for (i = 0; i < ClientGroupsCount; i++)
653 {
654 SrcSid = LocalGroups->Groups[i].Sid;
655
656 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
657 SrcSid,
658 SidHeader,
659 SidHeaderLength,
660 NULL);
661 if (!NT_SUCCESS(Status))
662 goto done;
663
664 SidLength = RtlLengthSid(SidHeader);
665 TRACE("Sid %lu: Length %lu\n", i, SidLength);
666
667 DstSid = RtlAllocateHeap(RtlGetProcessHeap(),
668 HEAP_ZERO_MEMORY,
669 SidLength);
670 if (DstSid == NULL)
671 {
672 Status = STATUS_INSUFFICIENT_RESOURCES;
673 goto done;
674 }
675
676 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
677 SrcSid,
678 DstSid,
679 SidLength,
680 NULL);
681 if (!NT_SUCCESS(Status))
682 {
683 RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid);
684 goto done;
685 }
686
687 LocalGroups->Groups[i].Sid = DstSid;
688 AllocatedSids++;
689 }
690
691 *TokenGroups = LocalGroups;
692
693 done:
694 if (SidHeader != NULL)
695 RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
696
697 if (!NT_SUCCESS(Status))
698 {
699 if (LocalGroups != NULL)
700 {
701 for (i = 0; i < AllocatedSids; i++)
702 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
703
704 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
705 }
706 }
707
708 return Status;
709 }
710
711
712 static
713 NTSTATUS
714 LsapAddLocalGroups(
715 IN PVOID TokenInformation,
716 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
717 IN PTOKEN_GROUPS LocalGroups)
718 {
719 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
720 PTOKEN_GROUPS Groups;
721 ULONG Length;
722 ULONG i;
723 ULONG j;
724
725 if (LocalGroups == NULL || LocalGroups->GroupCount == 0)
726 return STATUS_SUCCESS;
727
728 if (TokenInformationType == LsaTokenInformationV1)
729 {
730 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
731
732 if (TokenInfo1->Groups != NULL)
733 {
734 Length = sizeof(TOKEN_GROUPS) +
735 (LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
736
737 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
738 if (Groups == NULL)
739 {
740 ERR("Group buffer allocation failed!\n");
741 return STATUS_INSUFFICIENT_RESOURCES;
742 }
743
744 Groups->GroupCount = LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount;
745
746 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
747 {
748 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
749 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
750 }
751
752 for (j = 0; j < LocalGroups->GroupCount; i++, j++)
753 {
754 Groups->Groups[i].Sid = LocalGroups->Groups[j].Sid;
755 Groups->Groups[i].Attributes = LocalGroups->Groups[j].Attributes;
756 LocalGroups->Groups[j].Sid = NULL;
757 }
758
759 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
760
761 TokenInfo1->Groups = Groups;
762 }
763 else
764 {
765 Length = sizeof(TOKEN_GROUPS) +
766 (LocalGroups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
767
768 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
769 if (Groups == NULL)
770 {
771 ERR("Group buffer allocation failed!\n");
772 return STATUS_INSUFFICIENT_RESOURCES;
773 }
774
775 Groups->GroupCount = LocalGroups->GroupCount;
776
777 for (i = 0; i < LocalGroups->GroupCount; i++)
778 {
779 Groups->Groups[i].Sid = LocalGroups->Groups[i].Sid;
780 Groups->Groups[i].Attributes = LocalGroups->Groups[i].Attributes;
781 }
782
783 TokenInfo1->Groups = Groups;
784 }
785 }
786 else
787 {
788 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
789 return STATUS_NOT_IMPLEMENTED;
790 }
791
792 return STATUS_SUCCESS;
793 }
794
795 static
796 NTSTATUS
797 LsapAddDefaultGroups(
798 IN PVOID TokenInformation,
799 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
800 IN SECURITY_LOGON_TYPE LogonType)
801 {
802 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
803 PTOKEN_GROUPS Groups;
804 ULONG i, Length;
805 PSID SrcSid;
806
807 if (TokenInformationType == LsaTokenInformationV1)
808 {
809 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
810
811 if (TokenInfo1->Groups != NULL)
812 {
813 Length = sizeof(TOKEN_GROUPS) +
814 (TokenInfo1->Groups->GroupCount + 2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
815
816 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
817 if (Groups == NULL)
818 {
819 ERR("Group buffer allocation failed!\n");
820 return STATUS_INSUFFICIENT_RESOURCES;
821 }
822
823 Groups->GroupCount = TokenInfo1->Groups->GroupCount;
824
825 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
826 {
827 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid;
828 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes;
829 }
830
831 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups);
832
833 TokenInfo1->Groups = Groups;
834
835 }
836 else
837 {
838 Length = sizeof(TOKEN_GROUPS) +
839 (2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
840
841 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
842 if (Groups == NULL)
843 {
844 ERR("Group buffer allocation failed!\n");
845 return STATUS_INSUFFICIENT_RESOURCES;
846 }
847
848 TokenInfo1->Groups = Groups;
849 }
850
851 /* Append the World SID (aka Everyone) */
852 Length = RtlLengthSid(LsapWorldSid);
853 Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
854 HEAP_ZERO_MEMORY,
855 Length);
856 if (Groups->Groups[Groups->GroupCount].Sid == NULL)
857 return STATUS_INSUFFICIENT_RESOURCES;
858
859 RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
860 LsapWorldSid,
861 Length);
862
863 Groups->Groups[Groups->GroupCount].Attributes =
864 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
865
866 Groups->GroupCount++;
867
868 /* Append the logon type SID */
869 switch (LogonType)
870 {
871 case Interactive:
872 SrcSid = LsapInteractiveSid;
873 break;
874
875 case Network:
876 SrcSid = LsapNetworkSid;
877 break;
878
879 case Batch:
880 SrcSid = LsapBatchSid;
881 break;
882
883 case Service:
884 SrcSid = LsapServiceSid;
885 break;
886
887 default:
888 FIXME("LogonType %d is not supported!\n", LogonType);
889 return STATUS_NOT_IMPLEMENTED;
890 }
891
892 Length = RtlLengthSid(SrcSid);
893 Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(),
894 HEAP_ZERO_MEMORY,
895 Length);
896 if (Groups->Groups[Groups->GroupCount].Sid == NULL)
897 return STATUS_INSUFFICIENT_RESOURCES;
898
899 RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid,
900 SrcSid,
901 Length);
902
903 Groups->Groups[Groups->GroupCount].Attributes =
904 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
905
906 Groups->GroupCount++;
907 }
908 else
909 {
910 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
911 return STATUS_NOT_IMPLEMENTED;
912 }
913
914 return STATUS_SUCCESS;
915 }
916
917
918 static
919 NTSTATUS
920 LsapAppendSidToGroups(
921 IN PTOKEN_GROUPS *TokenGroups,
922 IN PSID DomainSid,
923 IN ULONG RelativeId)
924 {
925 PTOKEN_GROUPS Groups;
926 PSID Sid;
927 ULONG Length;
928 ULONG i;
929
930 Sid = LsapAppendRidToSid(DomainSid, RelativeId);
931 if (Sid == NULL)
932 {
933 ERR("Group SID creation failed!\n");
934 return STATUS_INSUFFICIENT_RESOURCES;
935 }
936
937 if (*TokenGroups == NULL)
938 {
939 Length = sizeof(TOKEN_GROUPS) +
940 (1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
941
942 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
943 if (Groups == NULL)
944 {
945 ERR("Group buffer allocation failed!\n");
946 return STATUS_INSUFFICIENT_RESOURCES;
947 }
948
949 Groups->GroupCount = 1;
950
951 Groups->Groups[0].Sid = Sid;
952 Groups->Groups[0].Attributes =
953 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
954
955 *TokenGroups = Groups;
956 }
957 else
958 {
959 for (i = 0; i < (*TokenGroups)->GroupCount; i++)
960 {
961 if (RtlEqualSid((*TokenGroups)->Groups[i].Sid, Sid))
962 {
963 RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
964 return STATUS_SUCCESS;
965 }
966 }
967
968 Length = sizeof(TOKEN_GROUPS) +
969 ((*TokenGroups)->GroupCount + 1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
970
971 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
972 if (Groups == NULL)
973 {
974 ERR("Group buffer allocation failed!\n");
975 return STATUS_INSUFFICIENT_RESOURCES;
976 }
977
978 Groups->GroupCount = (*TokenGroups)->GroupCount;
979
980 for (i = 0; i < (*TokenGroups)->GroupCount; i++)
981 {
982 Groups->Groups[i].Sid = (*TokenGroups)->Groups[i].Sid;
983 Groups->Groups[i].Attributes = (*TokenGroups)->Groups[i].Attributes;
984 }
985
986 Groups->Groups[Groups->GroupCount].Sid = Sid;
987 Groups->Groups[Groups->GroupCount].Attributes =
988 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
989
990 Groups->GroupCount++;
991
992 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenGroups);
993
994 *TokenGroups = Groups;
995 }
996
997 return STATUS_SUCCESS;
998 }
999
1000
1001 static
1002 NTSTATUS
1003 LsapAddSamGroups(
1004 IN PVOID TokenInformation,
1005 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1006 {
1007 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1008 SAMPR_HANDLE ServerHandle = NULL;
1009 SAMPR_HANDLE BuiltinDomainHandle = NULL;
1010 SAMPR_HANDLE AccountDomainHandle = NULL;
1011 SAMPR_PSID_ARRAY SidArray;
1012 SAMPR_ULONG_ARRAY BuiltinMembership;
1013 SAMPR_ULONG_ARRAY AccountMembership;
1014 ULONG i;
1015 NTSTATUS Status = STATUS_SUCCESS;
1016
1017 if (TokenInformationType != LsaTokenInformationV1)
1018 return STATUS_SUCCESS;
1019
1020 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1021
1022 SidArray.Count = TokenInfo1->Groups->GroupCount + 1;
1023 SidArray.Sids = RtlAllocateHeap(RtlGetProcessHeap(),
1024 HEAP_ZERO_MEMORY,
1025 (TokenInfo1->Groups->GroupCount + 1) * sizeof(PRPC_SID));
1026 if (SidArray.Sids == NULL)
1027 return STATUS_INSUFFICIENT_RESOURCES;
1028
1029 SidArray.Sids[0].SidPointer = TokenInfo1->User.User.Sid;
1030 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1031 SidArray.Sids[i + 1].SidPointer = TokenInfo1->Groups->Groups[i].Sid;
1032
1033 Status = SamIConnect(NULL,
1034 &ServerHandle,
1035 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1036 FALSE);
1037 if (!NT_SUCCESS(Status))
1038 {
1039 TRACE("SamIConnect failed (Status %08lx)\n", Status);
1040 goto done;
1041 }
1042
1043 Status = SamrOpenDomain(ServerHandle,
1044 DOMAIN_GET_ALIAS_MEMBERSHIP,
1045 BuiltinDomainSid,
1046 &BuiltinDomainHandle);
1047 if (!NT_SUCCESS(Status))
1048 {
1049 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1050 goto done;
1051 }
1052
1053 Status = SamrOpenDomain(ServerHandle,
1054 DOMAIN_GET_ALIAS_MEMBERSHIP,
1055 AccountDomainSid,
1056 &AccountDomainHandle);
1057 if (!NT_SUCCESS(Status))
1058 {
1059 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1060 goto done;
1061 }
1062
1063 BuiltinMembership.Element = NULL;
1064 Status = SamrGetAliasMembership(BuiltinDomainHandle,
1065 &SidArray,
1066 &BuiltinMembership);
1067 if (!NT_SUCCESS(Status))
1068 {
1069 TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
1070 goto done;
1071 }
1072
1073 AccountMembership.Element = NULL;
1074 Status = SamrGetAliasMembership(AccountDomainHandle,
1075 &SidArray,
1076 &AccountMembership);
1077 if (!NT_SUCCESS(Status))
1078 {
1079 TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
1080 goto done;
1081 }
1082
1083 TRACE("Builtin Memberships: %lu\n", BuiltinMembership.Count);
1084 for (i = 0; i < BuiltinMembership.Count; i++)
1085 {
1086 TRACE("RID %lu: %lu (0x%lx)\n", i, BuiltinMembership.Element[i], BuiltinMembership.Element[i]);
1087 Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
1088 BuiltinDomainSid,
1089 BuiltinMembership.Element[i]);
1090 if (!NT_SUCCESS(Status))
1091 {
1092 TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
1093 goto done;
1094 }
1095 }
1096
1097 TRACE("Account Memberships: %lu\n", AccountMembership.Count);
1098 for (i = 0; i < AccountMembership.Count; i++)
1099 {
1100 TRACE("RID %lu: %lu (0x%lx)\n", i, AccountMembership.Element[i], AccountMembership.Element[i]);
1101 Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
1102 AccountDomainSid,
1103 AccountMembership.Element[i]);
1104 if (!NT_SUCCESS(Status))
1105 {
1106 TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
1107 goto done;
1108 }
1109 }
1110
1111 done:
1112 RtlFreeHeap(RtlGetProcessHeap(), 0, SidArray.Sids);
1113
1114 if (AccountMembership.Element != NULL)
1115 SamIFree_SAMPR_ULONG_ARRAY(&AccountMembership);
1116
1117 if (BuiltinMembership.Element != NULL)
1118 SamIFree_SAMPR_ULONG_ARRAY(&BuiltinMembership);
1119
1120 if (AccountDomainHandle != NULL)
1121 SamrCloseHandle(&AccountDomainHandle);
1122
1123 if (BuiltinDomainHandle != NULL)
1124 SamrCloseHandle(&BuiltinDomainHandle);
1125
1126 if (ServerHandle != NULL)
1127 SamrCloseHandle(&ServerHandle);
1128
1129 // return Status;
1130
1131 return STATUS_SUCCESS;
1132 }
1133
1134
1135 static
1136 NTSTATUS
1137 LsapSetTokenOwner(
1138 IN PVOID TokenInformation,
1139 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1140 {
1141 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1142 PSID OwnerSid = NULL;
1143 ULONG i, Length;
1144
1145 if (TokenInformationType == LsaTokenInformationV1)
1146 {
1147 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1148
1149 if (TokenInfo1->Owner.Owner != NULL)
1150 return STATUS_SUCCESS;
1151
1152 OwnerSid = TokenInfo1->User.User.Sid;
1153 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1154 {
1155 if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
1156 {
1157 OwnerSid = LsapAdministratorsSid;
1158 break;
1159 }
1160 }
1161
1162 Length = RtlLengthSid(OwnerSid);
1163 TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length);
1164 if (TokenInfo1->Owner.Owner == NULL)
1165 return STATUS_INSUFFICIENT_RESOURCES;
1166
1167 RtlCopyMemory(TokenInfo1->Owner.Owner,
1168 OwnerSid,
1169 Length);
1170 }
1171
1172 return STATUS_SUCCESS;
1173 }
1174
1175
1176 static
1177 NTSTATUS
1178 LsapAddTokenDefaultDacl(
1179 IN PVOID TokenInformation,
1180 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1181 {
1182 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1183 PACL Dacl = NULL;
1184 ULONG Length;
1185
1186 if (TokenInformationType == LsaTokenInformationV1)
1187 {
1188 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1189
1190 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1191 return STATUS_SUCCESS;
1192
1193 Length = sizeof(ACL) +
1194 (2 * sizeof(ACCESS_ALLOWED_ACE)) +
1195 RtlLengthSid(TokenInfo1->Owner.Owner) +
1196 RtlLengthSid(LsapLocalSystemSid);
1197
1198 Dacl = DispatchTable.AllocateLsaHeap(Length);
1199 if (Dacl == NULL)
1200 return STATUS_INSUFFICIENT_RESOURCES;
1201
1202 RtlCreateAcl(Dacl, Length, ACL_REVISION);
1203
1204 RtlAddAccessAllowedAce(Dacl,
1205 ACL_REVISION,
1206 GENERIC_ALL,
1207 TokenInfo1->Owner.Owner);
1208
1209 /* SID: S-1-5-18 */
1210 RtlAddAccessAllowedAce(Dacl,
1211 ACL_REVISION,
1212 GENERIC_ALL,
1213 LsapLocalSystemSid);
1214
1215 TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
1216 }
1217
1218 return STATUS_SUCCESS;
1219 }
1220
1221
1222 static
1223 NTSTATUS
1224 LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
1225 PLSAPR_LUID_AND_ATTRIBUTES Privilege)
1226 {
1227 PTOKEN_PRIVILEGES LocalPrivileges;
1228 ULONG Length, TokenPrivilegeCount, i;
1229 NTSTATUS Status = STATUS_SUCCESS;
1230
1231 if (*TokenPrivileges == NULL)
1232 {
1233 Length = sizeof(TOKEN_PRIVILEGES) +
1234 (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1235 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1236 0,
1237 Length);
1238 if (LocalPrivileges == NULL)
1239 return STATUS_INSUFFICIENT_RESOURCES;
1240
1241 LocalPrivileges->PrivilegeCount = 1;
1242 LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
1243 LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
1244 }
1245 else
1246 {
1247 TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
1248
1249 for (i = 0; i < TokenPrivilegeCount; i++)
1250 {
1251 if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
1252 return STATUS_SUCCESS;
1253 }
1254
1255 Length = sizeof(TOKEN_PRIVILEGES) +
1256 (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1257 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1258 0,
1259 Length);
1260 if (LocalPrivileges == NULL)
1261 return STATUS_INSUFFICIENT_RESOURCES;
1262
1263 LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
1264 for (i = 0; i < TokenPrivilegeCount; i++)
1265 {
1266 LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
1267 LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
1268 }
1269
1270 LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
1271 LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
1272
1273 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
1274 }
1275
1276 *TokenPrivileges = LocalPrivileges;
1277
1278 return Status;
1279 }
1280
1281 static
1282 NTSTATUS
1283 LsapSetPrivileges(
1284 IN PVOID TokenInformation,
1285 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1286 {
1287 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1288 LSAPR_HANDLE PolicyHandle = NULL;
1289 LSAPR_HANDLE AccountHandle = NULL;
1290 PLSAPR_PRIVILEGE_SET Privileges = NULL;
1291 ULONG i, j;
1292 NTSTATUS Status;
1293
1294 if (TokenInformationType == LsaTokenInformationV1)
1295 {
1296 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1297
1298 Status = LsarOpenPolicy(NULL,
1299 NULL,
1300 0,
1301 &PolicyHandle);
1302 if (!NT_SUCCESS(Status))
1303 return Status;
1304
1305 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1306 {
1307 Status = LsarOpenAccount(PolicyHandle,
1308 TokenInfo1->Groups->Groups[i].Sid,
1309 ACCOUNT_VIEW,
1310 &AccountHandle);
1311 if (!NT_SUCCESS(Status))
1312 continue;
1313
1314 Status = LsarEnumeratePrivilegesAccount(AccountHandle,
1315 &Privileges);
1316 if (NT_SUCCESS(Status))
1317 {
1318 for (j = 0; j < Privileges->PrivilegeCount; j++)
1319 {
1320 Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
1321 &(Privileges->Privilege[j]));
1322 if (!NT_SUCCESS(Status))
1323 {
1324 /* We failed, clean everything and return */
1325 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1326 LsarClose(&AccountHandle);
1327 LsarClose(&PolicyHandle);
1328
1329 return Status;
1330 }
1331 }
1332
1333 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1334 Privileges = NULL;
1335 }
1336
1337 LsarClose(&AccountHandle);
1338 }
1339
1340 LsarClose(&PolicyHandle);
1341
1342 if (TokenInfo1->Privileges != NULL)
1343 {
1344 for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
1345 {
1346 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
1347 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
1348 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
1349 {
1350 TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
1351 }
1352 }
1353 }
1354 }
1355
1356 return STATUS_SUCCESS;
1357 }
1358
1359
1360 NTSTATUS
1361 LsapLogonUser(PLSA_API_MSG RequestMsg,
1362 PLSAP_LOGON_CONTEXT LogonContext)
1363 {
1364 PAUTH_PACKAGE Package;
1365 OBJECT_ATTRIBUTES ObjectAttributes;
1366 SECURITY_QUALITY_OF_SERVICE Qos;
1367 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
1368 PVOID TokenInformation = NULL;
1369 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
1370 PUNICODE_STRING AccountName = NULL;
1371 PUNICODE_STRING AuthenticatingAuthority = NULL;
1372 PUNICODE_STRING MachineName = NULL;
1373 PVOID LocalAuthInfo = NULL;
1374 PTOKEN_GROUPS LocalGroups = NULL;
1375 HANDLE TokenHandle = NULL;
1376 ULONG i;
1377 ULONG PackageId;
1378 SECURITY_LOGON_TYPE LogonType;
1379 NTSTATUS Status;
1380
1381 TRACE("(%p %p)\n", RequestMsg, LogonContext);
1382
1383 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
1384 LogonType = RequestMsg->LogonUser.Request.LogonType;
1385
1386 /* Get the right authentication package */
1387 Package = LsapGetAuthenticationPackage(PackageId);
1388 if (Package == NULL)
1389 {
1390 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
1391 return STATUS_NO_SUCH_PACKAGE;
1392 }
1393
1394 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
1395 {
1396 /* Allocate the local authentication info buffer */
1397 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1398 HEAP_ZERO_MEMORY,
1399 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
1400 if (LocalAuthInfo == NULL)
1401 {
1402 ERR("RtlAllocateHeap() failed\n");
1403 return STATUS_INSUFFICIENT_RESOURCES;
1404 }
1405
1406 /* Read the authentication info from the callers adress space */
1407 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
1408 RequestMsg->LogonUser.Request.AuthenticationInformation,
1409 LocalAuthInfo,
1410 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1411 NULL);
1412 if (!NT_SUCCESS(Status))
1413 {
1414 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
1415 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1416 return Status;
1417 }
1418 }
1419
1420 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
1421 {
1422 Status = LsapCopyLocalGroups(LogonContext,
1423 RequestMsg->LogonUser.Request.LocalGroups,
1424 RequestMsg->LogonUser.Request.LocalGroupsCount,
1425 &LocalGroups);
1426 if (!NT_SUCCESS(Status))
1427 {
1428 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
1429 goto done;
1430 }
1431
1432 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
1433 }
1434
1435 if (Package->LsaApLogonUserEx2 != NULL)
1436 {
1437 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
1438 RequestMsg->LogonUser.Request.LogonType,
1439 LocalAuthInfo,
1440 RequestMsg->LogonUser.Request.AuthenticationInformation,
1441 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1442 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1443 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1444 &RequestMsg->LogonUser.Reply.LogonId,
1445 &RequestMsg->LogonUser.Reply.SubStatus,
1446 &TokenInformationType,
1447 &TokenInformation,
1448 &AccountName,
1449 &AuthenticatingAuthority,
1450 &MachineName,
1451 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
1452 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
1453 }
1454 else if (Package->LsaApLogonUserEx != NULL)
1455 {
1456 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
1457 RequestMsg->LogonUser.Request.LogonType,
1458 LocalAuthInfo,
1459 RequestMsg->LogonUser.Request.AuthenticationInformation,
1460 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1461 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1462 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1463 &RequestMsg->LogonUser.Reply.LogonId,
1464 &RequestMsg->LogonUser.Reply.SubStatus,
1465 &TokenInformationType,
1466 &TokenInformation,
1467 &AccountName,
1468 &AuthenticatingAuthority,
1469 &MachineName);
1470 }
1471 else
1472 {
1473 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
1474 RequestMsg->LogonUser.Request.LogonType,
1475 LocalAuthInfo,
1476 RequestMsg->LogonUser.Request.AuthenticationInformation,
1477 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1478 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1479 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1480 &RequestMsg->LogonUser.Reply.LogonId,
1481 &RequestMsg->LogonUser.Reply.SubStatus,
1482 &TokenInformationType,
1483 &TokenInformation,
1484 &AccountName,
1485 &AuthenticatingAuthority);
1486 }
1487
1488 if (!NT_SUCCESS(Status))
1489 {
1490 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
1491 goto done;
1492 }
1493
1494 if (LocalGroups->GroupCount > 0)
1495 {
1496 /* Add local groups to the token information */
1497 Status = LsapAddLocalGroups(TokenInformation,
1498 TokenInformationType,
1499 LocalGroups);
1500 if (!NT_SUCCESS(Status))
1501 {
1502 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status);
1503 goto done;
1504 }
1505 }
1506
1507 Status = LsapAddDefaultGroups(TokenInformation,
1508 TokenInformationType,
1509 LogonType);
1510 if (!NT_SUCCESS(Status))
1511 {
1512 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status);
1513 goto done;
1514 }
1515
1516 Status = LsapAddSamGroups(TokenInformation,
1517 TokenInformationType);
1518 if (!NT_SUCCESS(Status))
1519 {
1520 ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status);
1521 goto done;
1522 }
1523
1524 Status = LsapSetTokenOwner(TokenInformation,
1525 TokenInformationType);
1526 if (!NT_SUCCESS(Status))
1527 {
1528 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
1529 goto done;
1530 }
1531
1532 Status = LsapAddTokenDefaultDacl(TokenInformation,
1533 TokenInformationType);
1534 if (!NT_SUCCESS(Status))
1535 {
1536 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
1537 goto done;
1538 }
1539
1540 Status = LsapSetPrivileges(TokenInformation,
1541 TokenInformationType);
1542 if (!NT_SUCCESS(Status))
1543 {
1544 ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
1545 goto done;
1546 }
1547
1548 if (TokenInformationType == LsaTokenInformationV1)
1549 {
1550 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1551
1552 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1553 Qos.ImpersonationLevel = SecurityImpersonation;
1554 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
1555 Qos.EffectiveOnly = FALSE;
1556
1557 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1558 ObjectAttributes.RootDirectory = NULL;
1559 ObjectAttributes.ObjectName = NULL;
1560 ObjectAttributes.Attributes = 0;
1561 ObjectAttributes.SecurityDescriptor = NULL;
1562 ObjectAttributes.SecurityQualityOfService = &Qos;
1563
1564 /* Create the logon token */
1565 Status = NtCreateToken(&TokenHandle,
1566 TOKEN_ALL_ACCESS,
1567 &ObjectAttributes,
1568 TokenPrimary,
1569 &RequestMsg->LogonUser.Reply.LogonId,
1570 &TokenInfo1->ExpirationTime,
1571 &TokenInfo1->User,
1572 TokenInfo1->Groups,
1573 TokenInfo1->Privileges,
1574 &TokenInfo1->Owner,
1575 &TokenInfo1->PrimaryGroup,
1576 &TokenInfo1->DefaultDacl,
1577 &RequestMsg->LogonUser.Request.SourceContext);
1578 if (!NT_SUCCESS(Status))
1579 {
1580 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
1581 goto done;
1582 }
1583 }
1584 else
1585 {
1586 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1587 Status = STATUS_NOT_IMPLEMENTED;
1588 goto done;
1589 }
1590
1591 /* Duplicate the token handle into the client process */
1592 Status = NtDuplicateObject(NtCurrentProcess(),
1593 TokenHandle,
1594 LogonContext->ClientProcessHandle,
1595 &RequestMsg->LogonUser.Reply.Token,
1596 0,
1597 0,
1598 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
1599 if (!NT_SUCCESS(Status))
1600 {
1601 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
1602 goto done;
1603 }
1604
1605 TokenHandle = NULL;
1606
1607 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
1608 if (!NT_SUCCESS(Status))
1609 {
1610 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
1611 goto done;
1612 }
1613
1614 done:
1615 if (!NT_SUCCESS(Status))
1616 {
1617 if (TokenHandle != NULL)
1618 NtClose(TokenHandle);
1619 }
1620
1621 /* Free the local groups */
1622 if (LocalGroups != NULL)
1623 {
1624 for (i = 0; i < LocalGroups->GroupCount; i++)
1625 {
1626 if (LocalGroups->Groups[i].Sid != NULL)
1627 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
1628 }
1629
1630 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
1631 }
1632
1633 /* Free the local authentication info buffer */
1634 if (LocalAuthInfo != NULL)
1635 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1636
1637 /* Free the token information */
1638 if (TokenInformation != NULL)
1639 {
1640 if (TokenInformationType == LsaTokenInformationV1)
1641 {
1642 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1643
1644 if (TokenInfo1 != NULL)
1645 {
1646 if (TokenInfo1->User.User.Sid != NULL)
1647 LsapFreeHeap(TokenInfo1->User.User.Sid);
1648
1649 if (TokenInfo1->Groups != NULL)
1650 {
1651 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1652 {
1653 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
1654 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
1655 }
1656
1657 LsapFreeHeap(TokenInfo1->Groups);
1658 }
1659
1660 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
1661 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
1662
1663 if (TokenInfo1->Privileges != NULL)
1664 LsapFreeHeap(TokenInfo1->Privileges);
1665
1666 if (TokenInfo1->Owner.Owner != NULL)
1667 LsapFreeHeap(TokenInfo1->Owner.Owner);
1668
1669 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1670 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
1671
1672 LsapFreeHeap(TokenInfo1);
1673 }
1674 }
1675 else
1676 {
1677 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1678 }
1679 }
1680
1681 /* Free the account name */
1682 if (AccountName != NULL)
1683 {
1684 if (AccountName->Buffer != NULL)
1685 LsapFreeHeap(AccountName->Buffer);
1686
1687 LsapFreeHeap(AccountName);
1688 }
1689
1690 /* Free the authentication authority */
1691 if (AuthenticatingAuthority != NULL)
1692 {
1693 if (AuthenticatingAuthority != NULL)
1694 LsapFreeHeap(AuthenticatingAuthority->Buffer);
1695
1696 LsapFreeHeap(AuthenticatingAuthority);
1697 }
1698
1699 /* Free the machine name */
1700 if (MachineName != NULL)
1701 {
1702 if (MachineName->Buffer != NULL)
1703 LsapFreeHeap(MachineName->Buffer);
1704
1705 LsapFreeHeap(MachineName);
1706 }
1707
1708 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
1709
1710 return Status;
1711 }
1712
1713 /* EOF */