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