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