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