c649d78aa2a8276866b96f60810b49a0c5d53530
[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 typedef enum _LSA_TOKEN_INFORMATION_TYPE
12 {
13 LsaTokenInformationNull,
14 LsaTokenInformationV1
15 } LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;
16
17 typedef struct _LSA_TOKEN_INFORMATION_V1
18 {
19 LARGE_INTEGER ExpirationTime;
20 TOKEN_USER User;
21 PTOKEN_GROUPS Groups;
22 TOKEN_PRIMARY_GROUP PrimaryGroup;
23 PTOKEN_PRIVILEGES Privileges;
24 TOKEN_OWNER Owner;
25 TOKEN_DEFAULT_DACL DefaultDacl;
26 } LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1;
27
28 typedef PVOID PLSA_CLIENT_REQUEST;
29
30 typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID);
31 typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID);
32
33 typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG);
34 typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID);
35 typedef NTSTATUS (NTAPI *PLSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, PVOID*);
36 typedef NTSTATUS (NTAPI *PLSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, PVOID);
37 typedef NTSTATUS (NTAPI *PLSA_COPY_TO_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG,
38 PVOID, PVOID);
39 typedef NTSTATUS (NTAPI *PLSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST,
40 ULONG, PVOID, PVOID);
41
42 typedef struct LSA_DISPATCH_TABLE
43 {
44 PLSA_CREATE_LOGON_SESSION CreateLogonSession;
45 PLSA_DELETE_LOGON_SESSION DeleteLogonSession;
46 PVOID /*PLSA_ADD_CREDENTIAL */ AddCredential;
47 PVOID /*PLSA_GET_CREDENTIALS */ GetCredentials;
48 PVOID /*PLSA_DELETE_CREDENTIAL */ DeleteCredential;
49 PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap;
50 PLSA_FREE_LSA_HEAP FreeLsaHeap;
51 PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer;
52 PLSA_FREE_CLIENT_BUFFER FreeClientBuffer;
53 PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer;
54 PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
55 } LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;
56
57
58 typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PLSA_DISPATCH_TABLE,
59 PLSA_STRING, PLSA_STRING, PLSA_STRING *);
60 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_INTERNAL)(PLSA_CLIENT_REQUEST, PVOID, PVOID,
61 ULONG, PVOID *, PULONG, PNTSTATUS);
62 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_PASSTHROUGH)(PLSA_CLIENT_REQUEST,
63 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
64 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_UNTRUSTED)(PLSA_CLIENT_REQUEST,
65 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS);
66 typedef VOID (NTAPI *PLSA_AP_LOGON_TERMINATED)(PLUID);
67 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX2)(PLSA_CLIENT_REQUEST,
68 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
69 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
70 PUNICODE_STRING *, PVOID /*PSECPKG_PRIMARY_CRED*/, PVOID /*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/);
71 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX)(PLSA_CLIENT_REQUEST,
72 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS,
73 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *,
74 PUNICODE_STRING *);
75
76 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_INTERNAL)(PLSA_CLIENT_REQUEST, SECURITY_LOGON_TYPE,
77 PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, PLSA_TOKEN_INFORMATION_TYPE,
78 PVOID *, PUNICODE_STRING *, PUNICODE_STRING *);
79
80 typedef struct _AUTH_PACKAGE
81 {
82 LIST_ENTRY Entry;
83 PSTRING Name;
84 ULONG Id;
85 PVOID ModuleHandle;
86
87 PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage;
88 PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage;
89 PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough;
90 PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted;
91 PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated;
92 PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2;
93 PLSA_AP_LOGON_USER_EX LsaApLogonUserEx;
94 PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser;
95 } AUTH_PACKAGE, *PAUTH_PACKAGE;
96
97
98 /* GLOBALS *****************************************************************/
99
100 static LIST_ENTRY PackageListHead;
101 static ULONG PackageId;
102 static LSA_DISPATCH_TABLE DispatchTable;
103
104
105 /* FUNCTIONS ***************************************************************/
106
107 static
108 NTSTATUS
109 NTAPI
110 LsapAddAuthPackage(IN PWSTR ValueName,
111 IN ULONG ValueType,
112 IN PVOID ValueData,
113 IN ULONG ValueLength,
114 IN PVOID Context,
115 IN PVOID EntryContext)
116 {
117 PAUTH_PACKAGE Package = NULL;
118 UNICODE_STRING PackageName;
119 STRING ProcName;
120 PULONG Id;
121 NTSTATUS Status = STATUS_SUCCESS;
122
123 TRACE("LsapAddAuthPackage()\n");
124
125 PackageName.Length = (USHORT)ValueLength - sizeof(WCHAR);
126 PackageName.MaximumLength = (USHORT)ValueLength;
127 PackageName.Buffer = ValueData;
128
129 Id = (PULONG)Context;
130
131 Package = RtlAllocateHeap(RtlGetProcessHeap(),
132 HEAP_ZERO_MEMORY,
133 sizeof(AUTH_PACKAGE));
134 if (Package == NULL)
135 return STATUS_INSUFFICIENT_RESOURCES;
136
137 Status = LdrLoadDll(NULL,
138 NULL,
139 &PackageName,
140 &Package->ModuleHandle);
141 if (!NT_SUCCESS(Status))
142 {
143 TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status);
144 goto done;
145 }
146
147 RtlInitAnsiString(&ProcName, "LsaApInitializePackage");
148 Status = LdrGetProcedureAddress(Package->ModuleHandle,
149 &ProcName,
150 0,
151 (PVOID *)&Package->LsaApInitializePackage);
152 if (!NT_SUCCESS(Status))
153 {
154 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
155 goto done;
156 }
157
158 RtlInitAnsiString(&ProcName, "LsaApCallPackage");
159 Status = LdrGetProcedureAddress(Package->ModuleHandle,
160 &ProcName,
161 0,
162 (PVOID *)&Package->LsaApCallPackage);
163 if (!NT_SUCCESS(Status))
164 {
165 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
166 goto done;
167 }
168
169 RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough");
170 Status = LdrGetProcedureAddress(Package->ModuleHandle,
171 &ProcName,
172 0,
173 (PVOID *)&Package->LsaApCallPackagePassthrough);
174 if (!NT_SUCCESS(Status))
175 {
176 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
177 goto done;
178 }
179
180 RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted");
181 Status = LdrGetProcedureAddress(Package->ModuleHandle,
182 &ProcName,
183 0,
184 (PVOID *)&Package->LsaApCallPackageUntrusted);
185 if (!NT_SUCCESS(Status))
186 {
187 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
188 goto done;
189 }
190
191 RtlInitAnsiString(&ProcName, "LsaApLogonTerminated");
192 Status = LdrGetProcedureAddress(Package->ModuleHandle,
193 &ProcName,
194 0,
195 (PVOID *)&Package->LsaApLogonTerminated);
196 if (!NT_SUCCESS(Status))
197 {
198 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
199 goto done;
200 }
201
202 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2");
203 Status = LdrGetProcedureAddress(Package->ModuleHandle,
204 &ProcName,
205 0,
206 (PVOID *)&Package->LsaApLogonUserEx2);
207 if (!NT_SUCCESS(Status))
208 {
209 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx");
210 Status = LdrGetProcedureAddress(Package->ModuleHandle,
211 &ProcName,
212 0,
213 (PVOID *)&Package->LsaApLogonUserEx);
214 if (!NT_SUCCESS(Status))
215 {
216 RtlInitAnsiString(&ProcName, "LsaApLogonUser");
217 Status = LdrGetProcedureAddress(Package->ModuleHandle,
218 &ProcName,
219 0,
220 (PVOID *)&Package->LsaApLogonUser);
221 if (!NT_SUCCESS(Status))
222 {
223 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status);
224 goto done;
225 }
226 }
227 }
228
229 /* Initialize the current package */
230 Status = Package->LsaApInitializePackage(*Id,
231 &DispatchTable,
232 NULL,
233 NULL,
234 &Package->Name);
235 if (!NT_SUCCESS(Status))
236 {
237 TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status);
238 goto done;
239 }
240
241 TRACE("Package Name: %s\n", Package->Name->Buffer);
242
243 Package->Id = *Id;
244 (*Id)++;
245
246 InsertTailList(&PackageListHead, &Package->Entry);
247
248 done:
249 if (!NT_SUCCESS(Status))
250 {
251 if (Package != NULL)
252 {
253 if (Package->ModuleHandle != NULL)
254 LdrUnloadDll(Package->ModuleHandle);
255
256 if (Package->Name != NULL)
257 {
258 if (Package->Name->Buffer != NULL)
259 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer);
260
261 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name);
262 }
263
264 RtlFreeHeap(RtlGetProcessHeap(), 0, Package);
265 }
266 }
267
268 return Status;
269 }
270
271
272 static
273 PAUTH_PACKAGE
274 LsapGetAuthenticationPackage(IN ULONG PackageId)
275 {
276 PLIST_ENTRY ListEntry;
277 PAUTH_PACKAGE Package;
278
279 ListEntry = PackageListHead.Flink;
280 while (ListEntry != &PackageListHead)
281 {
282 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
283
284 if (Package->Id == PackageId)
285 {
286 return Package;
287 }
288
289 ListEntry = ListEntry->Flink;
290 }
291
292 return NULL;
293 }
294
295
296 static
297 PVOID
298 NTAPI
299 LsapAllocateHeap(IN ULONG Length)
300 {
301 return RtlAllocateHeap(RtlGetProcessHeap(),
302 HEAP_ZERO_MEMORY,
303 Length);
304 }
305
306
307 static
308 VOID
309 NTAPI
310 LsapFreeHeap(IN PVOID Base)
311 {
312 RtlFreeHeap(RtlGetProcessHeap(),
313 0,
314 Base);
315 }
316
317
318 static
319 NTSTATUS
320 NTAPI
321 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
322 IN ULONG LengthRequired,
323 OUT PVOID *ClientBaseAddress)
324 {
325 PLSAP_LOGON_CONTEXT LogonContext;
326 ULONG Length;
327
328 *ClientBaseAddress = NULL;
329
330 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
331
332 Length = LengthRequired;
333 return NtAllocateVirtualMemory(LogonContext->ClientProcessHandle,
334 ClientBaseAddress,
335 0,
336 &Length,
337 MEM_COMMIT,
338 PAGE_READWRITE);
339 }
340
341
342 static
343 NTSTATUS
344 NTAPI
345 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
346 IN PVOID ClientBaseAddress)
347 {
348 PLSAP_LOGON_CONTEXT LogonContext;
349 ULONG Length;
350
351 if (ClientBaseAddress == NULL)
352 return STATUS_SUCCESS;
353
354 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
355
356 Length = 0;
357 return NtFreeVirtualMemory(LogonContext->ClientProcessHandle,
358 &ClientBaseAddress,
359 &Length,
360 MEM_RELEASE);
361 }
362
363
364 static
365 NTSTATUS
366 NTAPI
367 LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
368 IN ULONG Length,
369 IN PVOID ClientBaseAddress,
370 IN PVOID BufferToCopy)
371 {
372 PLSAP_LOGON_CONTEXT LogonContext;
373
374 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
375
376 return NtWriteVirtualMemory(LogonContext->ClientProcessHandle,
377 ClientBaseAddress,
378 BufferToCopy,
379 Length,
380 NULL);
381 }
382
383
384 static
385 NTSTATUS
386 NTAPI
387 LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest,
388 IN ULONG Length,
389 IN PVOID BufferToCopy,
390 IN PVOID ClientBaseAddress)
391 {
392 PLSAP_LOGON_CONTEXT LogonContext;
393
394 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest;
395
396 return NtReadVirtualMemory(LogonContext->ClientProcessHandle,
397 ClientBaseAddress,
398 BufferToCopy,
399 Length,
400 NULL);
401 }
402
403
404 NTSTATUS
405 LsapInitAuthPackages(VOID)
406 {
407 RTL_QUERY_REGISTRY_TABLE AuthPackageTable[] = {
408 {LsapAddAuthPackage, 0, L"Authentication Packages", NULL, REG_NONE, NULL, 0},
409 {NULL, 0, NULL, NULL, REG_NONE, NULL, 0}};
410
411 NTSTATUS Status;
412
413 InitializeListHead(&PackageListHead);
414 PackageId = 0;
415
416 /* Initialize the dispatch table */
417 DispatchTable.CreateLogonSession = &LsapCreateLogonSession;
418 DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession;
419 DispatchTable.AddCredential = NULL;
420 DispatchTable.GetCredentials = NULL;
421 DispatchTable.DeleteCredential = NULL;
422 DispatchTable.AllocateLsaHeap = &LsapAllocateHeap;
423 DispatchTable.FreeLsaHeap = &LsapFreeHeap;
424 DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer;
425 DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer;
426 DispatchTable.CopyToClientBuffer = &LsapCopyToClientBuffer;
427 DispatchTable.CopyFromClientBuffer = &LsapCopyFromClientBuffer;
428
429 /* Add registered authentication packages */
430 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
431 L"Lsa",
432 AuthPackageTable,
433 &PackageId,
434 NULL);
435
436 return Status;
437 }
438
439
440 NTSTATUS
441 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg,
442 PLSAP_LOGON_CONTEXT LogonContext)
443 {
444 PLIST_ENTRY ListEntry;
445 PAUTH_PACKAGE Package;
446 ULONG PackageNameLength;
447 PCHAR PackageName;
448
449 TRACE("(%p %p)\n", RequestMsg, LogonContext);
450
451 PackageNameLength = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength;
452 PackageName = RequestMsg->LookupAuthenticationPackage.Request.PackageName;
453
454 TRACE("PackageName: %s\n", PackageName);
455
456 ListEntry = PackageListHead.Flink;
457 while (ListEntry != &PackageListHead)
458 {
459 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry);
460
461 if ((PackageNameLength == Package->Name->Length) &&
462 (_strnicmp(PackageName, Package->Name->Buffer, Package->Name->Length) == 0))
463 {
464 RequestMsg->LookupAuthenticationPackage.Reply.Package = Package->Id;
465 return STATUS_SUCCESS;
466 }
467
468 ListEntry = ListEntry->Flink;
469 }
470
471 return STATUS_NO_SUCH_PACKAGE;
472 }
473
474
475 NTSTATUS
476 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg,
477 PLSAP_LOGON_CONTEXT LogonContext)
478 {
479 PAUTH_PACKAGE Package;
480 PVOID LocalBuffer = NULL;
481 ULONG PackageId;
482 NTSTATUS Status;
483
484 TRACE("(%p %p)\n", RequestMsg, LogonContext);
485
486 PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage;
487
488 /* Get the right authentication package */
489 Package = LsapGetAuthenticationPackage(PackageId);
490 if (Package == NULL)
491 {
492 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
493 return STATUS_NO_SUCH_PACKAGE;
494 }
495
496 if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0)
497 {
498 LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
499 HEAP_ZERO_MEMORY,
500 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength);
501 if (LocalBuffer == NULL)
502 {
503 return STATUS_INSUFFICIENT_RESOURCES;
504 }
505
506 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
507 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
508 LocalBuffer,
509 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
510 NULL);
511 if (!NT_SUCCESS(Status))
512 {
513 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
514 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
515 return Status;
516 }
517 }
518
519 Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext,
520 LocalBuffer,
521 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer,
522 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength,
523 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer,
524 &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength,
525 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus);
526 if (!NT_SUCCESS(Status))
527 {
528 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status);
529 }
530
531 if (LocalBuffer != NULL)
532 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
533
534 return Status;
535 }
536
537
538 static
539 NTSTATUS
540 LsapCopyLocalGroups(
541 IN PLSAP_LOGON_CONTEXT LogonContext,
542 IN PTOKEN_GROUPS ClientGroups,
543 IN ULONG ClientGroupsCount,
544 OUT PTOKEN_GROUPS *TokenGroups)
545 {
546 ULONG LocalGroupsLength = 0;
547 PTOKEN_GROUPS LocalGroups = NULL;
548 ULONG SidHeaderLength = 0;
549 PSID SidHeader = NULL;
550 PSID SrcSid, DstSid;
551 ULONG SidLength;
552 ULONG AllocatedSids = 0;
553 ULONG i;
554 NTSTATUS Status;
555
556 LocalGroupsLength = sizeof(TOKEN_GROUPS) +
557 (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
558 LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
559 HEAP_ZERO_MEMORY,
560 LocalGroupsLength);
561 if (LocalGroups == NULL)
562 {
563 TRACE("RtlAllocateHeap() failed\n");
564 return STATUS_INSUFFICIENT_RESOURCES;
565 }
566
567 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
568 ClientGroups,
569 LocalGroups,
570 LocalGroupsLength,
571 NULL);
572 if (!NT_SUCCESS(Status))
573 goto done;
574
575
576 SidHeaderLength = RtlLengthRequiredSid(0);
577 SidHeader = RtlAllocateHeap(RtlGetProcessHeap(),
578 HEAP_ZERO_MEMORY,
579 SidHeaderLength);
580 if (SidHeader == NULL)
581 {
582 Status = STATUS_INSUFFICIENT_RESOURCES;
583 goto done;
584 }
585
586 for (i = 0; i < ClientGroupsCount; i++)
587 {
588 SrcSid = LocalGroups->Groups[i].Sid;
589
590 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
591 SrcSid,
592 SidHeader,
593 SidHeaderLength,
594 NULL);
595 if (!NT_SUCCESS(Status))
596 goto done;
597
598 SidLength = RtlLengthSid(SidHeader);
599 TRACE("Sid %lu: Length %lu\n", i, SidLength);
600
601 DstSid = RtlAllocateHeap(RtlGetProcessHeap(),
602 HEAP_ZERO_MEMORY,
603 SidLength);
604 if (DstSid == NULL)
605 {
606 Status = STATUS_INSUFFICIENT_RESOURCES;
607 goto done;
608 }
609
610 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
611 SrcSid,
612 DstSid,
613 SidLength,
614 NULL);
615 if (!NT_SUCCESS(Status))
616 {
617 RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid);
618 goto done;
619 }
620
621 LocalGroups->Groups[i].Sid = DstSid;
622 AllocatedSids++;
623 }
624
625 *TokenGroups = LocalGroups;
626
627 done:
628 if (SidHeader != NULL)
629 RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader);
630
631 if (!NT_SUCCESS(Status))
632 {
633 if (LocalGroups != NULL)
634 {
635 for (i = 0; i < AllocatedSids; i++)
636 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
637
638 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
639 }
640 }
641
642 return Status;
643 }
644
645
646 static
647 NTSTATUS
648 LsapSetTokenOwner(
649 IN PVOID TokenInformation,
650 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
651 {
652 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
653 PSID OwnerSid = NULL;
654 ULONG i, Length;
655
656 if (TokenInformationType == LsaTokenInformationV1)
657 {
658 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
659
660 if (TokenInfo1->Owner.Owner != NULL)
661 return STATUS_SUCCESS;
662
663 OwnerSid = TokenInfo1->User.User.Sid;
664 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
665 {
666 if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid))
667 {
668 OwnerSid = LsapAdministratorsSid;
669 break;
670 }
671 }
672
673 Length = RtlLengthSid(OwnerSid);
674 TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length);
675 if (TokenInfo1->Owner.Owner == NULL)
676 return STATUS_INSUFFICIENT_RESOURCES;
677
678 RtlCopyMemory(TokenInfo1->Owner.Owner,
679 OwnerSid,
680 Length);
681 }
682
683 return STATUS_SUCCESS;
684 }
685
686
687 static
688 NTSTATUS
689 LsapAddTokenDefaultDacl(
690 IN PVOID TokenInformation,
691 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
692 {
693 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
694 PACL Dacl = NULL;
695 ULONG Length;
696
697 if (TokenInformationType == LsaTokenInformationV1)
698 {
699 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
700
701 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
702 return STATUS_SUCCESS;
703
704 Length = sizeof(ACL) +
705 (2 * sizeof(ACCESS_ALLOWED_ACE)) +
706 RtlLengthSid(TokenInfo1->Owner.Owner) +
707 RtlLengthSid(LsapLocalSystemSid);
708
709 Dacl = DispatchTable.AllocateLsaHeap(Length);
710 if (Dacl == NULL)
711 return STATUS_INSUFFICIENT_RESOURCES;
712
713 RtlCreateAcl(Dacl, Length, ACL_REVISION);
714
715 RtlAddAccessAllowedAce(Dacl,
716 ACL_REVISION,
717 GENERIC_ALL,
718 TokenInfo1->Owner.Owner);
719
720 /* SID: S-1-5-18 */
721 RtlAddAccessAllowedAce(Dacl,
722 ACL_REVISION,
723 GENERIC_ALL,
724 LsapLocalSystemSid);
725
726 TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
727 }
728
729 return STATUS_SUCCESS;
730 }
731
732
733 NTSTATUS
734 LsapLogonUser(PLSA_API_MSG RequestMsg,
735 PLSAP_LOGON_CONTEXT LogonContext)
736 {
737 PAUTH_PACKAGE Package;
738 OBJECT_ATTRIBUTES ObjectAttributes;
739 SECURITY_QUALITY_OF_SERVICE Qos;
740 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
741 PVOID TokenInformation = NULL;
742 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
743 PUNICODE_STRING AccountName = NULL;
744 PUNICODE_STRING AuthenticatingAuthority = NULL;
745 PUNICODE_STRING MachineName = NULL;
746 PVOID LocalAuthInfo = NULL;
747 PTOKEN_GROUPS LocalGroups = NULL;
748 HANDLE TokenHandle = NULL;
749 ULONG i;
750 ULONG PackageId;
751 NTSTATUS Status;
752
753 TRACE("(%p %p)\n", RequestMsg, LogonContext);
754
755 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
756
757 /* Get the right authentication package */
758 Package = LsapGetAuthenticationPackage(PackageId);
759 if (Package == NULL)
760 {
761 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
762 return STATUS_NO_SUCH_PACKAGE;
763 }
764
765 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
766 {
767 /* Allocate the local authentication info buffer */
768 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
769 HEAP_ZERO_MEMORY,
770 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
771 if (LocalAuthInfo == NULL)
772 {
773 ERR("RtlAllocateHeap() failed\n");
774 return STATUS_INSUFFICIENT_RESOURCES;
775 }
776
777 /* Read the authentication info from the callers adress space */
778 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
779 RequestMsg->LogonUser.Request.AuthenticationInformation,
780 LocalAuthInfo,
781 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
782 NULL);
783 if (!NT_SUCCESS(Status))
784 {
785 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
786 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
787 return Status;
788 }
789 }
790
791 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
792 {
793 Status = LsapCopyLocalGroups(LogonContext,
794 RequestMsg->LogonUser.Request.LocalGroups,
795 RequestMsg->LogonUser.Request.LocalGroupsCount,
796 &LocalGroups);
797 if (!NT_SUCCESS(Status))
798 {
799 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
800 goto done;
801 }
802
803 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
804 }
805
806 if (Package->LsaApLogonUserEx2 != NULL)
807 {
808 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
809 RequestMsg->LogonUser.Request.LogonType,
810 LocalAuthInfo,
811 RequestMsg->LogonUser.Request.AuthenticationInformation,
812 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
813 &RequestMsg->LogonUser.Reply.ProfileBuffer,
814 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
815 &RequestMsg->LogonUser.Reply.LogonId,
816 &RequestMsg->LogonUser.Reply.SubStatus,
817 &TokenInformationType,
818 &TokenInformation,
819 &AccountName,
820 &AuthenticatingAuthority,
821 &MachineName,
822 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
823 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
824 }
825 else if (Package->LsaApLogonUserEx != NULL)
826 {
827 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
828 RequestMsg->LogonUser.Request.LogonType,
829 LocalAuthInfo,
830 RequestMsg->LogonUser.Request.AuthenticationInformation,
831 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
832 &RequestMsg->LogonUser.Reply.ProfileBuffer,
833 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
834 &RequestMsg->LogonUser.Reply.LogonId,
835 &RequestMsg->LogonUser.Reply.SubStatus,
836 &TokenInformationType,
837 &TokenInformation,
838 &AccountName,
839 &AuthenticatingAuthority,
840 &MachineName);
841 }
842 else
843 {
844 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
845 RequestMsg->LogonUser.Request.LogonType,
846 LocalAuthInfo,
847 RequestMsg->LogonUser.Request.AuthenticationInformation,
848 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
849 &RequestMsg->LogonUser.Reply.ProfileBuffer,
850 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
851 &RequestMsg->LogonUser.Reply.LogonId,
852 &RequestMsg->LogonUser.Reply.SubStatus,
853 &TokenInformationType,
854 &TokenInformation,
855 &AccountName,
856 &AuthenticatingAuthority);
857 }
858
859 if (!NT_SUCCESS(Status))
860 {
861 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
862 goto done;
863 }
864
865 Status = LsapSetTokenOwner(TokenInformation,
866 TokenInformationType);
867 if (!NT_SUCCESS(Status))
868 {
869 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status);
870 goto done;
871 }
872
873 Status = LsapAddTokenDefaultDacl(TokenInformation,
874 TokenInformationType);
875 if (!NT_SUCCESS(Status))
876 {
877 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
878 goto done;
879 }
880
881 if (TokenInformationType == LsaTokenInformationV1)
882 {
883 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
884
885 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
886 Qos.ImpersonationLevel = SecurityImpersonation;
887 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
888 Qos.EffectiveOnly = FALSE;
889
890 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
891 ObjectAttributes.RootDirectory = NULL;
892 ObjectAttributes.ObjectName = NULL;
893 ObjectAttributes.Attributes = 0;
894 ObjectAttributes.SecurityDescriptor = NULL;
895 ObjectAttributes.SecurityQualityOfService = &Qos;
896
897 /* Create the logon token */
898 Status = NtCreateToken(&TokenHandle,
899 TOKEN_ALL_ACCESS,
900 &ObjectAttributes,
901 TokenPrimary,
902 &RequestMsg->LogonUser.Reply.LogonId,
903 &TokenInfo1->ExpirationTime,
904 &TokenInfo1->User,
905 TokenInfo1->Groups,
906 TokenInfo1->Privileges,
907 &TokenInfo1->Owner,
908 &TokenInfo1->PrimaryGroup,
909 &TokenInfo1->DefaultDacl,
910 &RequestMsg->LogonUser.Request.SourceContext);
911 if (!NT_SUCCESS(Status))
912 {
913 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
914 goto done;
915 }
916 }
917 else
918 {
919 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
920 Status = STATUS_NOT_IMPLEMENTED;
921 goto done;
922 }
923
924 /* Duplicate the token handle into the client process */
925 Status = NtDuplicateObject(NtCurrentProcess(),
926 TokenHandle,
927 LogonContext->ClientProcessHandle,
928 &RequestMsg->LogonUser.Reply.Token,
929 0,
930 0,
931 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
932 if (!NT_SUCCESS(Status))
933 {
934 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
935 goto done;
936 }
937
938 TokenHandle = NULL;
939
940 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
941 if (!NT_SUCCESS(Status))
942 {
943 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
944 goto done;
945 }
946
947 done:
948 if (!NT_SUCCESS(Status))
949 {
950 if (TokenHandle != NULL)
951 NtClose(TokenHandle);
952 }
953
954 /* Free the local groups */
955 if (LocalGroups != NULL)
956 {
957 for (i = 0; i < LocalGroups->GroupCount; i++)
958 {
959 if (LocalGroups->Groups[i].Sid != NULL)
960 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
961 }
962
963 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
964 }
965
966 /* Free the local authentication info buffer */
967 if (LocalAuthInfo != NULL)
968 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
969
970 /* Free the token information */
971 if (TokenInformation != NULL)
972 {
973 if (TokenInformationType == LsaTokenInformationV1)
974 {
975 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
976
977 if (TokenInfo1 != NULL)
978 {
979 if (TokenInfo1->User.User.Sid != NULL)
980 LsapFreeHeap(TokenInfo1->User.User.Sid);
981
982 if (TokenInfo1->Groups != NULL)
983 {
984 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
985 {
986 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
987 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
988 }
989
990 LsapFreeHeap(TokenInfo1->Groups);
991 }
992
993 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
994 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
995
996 if (TokenInfo1->Privileges != NULL)
997 LsapFreeHeap(TokenInfo1->Privileges);
998
999 if (TokenInfo1->Owner.Owner != NULL)
1000 LsapFreeHeap(TokenInfo1->Owner.Owner);
1001
1002 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
1003 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
1004
1005 LsapFreeHeap(TokenInfo1);
1006 }
1007 }
1008 else
1009 {
1010 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
1011 }
1012 }
1013
1014 /* Free the account name */
1015 if (AccountName != NULL)
1016 {
1017 if (AccountName->Buffer != NULL)
1018 LsapFreeHeap(AccountName->Buffer);
1019
1020 LsapFreeHeap(AccountName);
1021 }
1022
1023 /* Free the authentication authority */
1024 if (AuthenticatingAuthority != NULL)
1025 {
1026 if (AuthenticatingAuthority != NULL)
1027 LsapFreeHeap(AuthenticatingAuthority->Buffer);
1028
1029 LsapFreeHeap(AuthenticatingAuthority);
1030 }
1031
1032 /* Free the machine name */
1033 if (MachineName != NULL)
1034 {
1035 if (MachineName->Buffer != NULL)
1036 LsapFreeHeap(MachineName->Buffer);
1037
1038 LsapFreeHeap(MachineName);
1039 }
1040
1041 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
1042
1043 return Status;
1044 }
1045
1046 /* EOF */