* Sync up to trunk head (r64829).
[reactos.git] / dll / win32 / lsasrv / authpackage.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/lsasrv/authpackage.c
5 * PURPOSE: Authenticaton package management routines
6 * COPYRIGHT: Copyright 2013 Eric Kohl
7 */
8
9 #include "lsasrv.h"
10
11 #include <ndk/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 Status = SamIConnect(NULL,
1033 &ServerHandle,
1034 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1035 FALSE);
1036 if (!NT_SUCCESS(Status))
1037 {
1038 TRACE("SamIConnect failed (Status %08lx)\n", Status);
1039 goto done;
1040 }
1041
1042 Status = SamrOpenDomain(ServerHandle,
1043 DOMAIN_GET_ALIAS_MEMBERSHIP,
1044 BuiltinDomainSid,
1045 &BuiltinDomainHandle);
1046 if (!NT_SUCCESS(Status))
1047 {
1048 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1049 goto done;
1050 }
1051
1052 Status = SamrOpenDomain(ServerHandle,
1053 DOMAIN_GET_ALIAS_MEMBERSHIP,
1054 AccountDomainSid,
1055 &AccountDomainHandle);
1056 if (!NT_SUCCESS(Status))
1057 {
1058 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1059 goto done;
1060 }
1061
1062 BuiltinMembership.Element = NULL;
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 AccountMembership.Element = NULL;
1073 Status = SamrGetAliasMembership(AccountDomainHandle,
1074 &SidArray,
1075 &AccountMembership);
1076 if (!NT_SUCCESS(Status))
1077 {
1078 TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status);
1079 goto done;
1080 }
1081
1082 TRACE("Builtin Memberships: %lu\n", BuiltinMembership.Count);
1083 for (i = 0; i < BuiltinMembership.Count; i++)
1084 {
1085 TRACE("RID %lu: %lu (0x%lx)\n", i, BuiltinMembership.Element[i], BuiltinMembership.Element[i]);
1086 Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
1087 BuiltinDomainSid,
1088 BuiltinMembership.Element[i]);
1089 if (!NT_SUCCESS(Status))
1090 {
1091 TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
1092 goto done;
1093 }
1094 }
1095
1096 TRACE("Account Memberships: %lu\n", AccountMembership.Count);
1097 for (i = 0; i < AccountMembership.Count; i++)
1098 {
1099 TRACE("RID %lu: %lu (0x%lx)\n", i, AccountMembership.Element[i], AccountMembership.Element[i]);
1100 Status = LsapAppendSidToGroups(&TokenInfo1->Groups,
1101 AccountDomainSid,
1102 AccountMembership.Element[i]);
1103 if (!NT_SUCCESS(Status))
1104 {
1105 TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status);
1106 goto done;
1107 }
1108 }
1109
1110 done:
1111 RtlFreeHeap(RtlGetProcessHeap(), 0, SidArray.Sids);
1112
1113 if (AccountMembership.Element != NULL)
1114 SamIFree_SAMPR_ULONG_ARRAY(&AccountMembership);
1115
1116 if (BuiltinMembership.Element != NULL)
1117 SamIFree_SAMPR_ULONG_ARRAY(&BuiltinMembership);
1118
1119 if (AccountDomainHandle != NULL)
1120 SamrCloseHandle(&AccountDomainHandle);
1121
1122 if (BuiltinDomainHandle != NULL)
1123 SamrCloseHandle(&BuiltinDomainHandle);
1124
1125 if (ServerHandle != NULL)
1126 SamrCloseHandle(&ServerHandle);
1127
1128 // return Status;
1129
1130 return STATUS_SUCCESS;
1131 }
1132
1133
1134 static
1135 NTSTATUS
1136 LsapSetTokenOwner(
1137 IN PVOID TokenInformation,
1138 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1139 {
1140 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1141 PSID OwnerSid = NULL;
1142 ULONG i, Length;
1143
1144 if (TokenInformationType == LsaTokenInformationV1)
1145 {
1146 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1147
1148 if (TokenInfo1->Owner.Owner != NULL)
1149 return STATUS_SUCCESS;
1150
1151 OwnerSid = TokenInfo1->User.User.Sid;
1152 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1153 {
1154 if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
1155 {
1156 OwnerSid = LsapAdministratorsSid;
1157 break;
1158 }
1159 }
1160
1161 Length = RtlLengthSid(OwnerSid);
1162 TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length);
1163 if (TokenInfo1->Owner.Owner == NULL)
1164 return STATUS_INSUFFICIENT_RESOURCES;
1165
1166 RtlCopyMemory(TokenInfo1->Owner.Owner,
1167 OwnerSid,
1168 Length);
1169 }
1170
1171 return STATUS_SUCCESS;
1172 }
1173
1174
1175 static
1176 NTSTATUS
1177 LsapAddTokenDefaultDacl(
1178 IN PVOID TokenInformation,
1179 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1180 {
1181 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1182 PACL Dacl = NULL;
1183 ULONG Length;
1184
1185 if (TokenInformationType == LsaTokenInformationV1)
1186 {
1187 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1188
1189 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1190 return STATUS_SUCCESS;
1191
1192 Length = sizeof(ACL) +
1193 (2 * sizeof(ACCESS_ALLOWED_ACE)) +
1194 RtlLengthSid(TokenInfo1->Owner.Owner) +
1195 RtlLengthSid(LsapLocalSystemSid);
1196
1197 Dacl = DispatchTable.AllocateLsaHeap(Length);
1198 if (Dacl == NULL)
1199 return STATUS_INSUFFICIENT_RESOURCES;
1200
1201 RtlCreateAcl(Dacl, Length, ACL_REVISION);
1202
1203 RtlAddAccessAllowedAce(Dacl,
1204 ACL_REVISION,
1205 GENERIC_ALL,
1206 TokenInfo1->Owner.Owner);
1207
1208 /* SID: S-1-5-18 */
1209 RtlAddAccessAllowedAce(Dacl,
1210 ACL_REVISION,
1211 GENERIC_ALL,
1212 LsapLocalSystemSid);
1213
1214 TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
1215 }
1216
1217 return STATUS_SUCCESS;
1218 }
1219
1220
1221 static
1222 NTSTATUS
1223 LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
1224 PLSAPR_LUID_AND_ATTRIBUTES Privilege)
1225 {
1226 PTOKEN_PRIVILEGES LocalPrivileges;
1227 ULONG Length, TokenPrivilegeCount, i;
1228 NTSTATUS Status = STATUS_SUCCESS;
1229
1230 if (*TokenPrivileges == NULL)
1231 {
1232 Length = sizeof(TOKEN_PRIVILEGES) +
1233 (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1234 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1235 0,
1236 Length);
1237 if (LocalPrivileges == NULL)
1238 return STATUS_INSUFFICIENT_RESOURCES;
1239
1240 LocalPrivileges->PrivilegeCount = 1;
1241 LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
1242 LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
1243 }
1244 else
1245 {
1246 TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
1247
1248 for (i = 0; i < TokenPrivilegeCount; i++)
1249 {
1250 if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
1251 return STATUS_SUCCESS;
1252 }
1253
1254 Length = sizeof(TOKEN_PRIVILEGES) +
1255 (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
1256 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
1257 0,
1258 Length);
1259 if (LocalPrivileges == NULL)
1260 return STATUS_INSUFFICIENT_RESOURCES;
1261
1262 LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
1263 for (i = 0; i < TokenPrivilegeCount; i++)
1264 {
1265 LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
1266 LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
1267 }
1268
1269 LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
1270 LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
1271
1272 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
1273 }
1274
1275 *TokenPrivileges = LocalPrivileges;
1276
1277 return Status;
1278 }
1279
1280 static
1281 NTSTATUS
1282 LsapSetPrivileges(
1283 IN PVOID TokenInformation,
1284 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
1285 {
1286 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
1287 LSAPR_HANDLE PolicyHandle = NULL;
1288 LSAPR_HANDLE AccountHandle = NULL;
1289 PLSAPR_PRIVILEGE_SET Privileges = NULL;
1290 ULONG i, j;
1291 NTSTATUS Status;
1292
1293 if (TokenInformationType == LsaTokenInformationV1)
1294 {
1295 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1296
1297 Status = LsarOpenPolicy(NULL,
1298 NULL,
1299 0,
1300 &PolicyHandle);
1301 if (!NT_SUCCESS(Status))
1302 return Status;
1303
1304 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1305 {
1306 Status = LsarOpenAccount(PolicyHandle,
1307 TokenInfo1->Groups->Groups[i].Sid,
1308 ACCOUNT_VIEW,
1309 &AccountHandle);
1310 if (!NT_SUCCESS(Status))
1311 continue;
1312
1313 Status = LsarEnumeratePrivilegesAccount(AccountHandle,
1314 &Privileges);
1315 if (NT_SUCCESS(Status))
1316 {
1317 for (j = 0; j < Privileges->PrivilegeCount; j++)
1318 {
1319 Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
1320 &(Privileges->Privilege[j]));
1321 if (!NT_SUCCESS(Status))
1322 {
1323 /* We failed, clean everything and return */
1324 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1325 LsarClose(&AccountHandle);
1326 LsarClose(&PolicyHandle);
1327
1328 return Status;
1329 }
1330 }
1331
1332 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
1333 Privileges = NULL;
1334 }
1335
1336 LsarClose(&AccountHandle);
1337 }
1338
1339 LsarClose(&PolicyHandle);
1340
1341 if (TokenInfo1->Privileges != NULL)
1342 {
1343 for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
1344 {
1345 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
1346 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
1347 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
1348 {
1349 TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
1350 }
1351 }
1352 }
1353 }
1354
1355 return STATUS_SUCCESS;
1356 }
1357
1358
1359 NTSTATUS
1360 LsapLogonUser(PLSA_API_MSG RequestMsg,
1361 PLSAP_LOGON_CONTEXT LogonContext)
1362 {
1363 PAUTH_PACKAGE Package;
1364 OBJECT_ATTRIBUTES ObjectAttributes;
1365 SECURITY_QUALITY_OF_SERVICE Qos;
1366 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
1367 PVOID TokenInformation = NULL;
1368 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
1369 PUNICODE_STRING AccountName = NULL;
1370 PUNICODE_STRING AuthenticatingAuthority = NULL;
1371 PUNICODE_STRING MachineName = NULL;
1372 PVOID LocalAuthInfo = NULL;
1373 PTOKEN_GROUPS LocalGroups = NULL;
1374 HANDLE TokenHandle = NULL;
1375 ULONG i;
1376 ULONG PackageId;
1377 SECURITY_LOGON_TYPE LogonType;
1378 NTSTATUS Status;
1379
1380 TRACE("(%p %p)\n", RequestMsg, LogonContext);
1381
1382 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
1383 LogonType = RequestMsg->LogonUser.Request.LogonType;
1384
1385 /* Get the right authentication package */
1386 Package = LsapGetAuthenticationPackage(PackageId);
1387 if (Package == NULL)
1388 {
1389 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
1390 return STATUS_NO_SUCH_PACKAGE;
1391 }
1392
1393 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
1394 {
1395 /* Allocate the local authentication info buffer */
1396 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1397 HEAP_ZERO_MEMORY,
1398 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
1399 if (LocalAuthInfo == NULL)
1400 {
1401 ERR("RtlAllocateHeap() failed\n");
1402 return STATUS_INSUFFICIENT_RESOURCES;
1403 }
1404
1405 /* Read the authentication info from the callers adress space */
1406 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
1407 RequestMsg->LogonUser.Request.AuthenticationInformation,
1408 LocalAuthInfo,
1409 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1410 NULL);
1411 if (!NT_SUCCESS(Status))
1412 {
1413 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
1414 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1415 return Status;
1416 }
1417 }
1418
1419 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
1420 {
1421 Status = LsapCopyLocalGroups(LogonContext,
1422 RequestMsg->LogonUser.Request.LocalGroups,
1423 RequestMsg->LogonUser.Request.LocalGroupsCount,
1424 &LocalGroups);
1425 if (!NT_SUCCESS(Status))
1426 {
1427 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
1428 goto done;
1429 }
1430
1431 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
1432 }
1433
1434 if (Package->LsaApLogonUserEx2 != NULL)
1435 {
1436 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
1437 RequestMsg->LogonUser.Request.LogonType,
1438 LocalAuthInfo,
1439 RequestMsg->LogonUser.Request.AuthenticationInformation,
1440 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1441 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1442 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1443 &RequestMsg->LogonUser.Reply.LogonId,
1444 &RequestMsg->LogonUser.Reply.SubStatus,
1445 &TokenInformationType,
1446 &TokenInformation,
1447 &AccountName,
1448 &AuthenticatingAuthority,
1449 &MachineName,
1450 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
1451 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
1452 }
1453 else if (Package->LsaApLogonUserEx != NULL)
1454 {
1455 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
1456 RequestMsg->LogonUser.Request.LogonType,
1457 LocalAuthInfo,
1458 RequestMsg->LogonUser.Request.AuthenticationInformation,
1459 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1460 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1461 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1462 &RequestMsg->LogonUser.Reply.LogonId,
1463 &RequestMsg->LogonUser.Reply.SubStatus,
1464 &TokenInformationType,
1465 &TokenInformation,
1466 &AccountName,
1467 &AuthenticatingAuthority,
1468 &MachineName);
1469 }
1470 else
1471 {
1472 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
1473 RequestMsg->LogonUser.Request.LogonType,
1474 LocalAuthInfo,
1475 RequestMsg->LogonUser.Request.AuthenticationInformation,
1476 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
1477 &RequestMsg->LogonUser.Reply.ProfileBuffer,
1478 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
1479 &RequestMsg->LogonUser.Reply.LogonId,
1480 &RequestMsg->LogonUser.Reply.SubStatus,
1481 &TokenInformationType,
1482 &TokenInformation,
1483 &AccountName,
1484 &AuthenticatingAuthority);
1485 }
1486
1487 if (!NT_SUCCESS(Status))
1488 {
1489 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
1490 goto done;
1491 }
1492
1493 if (LocalGroups->GroupCount > 0)
1494 {
1495 /* Add local groups to the token information */
1496 Status = LsapAddLocalGroups(TokenInformation,
1497 TokenInformationType,
1498 LocalGroups);
1499 if (!NT_SUCCESS(Status))
1500 {
1501 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status);
1502 goto done;
1503 }
1504 }
1505
1506 Status = LsapAddDefaultGroups(TokenInformation,
1507 TokenInformationType,
1508 LogonType);
1509 if (!NT_SUCCESS(Status))
1510 {
1511 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status);
1512 goto done;
1513 }
1514
1515 Status = LsapAddSamGroups(TokenInformation,
1516 TokenInformationType);
1517 if (!NT_SUCCESS(Status))
1518 {
1519 ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status);
1520 goto done;
1521 }
1522
1523 Status = LsapSetTokenOwner(TokenInformation,
1524 TokenInformationType);
1525 if (!NT_SUCCESS(Status))
1526 {
1527 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
1528 goto done;
1529 }
1530
1531 Status = LsapAddTokenDefaultDacl(TokenInformation,
1532 TokenInformationType);
1533 if (!NT_SUCCESS(Status))
1534 {
1535 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
1536 goto done;
1537 }
1538
1539 Status = LsapSetPrivileges(TokenInformation,
1540 TokenInformationType);
1541 if (!NT_SUCCESS(Status))
1542 {
1543 ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
1544 goto done;
1545 }
1546
1547 if (TokenInformationType == LsaTokenInformationV1)
1548 {
1549 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1550
1551 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1552 Qos.ImpersonationLevel = SecurityImpersonation;
1553 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
1554 Qos.EffectiveOnly = FALSE;
1555
1556 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
1557 ObjectAttributes.RootDirectory = NULL;
1558 ObjectAttributes.ObjectName = NULL;
1559 ObjectAttributes.Attributes = 0;
1560 ObjectAttributes.SecurityDescriptor = NULL;
1561 ObjectAttributes.SecurityQualityOfService = &Qos;
1562
1563 /* Create the logon token */
1564 Status = NtCreateToken(&TokenHandle,
1565 TOKEN_ALL_ACCESS,
1566 &ObjectAttributes,
1567 TokenPrimary,
1568 &RequestMsg->LogonUser.Reply.LogonId,
1569 &TokenInfo1->ExpirationTime,
1570 &TokenInfo1->User,
1571 TokenInfo1->Groups,
1572 TokenInfo1->Privileges,
1573 &TokenInfo1->Owner,
1574 &TokenInfo1->PrimaryGroup,
1575 &TokenInfo1->DefaultDacl,
1576 &RequestMsg->LogonUser.Request.SourceContext);
1577 if (!NT_SUCCESS(Status))
1578 {
1579 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
1580 goto done;
1581 }
1582 }
1583 else
1584 {
1585 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1586 Status = STATUS_NOT_IMPLEMENTED;
1587 goto done;
1588 }
1589
1590 /* Duplicate the token handle into the client process */
1591 Status = NtDuplicateObject(NtCurrentProcess(),
1592 TokenHandle,
1593 LogonContext->ClientProcessHandle,
1594 &RequestMsg->LogonUser.Reply.Token,
1595 0,
1596 0,
1597 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
1598 if (!NT_SUCCESS(Status))
1599 {
1600 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
1601 goto done;
1602 }
1603
1604 TokenHandle = NULL;
1605
1606 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
1607 if (!NT_SUCCESS(Status))
1608 {
1609 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
1610 goto done;
1611 }
1612
1613 done:
1614 if (!NT_SUCCESS(Status))
1615 {
1616 if (TokenHandle != NULL)
1617 NtClose(TokenHandle);
1618 }
1619
1620 /* Free the local groups */
1621 if (LocalGroups != NULL)
1622 {
1623 for (i = 0; i < LocalGroups->GroupCount; i++)
1624 {
1625 if (LocalGroups->Groups[i].Sid != NULL)
1626 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
1627 }
1628
1629 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
1630 }
1631
1632 /* Free the local authentication info buffer */
1633 if (LocalAuthInfo != NULL)
1634 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
1635
1636 /* Free the token information */
1637 if (TokenInformation != NULL)
1638 {
1639 if (TokenInformationType == LsaTokenInformationV1)
1640 {
1641 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
1642
1643 if (TokenInfo1 != NULL)
1644 {
1645 if (TokenInfo1->User.User.Sid != NULL)
1646 LsapFreeHeap(TokenInfo1->User.User.Sid);
1647
1648 if (TokenInfo1->Groups != NULL)
1649 {
1650 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
1651 {
1652 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
1653 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
1654 }
1655
1656 LsapFreeHeap(TokenInfo1->Groups);
1657 }
1658
1659 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
1660 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
1661
1662 if (TokenInfo1->Privileges != NULL)
1663 LsapFreeHeap(TokenInfo1->Privileges);
1664
1665 if (TokenInfo1->Owner.Owner != NULL)
1666 LsapFreeHeap(TokenInfo1->Owner.Owner);
1667
1668 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1669 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
1670
1671 LsapFreeHeap(TokenInfo1);
1672 }
1673 }
1674 else
1675 {
1676 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1677 }
1678 }
1679
1680 /* Free the account name */
1681 if (AccountName != NULL)
1682 {
1683 if (AccountName->Buffer != NULL)
1684 LsapFreeHeap(AccountName->Buffer);
1685
1686 LsapFreeHeap(AccountName);
1687 }
1688
1689 /* Free the authentication authority */
1690 if (AuthenticatingAuthority != NULL)
1691 {
1692 if (AuthenticatingAuthority != NULL)
1693 LsapFreeHeap(AuthenticatingAuthority->Buffer);
1694
1695 LsapFreeHeap(AuthenticatingAuthority);
1696 }
1697
1698 /* Free the machine name */
1699 if (MachineName != NULL)
1700 {
1701 if (MachineName->Buffer != NULL)
1702 LsapFreeHeap(MachineName->Buffer);
1703
1704 LsapFreeHeap(MachineName);
1705 }
1706
1707 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
1708
1709 return Status;
1710 }
1711
1712 /* EOF */