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
9 /* INCLUDES ****************************************************************/
13 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv
);
15 typedef enum _LSA_TOKEN_INFORMATION_TYPE
17 LsaTokenInformationNull
,
19 } LSA_TOKEN_INFORMATION_TYPE
, *PLSA_TOKEN_INFORMATION_TYPE
;
21 typedef PVOID PLSA_CLIENT_REQUEST
;
23 typedef PVOID (NTAPI
*PLSA_ALLOCATE_LSA_HEAP
)(ULONG
);
24 typedef VOID (NTAPI
*PLSA_FREE_LSA_HEAP
)(PVOID
);
25 typedef NTSTATUS (NTAPI
*PLSA_ALLOCATE_CLIENT_BUFFER
)(PLSA_CLIENT_REQUEST
, ULONG
, PVOID
*);
26 typedef NTSTATUS (NTAPI
*PLSA_FREE_CLIENT_BUFFER
)(PLSA_CLIENT_REQUEST
, PVOID
);
27 typedef NTSTATUS (NTAPI
*PLSA_COPY_TO_CLIENT_BUFFER
)(PLSA_CLIENT_REQUEST
, ULONG
,
29 typedef NTSTATUS (NTAPI
*PLSA_COPY_FROM_CLIENT_BUFFER
)(PLSA_CLIENT_REQUEST
,
32 typedef struct LSA_DISPATCH_TABLE
34 PVOID
/*PLSA_CREATE_LOGON_SESSION */ CreateLogonSession
;
35 PVOID
/*PLSA_DELETE_LOGON_SESSION */ DeleteLogonSession
;
36 PVOID
/*PLSA_ADD_CREDENTIAL */ AddCredential
;
37 PVOID
/*PLSA_GET_CREDENTIALS */ GetCredentials
;
38 PVOID
/*PLSA_DELETE_CREDENTIAL */ DeleteCredential
;
39 PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap
;
40 PLSA_FREE_LSA_HEAP FreeLsaHeap
;
41 PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer
;
42 PLSA_FREE_CLIENT_BUFFER FreeClientBuffer
;
43 PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer
;
44 PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer
;
45 } LSA_DISPATCH_TABLE
, *PLSA_DISPATCH_TABLE
;
48 typedef NTSTATUS (NTAPI
*PLSA_AP_INITIALIZE_PACKAGE
)(ULONG
, PLSA_DISPATCH_TABLE
,
49 PLSA_STRING
, PLSA_STRING
, PLSA_STRING
*);
50 typedef NTSTATUS (NTAPI
*PLSA_AP_CALL_PACKAGE_INTERNAL
)(PLSA_CLIENT_REQUEST
, PVOID
, PVOID
,
51 ULONG
, PVOID
*, PULONG
, PNTSTATUS
);
52 typedef NTSTATUS (NTAPI
*PLSA_AP_CALL_PACKAGE_PASSTHROUGH
)(PLSA_CLIENT_REQUEST
,
53 PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PNTSTATUS
);
54 typedef NTSTATUS (NTAPI
*PLSA_AP_CALL_PACKAGE_UNTRUSTED
)(PLSA_CLIENT_REQUEST
,
55 PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PNTSTATUS
);
56 typedef VOID (NTAPI
*PLSA_AP_LOGON_TERMINATED
)(PLUID
);
57 typedef NTSTATUS (NTAPI
*PLSA_AP_LOGON_USER_EX2
)(PLSA_CLIENT_REQUEST
,
58 SECURITY_LOGON_TYPE
, PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PLUID
, PNTSTATUS
,
59 PLSA_TOKEN_INFORMATION_TYPE
, PVOID
*, PUNICODE_STRING
*, PUNICODE_STRING
*,
60 PUNICODE_STRING
*, PVOID
/*PSECPKG_PRIMARY_CRED*/, PVOID
/*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/);
61 typedef NTSTATUS (NTAPI
*PLSA_AP_LOGON_USER_EX
)(PLSA_CLIENT_REQUEST
,
62 SECURITY_LOGON_TYPE
, PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PLUID
, PNTSTATUS
,
63 PLSA_TOKEN_INFORMATION_TYPE
, PVOID
*, PUNICODE_STRING
*, PUNICODE_STRING
*,
66 typedef NTSTATUS (NTAPI
*PLSA_AP_LOGON_USER_INTERNAL
)(PLSA_CLIENT_REQUEST
, SECURITY_LOGON_TYPE
,
67 PVOID
, PVOID
, ULONG
, PVOID
*, PULONG
, PLUID
, PNTSTATUS
, PLSA_TOKEN_INFORMATION_TYPE
,
68 PVOID
*, PUNICODE_STRING
*, PUNICODE_STRING
*);
70 typedef struct _AUTH_PACKAGE
77 PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage
;
78 PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage
;
79 PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough
;
80 PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted
;
81 PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated
;
82 PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2
;
83 PLSA_AP_LOGON_USER_EX LsaApLogonUserEx
;
84 PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser
;
85 } AUTH_PACKAGE
, *PAUTH_PACKAGE
;
88 /* GLOBALS *****************************************************************/
90 static LIST_ENTRY PackageListHead
;
91 static ULONG PackageId
;
92 static LSA_DISPATCH_TABLE DispatchTable
;
95 /* FUNCTIONS ***************************************************************/
100 LsapAddAuthPackage(IN PWSTR ValueName
,
103 IN ULONG ValueLength
,
105 IN PVOID EntryContext
)
107 PAUTH_PACKAGE Package
= NULL
;
108 UNICODE_STRING PackageName
;
111 NTSTATUS Status
= STATUS_SUCCESS
;
113 TRACE("LsapAddAuthPackage()\n");
115 PackageName
.Length
= (USHORT
)ValueLength
- sizeof(WCHAR
);
116 PackageName
.MaximumLength
= (USHORT
)ValueLength
;
117 PackageName
.Buffer
= ValueData
;
119 Id
= (PULONG
)Context
;
121 Package
= RtlAllocateHeap(RtlGetProcessHeap(),
123 sizeof(AUTH_PACKAGE
));
125 return STATUS_INSUFFICIENT_RESOURCES
;
127 Status
= LdrLoadDll(NULL
,
130 &Package
->ModuleHandle
);
131 if (!NT_SUCCESS(Status
))
133 TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status
);
137 RtlInitAnsiString(&ProcName
, "LsaApInitializePackage");
138 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
141 (PVOID
*)&Package
->LsaApInitializePackage
);
142 if (!NT_SUCCESS(Status
))
144 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
148 RtlInitAnsiString(&ProcName
, "LsaApCallPackage");
149 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
152 (PVOID
*)&Package
->LsaApCallPackage
);
153 if (!NT_SUCCESS(Status
))
155 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
159 RtlInitAnsiString(&ProcName
, "LsaApCallPackagePassthrough");
160 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
163 (PVOID
*)&Package
->LsaApCallPackagePassthrough
);
164 if (!NT_SUCCESS(Status
))
166 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
170 RtlInitAnsiString(&ProcName
, "LsaApCallPackageUntrusted");
171 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
174 (PVOID
*)&Package
->LsaApCallPackageUntrusted
);
175 if (!NT_SUCCESS(Status
))
177 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
181 RtlInitAnsiString(&ProcName
, "LsaApLogonTerminated");
182 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
185 (PVOID
*)&Package
->LsaApLogonTerminated
);
186 if (!NT_SUCCESS(Status
))
188 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
192 RtlInitAnsiString(&ProcName
, "LsaApLogonUserEx2");
193 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
196 (PVOID
*)&Package
->LsaApLogonUserEx2
);
197 if (!NT_SUCCESS(Status
))
199 RtlInitAnsiString(&ProcName
, "LsaApLogonUserEx");
200 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
203 (PVOID
*)&Package
->LsaApLogonUserEx
);
204 if (!NT_SUCCESS(Status
))
206 RtlInitAnsiString(&ProcName
, "LsaApLogonUser");
207 Status
= LdrGetProcedureAddress(Package
->ModuleHandle
,
210 (PVOID
*)&Package
->LsaApLogonUser
);
211 if (!NT_SUCCESS(Status
))
213 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status
);
219 /* Initialize the current package */
220 Status
= Package
->LsaApInitializePackage(*Id
,
225 if (!NT_SUCCESS(Status
))
227 TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status
);
231 TRACE("Package Name: %s\n", Package
->Name
->Buffer
);
236 InsertTailList(&PackageListHead
, &Package
->Entry
);
239 if (!NT_SUCCESS(Status
))
243 if (Package
->ModuleHandle
!= NULL
)
244 LdrUnloadDll(Package
->ModuleHandle
);
246 if (Package
->Name
!= NULL
)
248 if (Package
->Name
->Buffer
!= NULL
)
249 RtlFreeHeap(RtlGetProcessHeap(), 0, Package
->Name
->Buffer
);
251 RtlFreeHeap(RtlGetProcessHeap(), 0, Package
->Name
);
254 RtlFreeHeap(RtlGetProcessHeap(), 0, Package
);
264 LsapGetAuthenticationPackage(IN ULONG PackageId
)
266 PLIST_ENTRY ListEntry
;
267 PAUTH_PACKAGE Package
;
269 ListEntry
= PackageListHead
.Flink
;
270 while (ListEntry
!= &PackageListHead
)
272 Package
= CONTAINING_RECORD(ListEntry
, AUTH_PACKAGE
, Entry
);
274 if (Package
->Id
== PackageId
)
279 ListEntry
= ListEntry
->Flink
;
289 LsapAllocateHeap(IN ULONG Length
)
291 return RtlAllocateHeap(RtlGetProcessHeap(),
300 LsapFreeHeap(IN PVOID Base
)
302 RtlFreeHeap(RtlGetProcessHeap(),
311 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
312 IN ULONG LengthRequired
,
313 OUT PVOID
*ClientBaseAddress
)
315 PLSAP_LOGON_CONTEXT LogonContext
;
318 *ClientBaseAddress
= NULL
;
320 LogonContext
= (PLSAP_LOGON_CONTEXT
)ClientRequest
;
322 Length
= LengthRequired
;
323 return NtAllocateVirtualMemory(LogonContext
->ClientProcessHandle
,
335 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
336 IN PVOID ClientBaseAddress
)
338 PLSAP_LOGON_CONTEXT LogonContext
;
341 if (ClientBaseAddress
== NULL
)
342 return STATUS_SUCCESS
;
344 LogonContext
= (PLSAP_LOGON_CONTEXT
)ClientRequest
;
347 return NtFreeVirtualMemory(LogonContext
->ClientProcessHandle
,
357 LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
359 IN PVOID ClientBaseAddress
,
360 IN PVOID BufferToCopy
)
362 PLSAP_LOGON_CONTEXT LogonContext
;
364 LogonContext
= (PLSAP_LOGON_CONTEXT
)ClientRequest
;
366 return NtWriteVirtualMemory(LogonContext
->ClientProcessHandle
,
377 LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
379 IN PVOID BufferToCopy
,
380 IN PVOID ClientBaseAddress
)
382 PLSAP_LOGON_CONTEXT LogonContext
;
384 LogonContext
= (PLSAP_LOGON_CONTEXT
)ClientRequest
;
386 return NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
395 LsapInitAuthPackages(VOID
)
397 RTL_QUERY_REGISTRY_TABLE AuthPackageTable
[] = {
398 {LsapAddAuthPackage
, 0, L
"Authentication Packages", NULL
, REG_NONE
, NULL
, 0},
399 {NULL
, 0, NULL
, NULL
, REG_NONE
, NULL
, 0}};
403 InitializeListHead(&PackageListHead
);
406 /* Initialize the dispatch table */
407 DispatchTable
.CreateLogonSession
= NULL
;
408 DispatchTable
.DeleteLogonSession
= NULL
;
409 DispatchTable
.AddCredential
= NULL
;
410 DispatchTable
.GetCredentials
= NULL
;
411 DispatchTable
.DeleteCredential
= NULL
;
412 DispatchTable
.AllocateLsaHeap
= &LsapAllocateHeap
;
413 DispatchTable
.FreeLsaHeap
= &LsapFreeHeap
;
414 DispatchTable
.AllocateClientBuffer
= &LsapAllocateClientBuffer
;
415 DispatchTable
.FreeClientBuffer
= &LsapFreeClientBuffer
;
416 DispatchTable
.CopyToClientBuffer
= &LsapCopyToClientBuffer
;
417 DispatchTable
.CopyFromClientBuffer
= &LsapCopyFromClientBuffer
;
419 /* Add registered authentication packages */
420 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
,
427 return STATUS_SUCCESS
;
432 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg
,
433 PLSAP_LOGON_CONTEXT LogonContext
)
435 PLIST_ENTRY ListEntry
;
436 PAUTH_PACKAGE Package
;
437 ULONG PackageNameLength
;
440 TRACE("(%p %p)\n", RequestMsg
, LogonContext
);
442 PackageNameLength
= RequestMsg
->LookupAuthenticationPackage
.Request
.PackageNameLength
;
443 PackageName
= RequestMsg
->LookupAuthenticationPackage
.Request
.PackageName
;
445 TRACE("PackageName: %s\n", PackageName
);
447 ListEntry
= PackageListHead
.Flink
;
448 while (ListEntry
!= &PackageListHead
)
450 Package
= CONTAINING_RECORD(ListEntry
, AUTH_PACKAGE
, Entry
);
452 if ((PackageNameLength
== Package
->Name
->Length
) &&
453 (_strnicmp(PackageName
, Package
->Name
->Buffer
, Package
->Name
->Length
) == 0))
455 RequestMsg
->LookupAuthenticationPackage
.Reply
.Package
= Package
->Id
;
456 return STATUS_SUCCESS
;
459 ListEntry
= ListEntry
->Flink
;
462 return STATUS_NO_SUCH_PACKAGE
;
467 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg
,
468 PLSAP_LOGON_CONTEXT LogonContext
)
470 PAUTH_PACKAGE Package
;
471 PVOID LocalBuffer
= NULL
;
475 TRACE("(%p %p)\n", RequestMsg
, LogonContext
);
477 PackageId
= RequestMsg
->CallAuthenticationPackage
.Request
.AuthenticationPackage
;
479 /* Get the right authentication package */
480 Package
= LsapGetAuthenticationPackage(PackageId
);
483 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
484 return STATUS_NO_SUCH_PACKAGE
;
487 if (RequestMsg
->CallAuthenticationPackage
.Request
.SubmitBufferLength
> 0)
489 LocalBuffer
= RtlAllocateHeap(RtlGetProcessHeap(),
491 RequestMsg
->CallAuthenticationPackage
.Request
.SubmitBufferLength
);
492 if (LocalBuffer
== NULL
)
494 return STATUS_INSUFFICIENT_RESOURCES
;
497 Status
= NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
498 RequestMsg
->CallAuthenticationPackage
.Request
.ProtocolSubmitBuffer
,
500 RequestMsg
->CallAuthenticationPackage
.Request
.SubmitBufferLength
,
502 if (!NT_SUCCESS(Status
))
504 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status
);
505 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer
);
510 Status
= Package
->LsaApCallPackage((PLSA_CLIENT_REQUEST
)LogonContext
,
512 RequestMsg
->CallAuthenticationPackage
.Request
.ProtocolSubmitBuffer
,
513 RequestMsg
->CallAuthenticationPackage
.Request
.SubmitBufferLength
,
514 &RequestMsg
->CallAuthenticationPackage
.Reply
.ProtocolReturnBuffer
,
515 &RequestMsg
->CallAuthenticationPackage
.Reply
.ReturnBufferLength
,
516 &RequestMsg
->CallAuthenticationPackage
.Reply
.ProtocolStatus
);
517 if (!NT_SUCCESS(Status
))
519 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status
);
522 if (LocalBuffer
!= NULL
)
523 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer
);
530 LsapLogonUser(PLSA_API_MSG RequestMsg
,
531 PLSAP_LOGON_CONTEXT LogonContext
)
533 PAUTH_PACKAGE Package
;
537 LSA_TOKEN_INFORMATION_TYPE TokenInformationType
;
538 PVOID TokenInformation
= NULL
;
539 PUNICODE_STRING AccountName
= NULL
;
540 PUNICODE_STRING AuthenticatingAuthority
= NULL
;
541 PUNICODE_STRING MachineName
= NULL
;
543 PVOID LocalAuthInfo
= NULL
;
545 TRACE("(%p %p)\n", RequestMsg
, LogonContext
);
547 PackageId
= RequestMsg
->LogonUser
.Request
.AuthenticationPackage
;
549 /* Get the right authentication package */
550 Package
= LsapGetAuthenticationPackage(PackageId
);
553 TRACE("LsapGetAuthenticationPackage() failed to find a package\n");
554 return STATUS_NO_SUCH_PACKAGE
;
557 if (RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
> 0)
559 /* Allocat the local authentication info buffer */
560 LocalAuthInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
562 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
);
563 if (LocalAuthInfo
== NULL
)
565 TRACE("RtlAllocateHeap() failed\n");
566 return STATUS_INSUFFICIENT_RESOURCES
;
569 /* Read the authentication info from the callers adress space */
570 Status
= NtReadVirtualMemory(LogonContext
->ClientProcessHandle
,
571 RequestMsg
->LogonUser
.Request
.AuthenticationInformation
,
573 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
,
575 if (!NT_SUCCESS(Status
))
577 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status
);
578 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo
);
583 if (Package
->LsaApLogonUserEx2
!= NULL
)
585 Status
= Package
->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST
)LogonContext
,
586 RequestMsg
->LogonUser
.Request
.LogonType
,
588 RequestMsg
->LogonUser
.Request
.AuthenticationInformation
,
589 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
,
590 &RequestMsg
->LogonUser
.Reply
.ProfileBuffer
,
591 &RequestMsg
->LogonUser
.Reply
.ProfileBufferLength
,
592 &RequestMsg
->LogonUser
.Reply
.LogonId
,
593 &RequestMsg
->LogonUser
.Reply
.SubStatus
,
594 &TokenInformationType
,
597 &AuthenticatingAuthority
,
599 NULL
, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */
600 NULL
); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */
602 else if (Package
->LsaApLogonUserEx
!= NULL
)
604 Status
= Package
->LsaApLogonUserEx((PLSA_CLIENT_REQUEST
)LogonContext
,
605 RequestMsg
->LogonUser
.Request
.LogonType
,
607 RequestMsg
->LogonUser
.Request
.AuthenticationInformation
,
608 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
,
609 &RequestMsg
->LogonUser
.Reply
.ProfileBuffer
,
610 &RequestMsg
->LogonUser
.Reply
.ProfileBufferLength
,
611 &RequestMsg
->LogonUser
.Reply
.LogonId
,
612 &RequestMsg
->LogonUser
.Reply
.SubStatus
,
613 &TokenInformationType
,
616 &AuthenticatingAuthority
,
621 Status
= Package
->LsaApLogonUser((PLSA_CLIENT_REQUEST
)LogonContext
,
622 RequestMsg
->LogonUser
.Request
.LogonType
,
624 RequestMsg
->LogonUser
.Request
.AuthenticationInformation
,
625 RequestMsg
->LogonUser
.Request
.AuthenticationInformationLength
,
626 &RequestMsg
->LogonUser
.Reply
.ProfileBuffer
,
627 &RequestMsg
->LogonUser
.Reply
.ProfileBufferLength
,
628 &RequestMsg
->LogonUser
.Reply
.LogonId
,
629 &RequestMsg
->LogonUser
.Reply
.SubStatus
,
630 &TokenInformationType
,
633 &AuthenticatingAuthority
);
636 /* Free the local authentication info buffer */
637 if (LocalAuthInfo
!= NULL
)
638 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo
);
640 if (TokenInformation
!= NULL
)
645 if (AuthenticatingAuthority
!= NULL
)
650 if (AccountName
!= NULL
)
655 if (MachineName
!= NULL
)