[LSASRV]
[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 NTSTATUS Status;
553
554 LocalGroupsLength = sizeof(TOKEN_GROUPS) +
555 (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES);
556 LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(),
557 HEAP_ZERO_MEMORY,
558 LocalGroupsLength);
559 if (LocalGroups == NULL)
560 {
561 TRACE("RtlAllocateHeap() failed\n");
562 return STATUS_INSUFFICIENT_RESOURCES;
563 }
564
565 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
566 ClientGroups,
567 LocalGroups,
568 LocalGroupsLength,
569 NULL);
570 if (!NT_SUCCESS(Status))
571 goto done;
572
573 *TokenGroups = LocalGroups;
574
575 done:
576 if (!NT_SUCCESS(Status))
577 {
578 if (LocalGroups != NULL)
579 {
580 RtlFreeHeap(RtlGetProcessHeap(),
581 0,
582 LocalGroups);
583 }
584 }
585
586 return Status;
587 }
588
589
590 NTSTATUS
591 LsapLogonUser(PLSA_API_MSG RequestMsg,
592 PLSAP_LOGON_CONTEXT LogonContext)
593 {
594 PAUTH_PACKAGE Package;
595 OBJECT_ATTRIBUTES ObjectAttributes;
596 SECURITY_QUALITY_OF_SERVICE Qos;
597 LSA_TOKEN_INFORMATION_TYPE TokenInformationType;
598 PVOID TokenInformation = NULL;
599 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL;
600 PUNICODE_STRING AccountName = NULL;
601 PUNICODE_STRING AuthenticatingAuthority = NULL;
602 PUNICODE_STRING MachineName = NULL;
603 PVOID LocalAuthInfo = NULL;
604 PTOKEN_GROUPS LocalGroups = NULL;
605 HANDLE TokenHandle = NULL;
606 ULONG i;
607 ULONG PackageId;
608 NTSTATUS Status;
609
610 TRACE("(%p %p)\n", RequestMsg, LogonContext);
611
612 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage;
613
614 /* Get the right authentication package */
615 Package = LsapGetAuthenticationPackage(PackageId);
616 if (Package == NULL)
617 {
618 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
619 return STATUS_NO_SUCH_PACKAGE;
620 }
621
622 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0)
623 {
624 /* Allocate the local authentication info buffer */
625 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
626 HEAP_ZERO_MEMORY,
627 RequestMsg->LogonUser.Request.AuthenticationInformationLength);
628 if (LocalAuthInfo == NULL)
629 {
630 TRACE("RtlAllocateHeap() failed\n");
631 return STATUS_INSUFFICIENT_RESOURCES;
632 }
633
634 /* Read the authentication info from the callers adress space */
635 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle,
636 RequestMsg->LogonUser.Request.AuthenticationInformation,
637 LocalAuthInfo,
638 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
639 NULL);
640 if (!NT_SUCCESS(Status))
641 {
642 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status);
643 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
644 return Status;
645 }
646 }
647
648 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0)
649 {
650 Status = LsapCopyLocalGroups(LogonContext,
651 RequestMsg->LogonUser.Request.LocalGroups,
652 RequestMsg->LogonUser.Request.LocalGroupsCount,
653 &LocalGroups);
654 if (!NT_SUCCESS(Status))
655 goto done;
656
657 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount);
658 }
659
660 if (Package->LsaApLogonUserEx2 != NULL)
661 {
662 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext,
663 RequestMsg->LogonUser.Request.LogonType,
664 LocalAuthInfo,
665 RequestMsg->LogonUser.Request.AuthenticationInformation,
666 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
667 &RequestMsg->LogonUser.Reply.ProfileBuffer,
668 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
669 &RequestMsg->LogonUser.Reply.LogonId,
670 &RequestMsg->LogonUser.Reply.SubStatus,
671 &TokenInformationType,
672 &TokenInformation,
673 &AccountName,
674 &AuthenticatingAuthority,
675 &MachineName,
676 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
677 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
678 }
679 else if (Package->LsaApLogonUserEx != NULL)
680 {
681 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext,
682 RequestMsg->LogonUser.Request.LogonType,
683 LocalAuthInfo,
684 RequestMsg->LogonUser.Request.AuthenticationInformation,
685 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
686 &RequestMsg->LogonUser.Reply.ProfileBuffer,
687 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
688 &RequestMsg->LogonUser.Reply.LogonId,
689 &RequestMsg->LogonUser.Reply.SubStatus,
690 &TokenInformationType,
691 &TokenInformation,
692 &AccountName,
693 &AuthenticatingAuthority,
694 &MachineName);
695 }
696 else
697 {
698 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext,
699 RequestMsg->LogonUser.Request.LogonType,
700 LocalAuthInfo,
701 RequestMsg->LogonUser.Request.AuthenticationInformation,
702 RequestMsg->LogonUser.Request.AuthenticationInformationLength,
703 &RequestMsg->LogonUser.Reply.ProfileBuffer,
704 &RequestMsg->LogonUser.Reply.ProfileBufferLength,
705 &RequestMsg->LogonUser.Reply.LogonId,
706 &RequestMsg->LogonUser.Reply.SubStatus,
707 &TokenInformationType,
708 &TokenInformation,
709 &AccountName,
710 &AuthenticatingAuthority);
711 }
712
713 if (!NT_SUCCESS(Status))
714 {
715 TRACE("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status);
716 goto done;
717 }
718
719 if (TokenInformationType == LsaTokenInformationV1)
720 {
721 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
722
723 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
724 Qos.ImpersonationLevel = SecurityImpersonation;
725 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
726 Qos.EffectiveOnly = FALSE;
727
728 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
729 ObjectAttributes.RootDirectory = NULL;
730 ObjectAttributes.ObjectName = NULL;
731 ObjectAttributes.Attributes = 0;
732 ObjectAttributes.SecurityDescriptor = NULL;
733 ObjectAttributes.SecurityQualityOfService = &Qos;
734
735 /* Create the logon token */
736 Status = NtCreateToken(&TokenHandle,
737 TOKEN_ALL_ACCESS,
738 &ObjectAttributes,
739 TokenPrimary,
740 &RequestMsg->LogonUser.Reply.LogonId,
741 &TokenInfo1->ExpirationTime,
742 &TokenInfo1->User,
743 TokenInfo1->Groups,
744 TokenInfo1->Privileges,
745 &TokenInfo1->Owner,
746 &TokenInfo1->PrimaryGroup,
747 &TokenInfo1->DefaultDacl,
748 &RequestMsg->LogonUser.Request.SourceContext);
749 if (!NT_SUCCESS(Status))
750 {
751 TRACE("NtCreateToken failed (Status 0x%08lx)\n", Status);
752 goto done;
753 }
754 }
755 else
756 {
757 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
758 Status = STATUS_NOT_IMPLEMENTED;
759 goto done;
760 }
761
762 /* Duplicate the token handle into the client process */
763 Status = NtDuplicateObject(NtCurrentProcess(),
764 TokenHandle,
765 LogonContext->ClientProcessHandle,
766 &RequestMsg->LogonUser.Reply.Token,
767 0,
768 0,
769 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE);
770 if (!NT_SUCCESS(Status))
771 {
772 TRACE("NtDuplicateObject failed (Status 0x%08lx)\n", Status);
773 goto done;
774 }
775
776 TokenHandle = NULL;
777
778 done:
779 if (!NT_SUCCESS(Status))
780 {
781 if (TokenHandle != NULL)
782 NtClose(TokenHandle);
783 }
784
785 /* Free the local groups */
786 if (LocalGroups != NULL)
787 {
788 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups);
789 }
790
791 /* Free the local authentication info buffer */
792 if (LocalAuthInfo != NULL)
793 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo);
794
795 /* Free the token information */
796 if (TokenInformation != NULL)
797 {
798 if (TokenInformationType == LsaTokenInformationV1)
799 {
800 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
801
802 if (TokenInfo1 != NULL)
803 {
804 if (TokenInfo1->User.User.Sid != NULL)
805 LsapFreeHeap(TokenInfo1->User.User.Sid);
806
807 if (TokenInfo1->Groups != NULL)
808 {
809 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
810 {
811 if (TokenInfo1->Groups->Groups[i].Sid != NULL)
812 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid);
813 }
814
815 LsapFreeHeap(TokenInfo1->Groups);
816 }
817
818 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL)
819 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup);
820
821 if (TokenInfo1->Privileges != NULL)
822 LsapFreeHeap(TokenInfo1->Privileges);
823
824 if (TokenInfo1->Owner.Owner != NULL)
825 LsapFreeHeap(TokenInfo1->Owner.Owner);
826
827 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL)
828 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl);
829
830 LsapFreeHeap(TokenInfo1);
831 }
832 }
833 else
834 {
835 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType);
836 }
837 }
838
839 /* Free the account name */
840 if (AccountName != NULL)
841 {
842 if (AccountName->Buffer != NULL)
843 LsapFreeHeap(AccountName->Buffer);
844
845 LsapFreeHeap(AccountName);
846 }
847
848 /* Free the authentication authority */
849 if (AuthenticatingAuthority != NULL)
850 {
851 if (AuthenticatingAuthority != NULL)
852 LsapFreeHeap(AuthenticatingAuthority->Buffer);
853
854 LsapFreeHeap(AuthenticatingAuthority);
855 }
856
857 /* Free the machine name */
858 if (MachineName != NULL)
859 {
860 if (MachineName->Buffer != NULL)
861 LsapFreeHeap(MachineName->Buffer);
862
863 LsapFreeHeap(MachineName);
864 }
865
866 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status);
867
868 return Status;
869 }
870
871 /* EOF */