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