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