[LIBXSLT] Update to version 1.1.32. CORE-14291
[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 ULONG 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 ULONG 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 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.Sid;
1151 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1152 {
1153 if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
1154 {
1155 OwnerSid = LsapAdministratorsSid;
1156 break;
1157 }
1158 }
1159
1160 Length = RtlLengthSid(OwnerSid);
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,
1167 Length);
1168 }
1169
1170 return STATUS_SUCCESS;
1171 }
1172
1173
1174 static
1175 NTSTATUS
1176 LsapAddTokenDefaultDacl(
1177 IN PVOID TokenInformation,
1178 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1179 {
1180 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1181 PACL Dacl = NULL;
1182 ULONG Length;
1183
1184 if (TokenInformationType == LsaTokenInformationV1)
1185 {
1186 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1187
1188 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1189 return STATUS_SUCCESS;
1190
1191 Length = sizeof(ACL) +
1192 (2 * sizeof(ACCESS_ALLOWED_ACE)) +
1193 RtlLengthSid(TokenInfo1->Owner.Owner) +
1194 RtlLengthSid(LsapLocalSystemSid);
1195
1196 Dacl = DispatchTable.AllocateLsaHeap(Length);
1197 if (Dacl == NULL)
1198 return STATUS_INSUFFICIENT_RESOURCES;
1199
1200 RtlCreateAcl(Dacl, Length, ACL_REVISION);
1201
1202 RtlAddAccessAllowedAce(Dacl,
1203 ACL_REVISION,
1204 GENERIC_ALL,
1205 TokenInfo1->Owner.Owner);
1206
1207 /* SID: S-1-5-18 */
1208 RtlAddAccessAllowedAce(Dacl,
1209 ACL_REVISION,
1210 GENERIC_ALL,
1211 LsapLocalSystemSid);
1212
1213 TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
1214 }
1215
1216 return STATUS_SUCCESS;
1217 }
1218
1219
1220 static
1221 NTSTATUS
1222 LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
1223 PLSAPR_LUID_AND_ATTRIBUTES Privilege)
1224 {
1225 PTOKEN_PRIVILEGES LocalPrivileges;
1226 ULONG Length, TokenPrivilegeCount, i;
1227 NTSTATUS Status = STATUS_SUCCESS;
1228
1229 if (*TokenPrivileges == NULL)
1230 {
1231 Length = sizeof(TOKEN_PRIVILEGES) +
1232 (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1233 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1234 0,
1235 Length);
1236 if (LocalPrivileges == NULL)
1237 return STATUS_INSUFFICIENT_RESOURCES;
1238
1239 LocalPrivileges->PrivilegeCount = 1;
1240 LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
1241 LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
1242 }
1243 else
1244 {
1245 TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
1246
1247 for (i = 0; i < TokenPrivilegeCount; i++)
1248 {
1249 if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
1250 return STATUS_SUCCESS;
1251 }
1252
1253 Length = sizeof(TOKEN_PRIVILEGES) +
1254 (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1255 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1256 0,
1257 Length);
1258 if (LocalPrivileges == NULL)
1259 return STATUS_INSUFFICIENT_RESOURCES;
1260
1261 LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
1262 for (i = 0; i < TokenPrivilegeCount; i++)
1263 {
1264 LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
1265 LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
1266 }
1267
1268 LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
1269 LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
1270
1271 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
1272 }
1273
1274 *TokenPrivileges = LocalPrivileges;
1275
1276 return Status;
1277 }
1278
1279 static
1280 NTSTATUS
1281 LsapSetPrivileges(
1282 IN PVOID TokenInformation,
1283 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1284 {
1285 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1286 LSAPR_HANDLE PolicyHandle = NULL;
1287 LSAPR_HANDLE AccountHandle = NULL;
1288 PLSAPR_PRIVILEGE_SET Privileges = NULL;
1289 ULONG i, j;
1290 NTSTATUS Status;
1291
1292 if (TokenInformationType == LsaTokenInformationV1)
1293 {
1294 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1295
1296 Status = LsarOpenPolicy(NULL,
1297 NULL,
1298 0,
1299 &PolicyHandle);
1300 if (!NT_SUCCESS(Status))
1301 return Status;
1302
1303 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1304 {
1305 Status = LsarOpenAccount(PolicyHandle,
1306 TokenInfo1->Groups->Groups[i].Sid,
1307 ACCOUNT_VIEW,
1308 &AccountHandle);
1309 if (!NT_SUCCESS(Status))
1310 continue;
1311
1312 Status = LsarEnumeratePrivilegesAccount(AccountHandle,
1313 &Privileges);
1314 if (NT_SUCCESS(Status))
1315 {
1316 for (j = 0; j < Privileges->PrivilegeCount; j++)
1317 {
1318 Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
1319 &(Privileges->Privilege[j]));
1320 if (!NT_SUCCESS(Status))
1321 {
1322 /* We failed, clean everything and return */
1323 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1324 LsarClose(&AccountHandle);
1325 LsarClose(&PolicyHandle);
1326
1327 return Status;
1328 }
1329 }
1330
1331 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1332 Privileges = NULL;
1333 }
1334
1335 LsarClose(&AccountHandle);
1336 }
1337
1338 LsarClose(&PolicyHandle);
1339
1340 if (TokenInfo1->Privileges != NULL)
1341 {
1342 for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
1343 {
1344 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
1345 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
1346 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
1347 {
1348 TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
1349 }
1350 }
1351 }
1352 }
1353
1354 return STATUS_SUCCESS;
1355 }
1356
1357
1358 NTSTATUS
1359 LsapLogonUser(PLSA_API_MSG RequestMsg,
1360 PLSAP_LOGON_CONTEXT LogonContext)
1361 {
1362 PAUTH_PACKAGE Package;
1363 OBJECT_ATTRIBUTES ObjectAttributes;
1364 SECURITY_QUALITY_OF_SERVICE Qos;
1365 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
1366 PVOID TokenInformation = NULL;
1367 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
1368 PUNICODE_STRING AccountName = NULL;
1369 PUNICODE_STRING AuthenticatingAuthority = NULL;
1370 PUNICODE_STRING MachineName = NULL;
1371 PVOID LocalAuthInfo = NULL;
1372 PTOKEN_GROUPS LocalGroups = NULL;
1373 HANDLE TokenHandle = NULL;
1374 ULONG i;
1375 ULONG PackageId;
1376 SECURITY_LOGON_TYPE LogonType;
1377 NTSTATUS Status;
1378
1379 PUNICODE_STRING UserName = NULL;
1380 PUNICODE_STRING LogonDomainName = NULL;
1381 // UNICODE_STRING LogonServer;
1382
1383
1384 TRACE("LsapLogonUser(%p %p)\n", RequestMsg, LogonContext);
1385
1386 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
1387 LogonType = RequestMsg->LogonUser.Request.LogonType;
1388
1389 /* Get the right authentication package */
1390 Package = LsapGetAuthenticationPackage(PackageId);
1391 if (Package == NULL)
1392 {
1393 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
1394 return STATUS_NO_SUCH_PACKAGE;
1395 }
1396
1397 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
1398 {
1399 /* Allocate the local authentication info buffer */
1400 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1401 HEAP_ZERO_MEMORY,
1402 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
1403 if (LocalAuthInfo == NULL)
1404 {
1405 ERR("RtlAllocateHeap() failed\n");
1406 return STATUS_INSUFFICIENT_RESOURCES;
1407 }
1408
1409 /* Read the authentication info from the callers address space */
1410 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
1411 RequestMsg->LogonUser.Request.AuthenticationInformation,
1412 LocalAuthInfo,
1413 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1414 NULL);
1415 if (!NT_SUCCESS(Status))
1416 {
1417 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
1418 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1419 return Status;
1420 }
1421 }
1422
1423 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
1424 {
1425 Status = LsapCopyLocalGroups(LogonContext,
1426 RequestMsg->LogonUser.Request.LocalGroups,
1427 RequestMsg->LogonUser.Request.LocalGroupsCount,
1428 &LocalGroups);
1429 if (!NT_SUCCESS(Status))
1430 {
1431 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
1432 goto done;
1433 }
1434
1435 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
1436 }
1437
1438 if (Package->LsaApLogonUserEx2 != NULL)
1439 {
1440 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
1441 RequestMsg->LogonUser.Request.LogonType,
1442 LocalAuthInfo,
1443 RequestMsg->LogonUser.Request.AuthenticationInformation,
1444 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1445 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1446 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1447 &RequestMsg->LogonUser.Reply.LogonId,
1448 &RequestMsg->LogonUser.Reply.SubStatus,
1449 &TokenInformationType,
1450 &TokenInformation,
1451 &AccountName,
1452 &AuthenticatingAuthority,
1453 &MachineName,
1454 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
1455 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
1456 }
1457 else if (Package->LsaApLogonUserEx != NULL)
1458 {
1459 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
1460 RequestMsg->LogonUser.Request.LogonType,
1461 LocalAuthInfo,
1462 RequestMsg->LogonUser.Request.AuthenticationInformation,
1463 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1464 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1465 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1466 &RequestMsg->LogonUser.Reply.LogonId,
1467 &RequestMsg->LogonUser.Reply.SubStatus,
1468 &TokenInformationType,
1469 &TokenInformation,
1470 &AccountName,
1471 &AuthenticatingAuthority,
1472 &MachineName);
1473 }
1474 else
1475 {
1476 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
1477 RequestMsg->LogonUser.Request.LogonType,
1478 LocalAuthInfo,
1479 RequestMsg->LogonUser.Request.AuthenticationInformation,
1480 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1481 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1482 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1483 &RequestMsg->LogonUser.Reply.LogonId,
1484 &RequestMsg->LogonUser.Reply.SubStatus,
1485 &TokenInformationType,
1486 &TokenInformation,
1487 &AccountName,
1488 &AuthenticatingAuthority);
1489 }
1490
1491 if (!NT_SUCCESS(Status))
1492 {
1493 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
1494 goto done;
1495 }
1496
1497 if (LocalGroups->GroupCount > 0)
1498 {
1499 /* Add local groups to the token information */
1500 Status = LsapAddLocalGroups(TokenInformation,
1501 TokenInformationType,
1502 LocalGroups);
1503 if (!NT_SUCCESS(Status))
1504 {
1505 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status);
1506 goto done;
1507 }
1508 }
1509
1510 Status = LsapAddDefaultGroups(TokenInformation,
1511 TokenInformationType,
1512 LogonType);
1513 if (!NT_SUCCESS(Status))
1514 {
1515 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status);
1516 goto done;
1517 }
1518
1519 Status = LsapAddSamGroups(TokenInformation,
1520 TokenInformationType);
1521 if (!NT_SUCCESS(Status))
1522 {
1523 ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status);
1524 goto done;
1525 }
1526
1527 Status = LsapSetTokenOwner(TokenInformation,
1528 TokenInformationType);
1529 if (!NT_SUCCESS(Status))
1530 {
1531 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
1532 goto done;
1533 }
1534
1535 Status = LsapAddTokenDefaultDacl(TokenInformation,
1536 TokenInformationType);
1537 if (!NT_SUCCESS(Status))
1538 {
1539 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
1540 goto done;
1541 }
1542
1543 Status = LsapSetPrivileges(TokenInformation,
1544 TokenInformationType);
1545 if (!NT_SUCCESS(Status))
1546 {
1547 ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
1548 goto done;
1549 }
1550
1551 if (TokenInformationType == LsaTokenInformationV1)
1552 {
1553 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1554
1555 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1556 Qos.ImpersonationLevel = SecurityImpersonation;
1557 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
1558 Qos.EffectiveOnly = FALSE;
1559
1560 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1561 ObjectAttributes.RootDirectory = NULL;
1562 ObjectAttributes.ObjectName = NULL;
1563 ObjectAttributes.Attributes = 0;
1564 ObjectAttributes.SecurityDescriptor = NULL;
1565 ObjectAttributes.SecurityQualityOfService = &Qos;
1566
1567 /* Create the logon token */
1568 Status = NtCreateToken(&TokenHandle,
1569 TOKEN_ALL_ACCESS,
1570 &ObjectAttributes,
1571 TokenPrimary,
1572 &RequestMsg->LogonUser.Reply.LogonId,
1573 &TokenInfo1->ExpirationTime,
1574 &TokenInfo1->User,
1575 TokenInfo1->Groups,
1576 TokenInfo1->Privileges,
1577 &TokenInfo1->Owner,
1578 &TokenInfo1->PrimaryGroup,
1579 &TokenInfo1->DefaultDacl,
1580 &RequestMsg->LogonUser.Request.SourceContext);
1581 if (!NT_SUCCESS(Status))
1582 {
1583 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
1584 goto done;
1585 }
1586 }
1587 else
1588 {
1589 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1590 Status = STATUS_NOT_IMPLEMENTED;
1591 goto done;
1592 }
1593
1594 /* Duplicate the token handle into the client process */
1595 Status = NtDuplicateObject(NtCurrentProcess(),
1596 TokenHandle,
1597 LogonContext->ClientProcessHandle,
1598 &RequestMsg->LogonUser.Reply.Token,
1599 0,
1600 0,
1601 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
1602 if (!NT_SUCCESS(Status))
1603 {
1604 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
1605 goto done;
1606 }
1607
1608 // TokenHandle = NULL;
1609
1610 if (LogonType == Interactive ||
1611 LogonType == Batch ||
1612 LogonType == Service)
1613 {
1614 UserName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->UserName;
1615 LogonDomainName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->LogonDomainName;
1616 }
1617 else
1618 {
1619 FIXME("LogonType %lu is not supported yet!\n", LogonType);
1620 }
1621
1622 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId,
1623 LogonType,
1624 UserName,
1625 LogonDomainName,
1626 TokenInfo1->User.User.Sid);
1627 if (!NT_SUCCESS(Status))
1628 {
1629 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
1630 goto done;
1631 }
1632
1633 done:
1634 // if (!NT_SUCCESS(Status))
1635 // {
1636 if (TokenHandle != NULL)
1637 NtClose(TokenHandle);
1638 // }
1639
1640 /* Free the local groups */
1641 if (LocalGroups != NULL)
1642 {
1643 for (i = 0; i < LocalGroups->GroupCount; i++)
1644 {
1645 if (LocalGroups->Groups[i].Sid != NULL)
1646 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
1647 }
1648
1649 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
1650 }
1651
1652 /* Free the local authentication info buffer */
1653 if (LocalAuthInfo != NULL)
1654 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1655
1656 /* Free the token information */
1657 if (TokenInformation != NULL)
1658 {
1659 if (TokenInformationType == LsaTokenInformationV1)
1660 {
1661 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1662
1663 if (TokenInfo1 != NULL)
1664 {
1665 if (TokenInfo1->User.User.Sid != NULL)
1666 LsapFreeHeap(TokenInfo1->User.User.Sid);
1667
1668 if (TokenInfo1->Groups != NULL)
1669 {
1670 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1671 {
1672 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
1673 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
1674 }
1675
1676 LsapFreeHeap(TokenInfo1->Groups);
1677 }
1678
1679 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
1680 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
1681
1682 if (TokenInfo1->Privileges != NULL)
1683 LsapFreeHeap(TokenInfo1->Privileges);
1684
1685 if (TokenInfo1->Owner.Owner != NULL)
1686 LsapFreeHeap(TokenInfo1->Owner.Owner);
1687
1688 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1689 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
1690
1691 LsapFreeHeap(TokenInfo1);
1692 }
1693 }
1694 else
1695 {
1696 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1697 }
1698 }
1699
1700 /* Free the account name */
1701 if (AccountName != NULL)
1702 {
1703 if (AccountName->Buffer != NULL)
1704 LsapFreeHeap(AccountName->Buffer);
1705
1706 LsapFreeHeap(AccountName);
1707 }
1708
1709 /* Free the authentication authority */
1710 if (AuthenticatingAuthority != NULL)
1711 {
1712 if (AuthenticatingAuthority != NULL)
1713 LsapFreeHeap(AuthenticatingAuthority->Buffer);
1714
1715 LsapFreeHeap(AuthenticatingAuthority);
1716 }
1717
1718 /* Free the machine name */
1719 if (MachineName != NULL)
1720 {
1721 if (MachineName->Buffer != NULL)
1722 LsapFreeHeap(MachineName->Buffer);
1723
1724 LsapFreeHeap(MachineName);
1725 }
1726
1727 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
1728
1729 return Status;
1730 }
1731
1732 /* EOF */