6eea470e30e5124b5a2d6f9d553636fdf18c925e
[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 LsapAddTokenDefaultDacl(
649 IN PVOID TokenInformation,
650 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
651 {
652 PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
653 PACL Dacl = NULL;
654 ULONG Length;
655
656 if (TokenInformationType == LsaTokenInformationV1)
657 {
658 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
659
660 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
661 return STATUS_SUCCESS;
662
663 Length = sizeof(ACL) +
664 (2 * sizeof(ACCESS_ALLOWED_ACE)) +
665 RtlLengthSid(TokenInfo1->Owner.Owner) +
666 RtlLengthSid(LsapLocalSystemSid);
667
668 Dacl = DispatchTable.AllocateLsaHeap(Length);
669 if (Dacl == NULL)
670 return STATUS_INSUFFICIENT_RESOURCES;
671
672 RtlCreateAcl(Dacl, Length, ACL_REVISION);
673
674 RtlAddAccessAllowedAce(Dacl,
675 ACL_REVISION,
676 GENERIC_ALL,
677 TokenInfo1->Owner.Owner);
678
679 /* SID: S-1-5-18 */
680 RtlAddAccessAllowedAce(Dacl,
681 ACL_REVISION,
682 GENERIC_ALL,
683 LsapLocalSystemSid);
684
685 TokenInfo1->DefaultDacl.DefaultDacl = Dacl;
686 }
687
688 return STATUS_SUCCESS;
689 }
690
691
692 NTSTATUS
693 LsapLogonUser(PLSA_API_MSG RequestMsg,
694 PLSAP_LOGON_CONTEXT LogonContext)
695 {
696 PAUTH_PACKAGE Package;
697 OBJECT_ATTRIBUTES ObjectAttributes;
698 SECURITY_QUALITY_OF_SERVICE Qos;
699 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
700 PVOID TokenInformation = NULL;
701 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
702 PUNICODE_STRING AccountName = NULL;
703 PUNICODE_STRING AuthenticatingAuthority = NULL;
704 PUNICODE_STRING MachineName = NULL;
705 PVOID LocalAuthInfo = NULL;
706 PTOKEN_GROUPS LocalGroups = NULL;
707 HANDLE TokenHandle = NULL;
708 ULONG i;
709 ULONG PackageId;
710 NTSTATUS Status;
711
712 TRACE("(%p %p)\n", RequestMsg, LogonContext);
713
714 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
715
716 /* Get the right authentication package */
717 Package = LsapGetAuthenticationPackage(PackageId);
718 if (Package == NULL)
719 {
720 ERR("LsapGetAuthenticationPackage() failed to find a package\n");
721 return STATUS_NO_SUCH_PACKAGE;
722 }
723
724 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
725 {
726 /* Allocate the local authentication info buffer */
727 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
728 HEAP_ZERO_MEMORY,
729 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
730 if (LocalAuthInfo == NULL)
731 {
732 ERR("RtlAllocateHeap() failed\n");
733 return STATUS_INSUFFICIENT_RESOURCES;
734 }
735
736 /* Read the authentication info from the callers adress space */
737 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
738 RequestMsg->LogonUser.Request.AuthenticationInformation,
739 LocalAuthInfo,
740 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
741 NULL);
742 if (!NT_SUCCESS(Status))
743 {
744 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
745 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
746 return Status;
747 }
748 }
749
750 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
751 {
752 Status = LsapCopyLocalGroups(LogonContext,
753 RequestMsg->LogonUser.Request.LocalGroups,
754 RequestMsg->LogonUser.Request.LocalGroupsCount,
755 &LocalGroups);
756 if (!NT_SUCCESS(Status))
757 {
758 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status);
759 goto done;
760 }
761
762 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
763 }
764
765 if (Package->LsaApLogonUserEx2 != NULL)
766 {
767 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
768 RequestMsg->LogonUser.Request.LogonType,
769 LocalAuthInfo,
770 RequestMsg->LogonUser.Request.AuthenticationInformation,
771 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
772 &RequestMsg->LogonUser.Reply.ProfileBuffer,
773 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
774 &RequestMsg->LogonUser.Reply.LogonId,
775 &RequestMsg->LogonUser.Reply.SubStatus,
776 &TokenInformationType,
777 &TokenInformation,
778 &AccountName,
779 &AuthenticatingAuthority,
780 &MachineName,
781 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
782 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
783 }
784 else if (Package->LsaApLogonUserEx != NULL)
785 {
786 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
787 RequestMsg->LogonUser.Request.LogonType,
788 LocalAuthInfo,
789 RequestMsg->LogonUser.Request.AuthenticationInformation,
790 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
791 &RequestMsg->LogonUser.Reply.ProfileBuffer,
792 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
793 &RequestMsg->LogonUser.Reply.LogonId,
794 &RequestMsg->LogonUser.Reply.SubStatus,
795 &TokenInformationType,
796 &TokenInformation,
797 &AccountName,
798 &AuthenticatingAuthority,
799 &MachineName);
800 }
801 else
802 {
803 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
804 RequestMsg->LogonUser.Request.LogonType,
805 LocalAuthInfo,
806 RequestMsg->LogonUser.Request.AuthenticationInformation,
807 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
808 &RequestMsg->LogonUser.Reply.ProfileBuffer,
809 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
810 &RequestMsg->LogonUser.Reply.LogonId,
811 &RequestMsg->LogonUser.Reply.SubStatus,
812 &TokenInformationType,
813 &TokenInformation,
814 &AccountName,
815 &AuthenticatingAuthority);
816 }
817
818 if (!NT_SUCCESS(Status))
819 {
820 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
821 goto done;
822 }
823
824
825 Status = LsapAddTokenDefaultDacl(TokenInformation,
826 TokenInformationType);
827 if (!NT_SUCCESS(Status))
828 {
829 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status);
830 goto done;
831 }
832
833 if (TokenInformationType == LsaTokenInformationV1)
834 {
835 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
836
837 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
838 Qos.ImpersonationLevel = SecurityImpersonation;
839 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
840 Qos.EffectiveOnly = FALSE;
841
842 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
843 ObjectAttributes.RootDirectory = NULL;
844 ObjectAttributes.ObjectName = NULL;
845 ObjectAttributes.Attributes = 0;
846 ObjectAttributes.SecurityDescriptor = NULL;
847 ObjectAttributes.SecurityQualityOfService = &Qos;
848
849 /* Create the logon token */
850 Status = NtCreateToken(&TokenHandle,
851 TOKEN_ALL_ACCESS,
852 &ObjectAttributes,
853 TokenPrimary,
854 &RequestMsg->LogonUser.Reply.LogonId,
855 &TokenInfo1->ExpirationTime,
856 &TokenInfo1->User,
857 TokenInfo1->Groups,
858 TokenInfo1->Privileges,
859 &TokenInfo1->Owner,
860 &TokenInfo1->PrimaryGroup,
861 &TokenInfo1->DefaultDacl,
862 &RequestMsg->LogonUser.Request.SourceContext);
863 if (!NT_SUCCESS(Status))
864 {
865 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status);
866 goto done;
867 }
868 }
869 else
870 {
871 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
872 Status = STATUS_NOT_IMPLEMENTED;
873 goto done;
874 }
875
876 /* Duplicate the token handle into the client process */
877 Status = NtDuplicateObject(NtCurrentProcess(),
878 TokenHandle,
879 LogonContext->ClientProcessHandle,
880 &RequestMsg->LogonUser.Reply.Token,
881 0,
882 0,
883 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
884 if (!NT_SUCCESS(Status))
885 {
886 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
887 goto done;
888 }
889
890 TokenHandle = NULL;
891
892 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId);
893 if (!NT_SUCCESS(Status))
894 {
895 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status);
896 goto done;
897 }
898
899 done:
900 if (!NT_SUCCESS(Status))
901 {
902 if (TokenHandle != NULL)
903 NtClose(TokenHandle);
904 }
905
906 /* Free the local groups */
907 if (LocalGroups != NULL)
908 {
909 for (i = 0; i < LocalGroups->GroupCount; i++)
910 {
911 if (LocalGroups->Groups[i].Sid != NULL)
912 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid);
913 }
914
915 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
916 }
917
918 /* Free the local authentication info buffer */
919 if (LocalAuthInfo != NULL)
920 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
921
922 /* Free the token information */
923 if (TokenInformation != NULL)
924 {
925 if (TokenInformationType == LsaTokenInformationV1)
926 {
927 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
928
929 if (TokenInfo1 != NULL)
930 {
931 if (TokenInfo1->User.User.Sid != NULL)
932 LsapFreeHeap(TokenInfo1->User.User.Sid);
933
934 if (TokenInfo1->Groups != NULL)
935 {
936 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
937 {
938 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
939 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
940 }
941
942 LsapFreeHeap(TokenInfo1->Groups);
943 }
944
945 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
946 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
947
948 if (TokenInfo1->Privileges != NULL)
949 LsapFreeHeap(TokenInfo1->Privileges);
950
951 if (TokenInfo1->Owner.Owner != NULL)
952 LsapFreeHeap(TokenInfo1->Owner.Owner);
953
954 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
955 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
956
957 LsapFreeHeap(TokenInfo1);
958 }
959 }
960 else
961 {
962 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
963 }
964 }
965
966 /* Free the account name */
967 if (AccountName != NULL)
968 {
969 if (AccountName->Buffer != NULL)
970 LsapFreeHeap(AccountName->Buffer);
971
972 LsapFreeHeap(AccountName);
973 }
974
975 /* Free the authentication authority */
976 if (AuthenticatingAuthority != NULL)
977 {
978 if (AuthenticatingAuthority != NULL)
979 LsapFreeHeap(AuthenticatingAuthority->Buffer);
980
981 LsapFreeHeap(AuthenticatingAuthority);
982 }
983
984 /* Free the machine name */
985 if (MachineName != NULL)
986 {
987 if (MachineName->Buffer != NULL)
988 LsapFreeHeap(MachineName->Buffer);
989
990 LsapFreeHeap(MachineName);
991 }
992
993 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
994
995 return Status;
996 }
997
998 /* EOF */