[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 #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 {
1313 Status = LsarEnumeratePrivilegesAccount(AccountHandle,
1314 &Privileges);
1315 if (NT_SUCCESS(Status))
1316 {
1317 for (j = 0; j < Privileges->PrivilegeCount; j++)
1318 {
1319 Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
1320 &(Privileges->Privilege[j]));
1321 if (!NT_SUCCESS(Status))
1322 return Status;
1323 }
1324
1325 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1326 Privileges = NULL;
1327 }
1328 }
1329
1330 LsarClose(&AccountHandle);
1331 }
1332
1333 LsarClose(&PolicyHandle);
1334
1335 if (TokenInfo1->Privileges != NULL)
1336 {
1337 for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
1338 {
1339 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
1340 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
1341 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
1342 {
1343 TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
1344 }
1345 }
1346 }
1347 }
1348
1349 return STATUS_SUCCESS;
1350 }
1351
1352
1353 NTSTATUS
1354 LsapLogonUser(PLSA_API_MSG RequestMsg,
1355 PLSAP_LOGON_CONTEXT LogonContext)
1356 {
1357 PAUTH_PACKAGE Package;
1358 OBJECT_ATTRIBUTES ObjectAttributes;
1359 SECURITY_QUALITY_OF_SERVICE Qos;
1360 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
1361 PVOID TokenInformation = NULL;
1362 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
1363 PUNICODE_STRING AccountName = NULL;
1364 PUNICODE_STRING AuthenticatingAuthority = NULL;
1365 PUNICODE_STRING MachineName = NULL;
1366 PVOID LocalAuthInfo = NULL;
1367 PTOKEN_GROUPS LocalGroups = NULL;
1368 HANDLE TokenHandle = NULL;
1369 ULONG i;
1370 ULONG PackageId;
1371 SECURITY_LOGON_TYPE LogonType;
1372 NTSTATUS Status;
1373
1374 TRACE("(%p %p)\n", RequestMsg, LogonContext);
1375
1376 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
1377 LogonType = RequestMsg->LogonUser.Request.LogonType;
1378
1379 /* Get the right authentication package */
1380 Package = LsapGetAuthenticationPackage(PackageId);
1381 if (Package == NULL)
1382 {
1383 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
1384 return STATUS_NO_SUCH_PACKAGE;
1385 }
1386
1387 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
1388 {
1389 /* Allocate the local authentication info buffer */
1390 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1391 HEAP_ZERO_MEMORY,
1392 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
1393 if (LocalAuthInfo == NULL)
1394 {
1395 ERR("RtlAllocateHeap() failed\n");
1396 return STATUS_INSUFFICIENT_RESOURCES;
1397 }
1398
1399 /* Read the authentication info from the callers adress space */
1400 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
1401 RequestMsg->LogonUser.Request.AuthenticationInformation,
1402 LocalAuthInfo,
1403 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1404 NULL);
1405 if (!NT_SUCCESS(Status))
1406 {
1407 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
1408 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1409 return Status;
1410 }
1411 }
1412
1413 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
1414 {
1415 Status = LsapCopyLocalGroups(LogonContext,
1416 RequestMsg->LogonUser.Request.LocalGroups,
1417 RequestMsg->LogonUser.Request.LocalGroupsCount,
1418 &LocalGroups);
1419 if (!NT_SUCCESS(Status))
1420 {
1421 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
1422 goto done;
1423 }
1424
1425 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
1426 }
1427
1428 if (Package->LsaApLogonUserEx2 != NULL)
1429 {
1430 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
1431 RequestMsg->LogonUser.Request.LogonType,
1432 LocalAuthInfo,
1433 RequestMsg->LogonUser.Request.AuthenticationInformation,
1434 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1435 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1436 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1437 &RequestMsg->LogonUser.Reply.LogonId,
1438 &RequestMsg->LogonUser.Reply.SubStatus,
1439 &TokenInformationType,
1440 &TokenInformation,
1441 &AccountName,
1442 &AuthenticatingAuthority,
1443 &MachineName,
1444 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
1445 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
1446 }
1447 else if (Package->LsaApLogonUserEx != NULL)
1448 {
1449 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
1450 RequestMsg->LogonUser.Request.LogonType,
1451 LocalAuthInfo,
1452 RequestMsg->LogonUser.Request.AuthenticationInformation,
1453 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1454 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1455 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1456 &RequestMsg->LogonUser.Reply.LogonId,
1457 &RequestMsg->LogonUser.Reply.SubStatus,
1458 &TokenInformationType,
1459 &TokenInformation,
1460 &AccountName,
1461 &AuthenticatingAuthority,
1462 &MachineName);
1463 }
1464 else
1465 {
1466 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
1467 RequestMsg->LogonUser.Request.LogonType,
1468 LocalAuthInfo,
1469 RequestMsg->LogonUser.Request.AuthenticationInformation,
1470 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1471 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1472 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1473 &RequestMsg->LogonUser.Reply.LogonId,
1474 &RequestMsg->LogonUser.Reply.SubStatus,
1475 &TokenInformationType,
1476 &TokenInformation,
1477 &AccountName,
1478 &AuthenticatingAuthority);
1479 }
1480
1481 if (!NT_SUCCESS(Status))
1482 {
1483 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
1484 goto done;
1485 }
1486
1487 if (LocalGroups->GroupCount > 0)
1488 {
1489 /* Add local groups to the token information */
1490 Status = LsapAddLocalGroups(TokenInformation,
1491 TokenInformationType,
1492 LocalGroups);
1493 if (!NT_SUCCESS(Status))
1494 {
1495 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status);
1496 goto done;
1497 }
1498 }
1499
1500 Status = LsapAddDefaultGroups(TokenInformation,
1501 TokenInformationType,
1502 LogonType);
1503 if (!NT_SUCCESS(Status))
1504 {
1505 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status);
1506 goto done;
1507 }
1508
1509 Status = LsapAddSamGroups(TokenInformation,
1510 TokenInformationType);
1511 if (!NT_SUCCESS(Status))
1512 {
1513 ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status);
1514 goto done;
1515 }
1516
1517 Status = LsapSetTokenOwner(TokenInformation,
1518 TokenInformationType);
1519 if (!NT_SUCCESS(Status))
1520 {
1521 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
1522 goto done;
1523 }
1524
1525 Status = LsapAddTokenDefaultDacl(TokenInformation,
1526 TokenInformationType);
1527 if (!NT_SUCCESS(Status))
1528 {
1529 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
1530 goto done;
1531 }
1532
1533 Status = LsapSetPrivileges(TokenInformation,
1534 TokenInformationType);
1535 if (!NT_SUCCESS(Status))
1536 {
1537 ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
1538 goto done;
1539 }
1540
1541 if (TokenInformationType == LsaTokenInformationV1)
1542 {
1543 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1544
1545 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1546 Qos.ImpersonationLevel = SecurityImpersonation;
1547 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
1548 Qos.EffectiveOnly = FALSE;
1549
1550 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1551 ObjectAttributes.RootDirectory = NULL;
1552 ObjectAttributes.ObjectName = NULL;
1553 ObjectAttributes.Attributes = 0;
1554 ObjectAttributes.SecurityDescriptor = NULL;
1555 ObjectAttributes.SecurityQualityOfService = &Qos;
1556
1557 /* Create the logon token */
1558 Status = NtCreateToken(&TokenHandle,
1559 TOKEN_ALL_ACCESS,
1560 &ObjectAttributes,
1561 TokenPrimary,
1562 &RequestMsg->LogonUser.Reply.LogonId,
1563 &TokenInfo1->ExpirationTime,
1564 &TokenInfo1->User,
1565 TokenInfo1->Groups,
1566 TokenInfo1->Privileges,
1567 &TokenInfo1->Owner,
1568 &TokenInfo1->PrimaryGroup,
1569 &TokenInfo1->DefaultDacl,
1570 &RequestMsg->LogonUser.Request.SourceContext);
1571 if (!NT_SUCCESS(Status))
1572 {
1573 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
1574 goto done;
1575 }
1576 }
1577 else
1578 {
1579 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1580 Status = STATUS_NOT_IMPLEMENTED;
1581 goto done;
1582 }
1583
1584 /* Duplicate the token handle into the client process */
1585 Status = NtDuplicateObject(NtCurrentProcess(),
1586 TokenHandle,
1587 LogonContext->ClientProcessHandle,
1588 &RequestMsg->LogonUser.Reply.Token,
1589 0,
1590 0,
1591 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
1592 if (!NT_SUCCESS(Status))
1593 {
1594 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
1595 goto done;
1596 }
1597
1598 TokenHandle = NULL;
1599
1600 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
1601 if (!NT_SUCCESS(Status))
1602 {
1603 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
1604 goto done;
1605 }
1606
1607 done:
1608 if (!NT_SUCCESS(Status))
1609 {
1610 if (TokenHandle != NULL)
1611 NtClose(TokenHandle);
1612 }
1613
1614 /* Free the local groups */
1615 if (LocalGroups != NULL)
1616 {
1617 for (i = 0; i < LocalGroups->GroupCount; i++)
1618 {
1619 if (LocalGroups->Groups[i].Sid != NULL)
1620 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
1621 }
1622
1623 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
1624 }
1625
1626 /* Free the local authentication info buffer */
1627 if (LocalAuthInfo != NULL)
1628 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1629
1630 /* Free the token information */
1631 if (TokenInformation != NULL)
1632 {
1633 if (TokenInformationType == LsaTokenInformationV1)
1634 {
1635 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1636
1637 if (TokenInfo1 != NULL)
1638 {
1639 if (TokenInfo1->User.User.Sid != NULL)
1640 LsapFreeHeap(TokenInfo1->User.User.Sid);
1641
1642 if (TokenInfo1->Groups != NULL)
1643 {
1644 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1645 {
1646 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
1647 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
1648 }
1649
1650 LsapFreeHeap(TokenInfo1->Groups);
1651 }
1652
1653 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
1654 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
1655
1656 if (TokenInfo1->Privileges != NULL)
1657 LsapFreeHeap(TokenInfo1->Privileges);
1658
1659 if (TokenInfo1->Owner.Owner != NULL)
1660 LsapFreeHeap(TokenInfo1->Owner.Owner);
1661
1662 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1663 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
1664
1665 LsapFreeHeap(TokenInfo1);
1666 }
1667 }
1668 else
1669 {
1670 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1671 }
1672 }
1673
1674 /* Free the account name */
1675 if (AccountName != NULL)
1676 {
1677 if (AccountName->Buffer != NULL)
1678 LsapFreeHeap(AccountName->Buffer);
1679
1680 LsapFreeHeap(AccountName);
1681 }
1682
1683 /* Free the authentication authority */
1684 if (AuthenticatingAuthority != NULL)
1685 {
1686 if (AuthenticatingAuthority != NULL)
1687 LsapFreeHeap(AuthenticatingAuthority->Buffer);
1688
1689 LsapFreeHeap(AuthenticatingAuthority);
1690 }
1691
1692 /* Free the machine name */
1693 if (MachineName != NULL)
1694 {
1695 if (MachineName->Buffer != NULL)
1696 LsapFreeHeap(MachineName->Buffer);
1697
1698 LsapFreeHeap(MachineName);
1699 }
1700
1701 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
1702
1703 return Status;
1704 }
1705
1706 /* EOF */