From b5aaf7147dc3d65eb276dfbe9082fedbb66df0c4 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 4 Mar 2013 21:32:44 +0000 Subject: [PATCH] [LSASRV] - Get all procedure addresses of the loaded authentication packages and keep them in the authentication package entry. - Implement parts of the lda dispatch table (allocate heap and free heap) and pass the table to LsaApInitializePackage call. - Implement authentication package lookup by name. [MSV1_0] - Store the dispatch table entries passed to the LsaApInitializePackage call and use them to allocate a STRING to return the package name. svn path=/trunk/; revision=58427 --- reactos/dll/win32/lsasrv/authpackage.c | 193 ++++++++++++++++++++++++- reactos/dll/win32/lsasrv/authport.c | 69 ++++++++- reactos/dll/win32/lsasrv/lsasrv.h | 4 + reactos/dll/win32/msv1_0/msv1_0.c | 30 ++++ 4 files changed, 284 insertions(+), 12 deletions(-) diff --git a/reactos/dll/win32/lsasrv/authpackage.c b/reactos/dll/win32/lsasrv/authpackage.c index 462f053a78f..2cc5044370c 100644 --- a/reactos/dll/win32/lsasrv/authpackage.c +++ b/reactos/dll/win32/lsasrv/authpackage.c @@ -13,29 +13,67 @@ WINE_DEFAULT_DEBUG_CHANNEL(lsasrv); +typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG); +typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID); -typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PVOID /*PLSA_DISPATCH_TABLE*/, +typedef struct LSA_DISPATCH_TABLE +{ + PVOID /*PLSA_CREATE_LOGON_SESSION */ CreateLogonSession; + PVOID /*PLSA_DELETE_LOGON_SESSION */ DeleteLogonSession; + PVOID /*PLSA_ADD_CREDENTIAL */ AddCredential; + PVOID /*PLSA_GET_CREDENTIALS */ GetCredentials; + PVOID /*PLSA_DELETE_CREDENTIAL */ DeleteCredential; + PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap; + PLSA_FREE_LSA_HEAP FreeLsaHeap; + PVOID /*PLSA_ALLOCATE_CLIENT_BUFFER */ AllocateClientBuffer; + PVOID /*PLSA_FREE_CLIENT_BUFFER */ FreeClientBuffer; + PVOID /*PLSA_COPY_TO_CLIENT_BUFFER */ CopyToClientBuffer; + PVOID /*PLSA_COPY_FROM_CLIENT_BUFFER */ CopyFromClientBuffer; +} LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE; + + +typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PLSA_DISPATCH_TABLE, PLSA_STRING, PLSA_STRING, PLSA_STRING *); +typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE)(PUNICODE_STRING, PVOID, ULONG, + PVOID *, PULONG, PNTSTATUS); +typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_PASSTHROUGH)(PUNICODE_STRING, + PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS); +typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_UNTRUSTED)(PVOID/*PLSA_CLIENT_REQUEST*/, + PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS); +typedef VOID (NTAPI *PLSA_AP_LOGON_TERMINATED)(PLUID); +typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX2)(PVOID /*PLSA_CLIENT_REQUEST*/, + SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, + PVOID /*PLSA_TOKEN_INFORMATION_TYPE*/, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *, + PUNICODE_STRING *, PVOID /*PSECPKG_PRIMARY_CRED*/, PVOID /*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/); +typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX)(PVOID /*PLSA_CLIENT_REQUEST*/, + SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, + PVOID /*PLSA_TOKEN_INFORMATION_TYPE*/, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *, + PUNICODE_STRING *); +typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER)(LPWSTR, LPWSTR, LPWSTR, LPWSTR, + DWORD, DWORD, PHANDLE); typedef struct _AUTH_PACKAGE { LIST_ENTRY Entry; PSTRING Name; + ULONG Id; PVOID ModuleHandle; PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage; -// PLSA_AP_CALL_PACKAGE LsaApCallPackage; -// PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted; -// PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated; -// PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2; -// PLSA_AP_LOGON_USER_EX LsaApLogonUserEx; -// PLSA_AP_LOGON_USER LsaApLogonUser; + PLSA_AP_CALL_PACKAGE LsaApCallPackage; + PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough; + PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted; + PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated; + PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2; + PLSA_AP_LOGON_USER_EX LsaApLogonUserEx; + PLSA_AP_LOGON_USER LsaApLogonUser; } AUTH_PACKAGE, *PAUTH_PACKAGE; /* GLOBALS *****************************************************************/ static LIST_ENTRY PackageListHead; static ULONG PackageId; +static LSA_DISPATCH_TABLE DispatchTable; /* FUNCTIONS ***************************************************************/ @@ -90,8 +128,80 @@ LsapAddAuthPackage(IN PWSTR ValueName, goto done; } + RtlInitAnsiString(&ProcName, "LsaApCallPackage"); + Status = LdrGetProcedureAddress(Package->ModuleHandle, + &ProcName, + 0, + (PVOID *)&Package->LsaApCallPackage); + if (!NT_SUCCESS(Status)) + { + TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); + goto done; + } + + RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough"); + Status = LdrGetProcedureAddress(Package->ModuleHandle, + &ProcName, + 0, + (PVOID *)&Package->LsaApCallPackagePassthrough); + if (!NT_SUCCESS(Status)) + { + TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); + goto done; + } + + RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted"); + Status = LdrGetProcedureAddress(Package->ModuleHandle, + &ProcName, + 0, + (PVOID *)&Package->LsaApCallPackageUntrusted); + if (!NT_SUCCESS(Status)) + { + TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); + goto done; + } + + RtlInitAnsiString(&ProcName, "LsaApLogonTerminated"); + Status = LdrGetProcedureAddress(Package->ModuleHandle, + &ProcName, + 0, + (PVOID *)&Package->LsaApLogonTerminated); + if (!NT_SUCCESS(Status)) + { + TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); + goto done; + } + + RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2"); + Status = LdrGetProcedureAddress(Package->ModuleHandle, + &ProcName, + 0, + (PVOID *)&Package->LsaApLogonUserEx2); + if (!NT_SUCCESS(Status)) + { + RtlInitAnsiString(&ProcName, "LsaApLogonUserEx"); + Status = LdrGetProcedureAddress(Package->ModuleHandle, + &ProcName, + 0, + (PVOID *)&Package->LsaApLogonUserEx); + if (!NT_SUCCESS(Status)) + { + RtlInitAnsiString(&ProcName, "LsaApLogonUser"); + Status = LdrGetProcedureAddress(Package->ModuleHandle, + &ProcName, + 0, + (PVOID *)&Package->LsaApLogonUser); + if (!NT_SUCCESS(Status)) + { + TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); + goto done; + } + } + } + + /* Initialize the current package */ Status = Package->LsaApInitializePackage(*Id, - NULL, + &DispatchTable, NULL, NULL, &Package->Name); @@ -101,6 +211,9 @@ LsapAddAuthPackage(IN PWSTR ValueName, goto done; } + TRACE("Package Name: %s\n", Package->Name->Buffer); + + Package->Id = *Id; *Id++; InsertTailList(&PackageListHead, &Package->Entry); @@ -113,6 +226,14 @@ done: if (Package->ModuleHandle != NULL) LdrUnloadDll(Package->ModuleHandle); + if (Package->Name != NULL) + { + if (Package->Name->Buffer != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer); + + RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name); + } + RtlFreeHeap(RtlGetProcessHeap(), 0, Package); } } @@ -121,6 +242,23 @@ done: } +static +PVOID +NTAPI +LsapAllocateHeap(ULONG Size) +{ + return RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Size); +} + +static +VOID +NTAPI +LsapFreeHeap(PVOID Ptr) +{ + RtlFreeHeap(RtlGetProcessHeap(), 0, Ptr); +} + + NTSTATUS LsapInitAuthPackages(VOID) { @@ -133,6 +271,19 @@ LsapInitAuthPackages(VOID) InitializeListHead(&PackageListHead); PackageId = 0; + /* Initialize the dispatch table */ + DispatchTable.CreateLogonSession = NULL; + DispatchTable.DeleteLogonSession = NULL; + DispatchTable.AddCredential = NULL; + DispatchTable.GetCredentials = NULL; + DispatchTable.DeleteCredential = NULL; + DispatchTable.AllocateLsaHeap = &LsapAllocateHeap; + DispatchTable.FreeLsaHeap = &LsapFreeHeap; + DispatchTable.AllocateClientBuffer = NULL; + DispatchTable.FreeClientBuffer = NULL; + DispatchTable.CopyToClientBuffer = NULL; + DispatchTable.CopyFromClientBuffer = NULL; + /* Add registered authentication packages */ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, L"Lsa", @@ -144,4 +295,30 @@ LsapInitAuthPackages(VOID) return STATUS_SUCCESS; } + +NTSTATUS +LsapLookupAuthenticationPackageByName(IN PSTRING PackageName, + OUT PULONG PackageId) +{ + PLIST_ENTRY ListEntry; + PAUTH_PACKAGE Package; + + ListEntry = PackageListHead.Flink; + while (ListEntry != &PackageListHead) + { + Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry); + + if ((PackageName->Length == Package->Name->Length) && + (_strnicmp(PackageName->Buffer, Package->Name->Buffer, Package->Name->Length) == 0)) + { + *PackageId = Package->Id; + return STATUS_SUCCESS; + } + + ListEntry = ListEntry->Flink; + } + + return STATUS_NO_SUCH_PACKAGE; +} + /* EOF */ diff --git a/reactos/dll/win32/lsasrv/authport.c b/reactos/dll/win32/lsasrv/authport.c index 53667301411..83689b608da 100644 --- a/reactos/dll/win32/lsasrv/authport.c +++ b/reactos/dll/win32/lsasrv/authport.c @@ -61,6 +61,9 @@ static NTSTATUS LsapLogonUser(PLSA_API_MSG RequestMsg, PLSAP_LOGON_CONTEXT LogonContext) { + PVOID LocalAuthInfo = NULL; + NTSTATUS Status = STATUS_SUCCESS; + TRACE("(%p %p)\n", RequestMsg, LogonContext); TRACE("LogonType: %lu\n", RequestMsg->LogonUser.Request.LogonType); @@ -68,6 +71,48 @@ LsapLogonUser(PLSA_API_MSG RequestMsg, TRACE("AuthenticationInformation: %p\n", RequestMsg->LogonUser.Request.AuthenticationInformation); TRACE("AuthenticationInformationLength: %lu\n", RequestMsg->LogonUser.Request.AuthenticationInformationLength); + LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RequestMsg->LogonUser.Request.AuthenticationInformationLength); + if (LocalAuthInfo == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* Read the authentication info from the callers adress space */ + Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle, + RequestMsg->LogonUser.Request.AuthenticationInformation, + LocalAuthInfo, + RequestMsg->LogonUser.Request.AuthenticationInformationLength, + NULL); + if (!NT_SUCCESS(Status)) + goto done; + + if (RequestMsg->LogonUser.Request.LogonType == Interactive || + RequestMsg->LogonUser.Request.LogonType == Batch || + RequestMsg->LogonUser.Request.LogonType == Service) + { + PMSV1_0_INTERACTIVE_LOGON LogonInfo; + ULONG_PTR PtrOffset; + + LogonInfo = (PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo; + + /* Fix-up pointers in the authentication info */ + PtrOffset = (ULONG_PTR)LocalAuthInfo - (ULONG_PTR)RequestMsg->LogonUser.Request.AuthenticationInformation; + + LogonInfo->LogonDomainName.Buffer = (PWSTR)((ULONG_PTR)LogonInfo->LogonDomainName.Buffer + PtrOffset); + LogonInfo->UserName.Buffer = (PWSTR)((ULONG_PTR)LogonInfo->UserName.Buffer + PtrOffset); + LogonInfo->Password.Buffer = (PWSTR)((ULONG_PTR)LogonInfo->Password.Buffer + PtrOffset); + + TRACE("Domain: %S\n", LogonInfo->LogonDomainName.Buffer); + TRACE("User: %S\n", LogonInfo->UserName.Buffer); + TRACE("Password: %S\n", LogonInfo->Password.Buffer); + } + else + { + FIXME("LogonType %lu is not supported yet!\n", RequestMsg->LogonUser.Request.LogonType); + } @@ -78,7 +123,11 @@ LsapLogonUser(PLSA_API_MSG RequestMsg, // QUOTA_LIMITS Quotas; RequestMsg->LogonUser.Reply.SubStatus = STATUS_SUCCESS; - return STATUS_SUCCESS; +done: + if (LocalAuthInfo != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo); + + return Status; } @@ -86,13 +135,25 @@ static NTSTATUS LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg, PLSAP_LOGON_CONTEXT LogonContext) { - TRACE("(%p %p)\n", RequestMsg, LogonContext); + STRING PackageName; + ULONG PackageId; + NTSTATUS Status; + TRACE("(%p %p)\n", RequestMsg, LogonContext); TRACE("PackageName: %s\n", RequestMsg->LookupAuthenticationPackage.Request.PackageName); - RequestMsg->LookupAuthenticationPackage.Reply.Package = 0x12345678; + PackageName.Length = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength; + PackageName.MaximumLength = LSASS_MAX_PACKAGE_NAME_LENGTH + 1; + PackageName.Buffer = RequestMsg->LookupAuthenticationPackage.Request.PackageName; - return STATUS_SUCCESS; + Status = LsapLookupAuthenticationPackageByName(&PackageName, + &PackageId); + if (NT_SUCCESS(Status)) + { + RequestMsg->LookupAuthenticationPackage.Reply.Package = PackageId; + } + + return Status; } diff --git a/reactos/dll/win32/lsasrv/lsasrv.h b/reactos/dll/win32/lsasrv/lsasrv.h index 25f9bada3aa..de709d60b86 100644 --- a/reactos/dll/win32/lsasrv/lsasrv.h +++ b/reactos/dll/win32/lsasrv/lsasrv.h @@ -85,6 +85,10 @@ extern UNICODE_STRING AccountDomainName; NTSTATUS LsapInitAuthPackages(VOID); +NTSTATUS +LsapLookupAuthenticationPackageByName(IN PSTRING PackageName, + OUT PULONG PackageId); + /* authport.c */ NTSTATUS StartAuthenticationPort(VOID); diff --git a/reactos/dll/win32/msv1_0/msv1_0.c b/reactos/dll/win32/msv1_0/msv1_0.c index 9a0d3473a3f..84f1b43da2d 100644 --- a/reactos/dll/win32/msv1_0/msv1_0.c +++ b/reactos/dll/win32/msv1_0/msv1_0.c @@ -13,6 +13,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(msv1_0); +/* GLOBALS *****************************************************************/ + +LSA_DISPATCH_TABLE DispatchTable; + + /* FUNCTIONS ***************************************************************/ /* @@ -80,10 +85,35 @@ LsaApInitializePackage(IN ULONG AuthenticationPackageId, IN PLSA_STRING Confidentiality OPTIONAL, OUT PLSA_STRING *AuthenticationPackageName) { + PANSI_STRING NameString; + PCHAR NameBuffer; + TRACE("(%lu %p %p %p %p)\n", AuthenticationPackageId, LsaDispatchTable, Database, Confidentiality, AuthenticationPackageName); + /* Get the dispatch table entries */ + DispatchTable.AllocateLsaHeap = LsaDispatchTable->AllocateLsaHeap; + DispatchTable.FreeLsaHeap = LsaDispatchTable->FreeLsaHeap; + + + /* Return the package name */ + NameString = DispatchTable.AllocateLsaHeap(sizeof(LSA_STRING)); + if (NameString == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + NameBuffer = DispatchTable.AllocateLsaHeap(sizeof(MSV1_0_PACKAGE_NAME)); + if (NameBuffer == NULL) + { + DispatchTable.FreeLsaHeap(NameString); + return STATUS_INSUFFICIENT_RESOURCES; + } + + strcpy(NameBuffer, MSV1_0_PACKAGE_NAME); + + RtlInitAnsiString(NameString, NameBuffer); + + *AuthenticationPackageName = (PLSA_STRING)NameString; return STATUS_SUCCESS; }