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