>From f6bdfae83073708df084339563a4f3c458290e59 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Mon, 21 Aug 2017 17:20:22 +0800 Subject: [2/3] secur32: Add an initial implementation of authentication package manager. Content-Type: text/plain; charset=UTF-8 To: wine-patches@winehq.org Signed-off-by: Dmitry Timoshkov --- dlls/secur32/lsa.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++++++--- loader/wine.inf.in | 2 +- 2 files changed, 250 insertions(+), 15 deletions(-) diff --git a/dlls/secur32/lsa.c b/dlls/secur32/lsa.c index fa765ed2ce..bbd2e2107a 100644 --- a/dlls/secur32/lsa.c +++ b/dlls/secur32/lsa.c @@ -1,5 +1,7 @@ -/* Copyright (C) 2004 Juan Lang +/* + * Copyright (C) 2004 Juan Lang * Copyright (C) 2007 Kai Blin + * Copyright (C) 2017 Dmitry Timoshkov * * Local Security Authority functions, as far as secur32 has them. * @@ -24,26 +26,72 @@ #define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" +#include "winreg.h" +#include "sspi.h" #include "ntsecapi.h" +#include "ntsecpkg.h" +#include "winternl.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(lsa); -NTSTATUS WINAPI LsaCallAuthenticationPackage(HANDLE LsaHandle, - ULONG AuthenticationPackage, PVOID ProtocolSubmitBuffer, - ULONG SubmitBufferLength, PVOID* ProtocolReturnBuffer, - PULONG ReturnBufferLength, PNTSTATUS ProtocolStatus) +#define LSA_MAGIC ('L' << 24 | 'S' << 16 | 'A' << 8 | ' ') + +struct lsa_package { - FIXME("%p %d %p %d %p %p %p stub\n", LsaHandle, AuthenticationPackage, - ProtocolSubmitBuffer, SubmitBufferLength, ProtocolReturnBuffer, - ReturnBufferLength, ProtocolStatus); - return STATUS_SUCCESS; + ULONG package_id; + HMODULE mod; + ULONG version; + LSA_STRING *name; + SECPKG_FUNCTION_TABLE *api; + ULONG table_count; +}; + +static struct lsa_package *loaded_packages; +static ULONG loaded_packages_count; + +struct lsa_connection +{ + DWORD magic; +}; + +NTSTATUS WINAPI LsaCallAuthenticationPackage(HANDLE lsa_handle, ULONG package_id, + PVOID in_buffer, ULONG in_buffer_length, + PVOID *out_buffer, PULONG out_buffer_length, PNTSTATUS status) +{ + ULONG i; + + TRACE("%p,%u,%p,%u,%p,%p,%p\n", lsa_handle, package_id, in_buffer, + in_buffer_length, out_buffer, out_buffer_length, status); + + for (i = 0; i < loaded_packages_count; i++) + { + if (loaded_packages[i].package_id == package_id) + { + if (loaded_packages[i].api->CallPackageUntrusted) + return loaded_packages[i].api->CallPackageUntrusted(NULL /* FIXME*/, + in_buffer, NULL, in_buffer_length, out_buffer, out_buffer_length, status); + + return SEC_E_UNSUPPORTED_FUNCTION; + } + } + + return STATUS_INVALID_PARAMETER; } NTSTATUS WINAPI LsaConnectUntrusted(PHANDLE LsaHandle) { - FIXME("%p stub\n", LsaHandle); + struct lsa_connection *lsa_conn; + + TRACE("%p\n", LsaHandle); + + lsa_conn = HeapAlloc(GetProcessHeap(), 0, sizeof(*lsa_conn)); + if (!lsa_conn) return STATUS_NO_MEMORY; + + lsa_conn->magic = LSA_MAGIC; + *LsaHandle = lsa_conn; + return STATUS_SUCCESS; } @@ -92,14 +140,201 @@ NTSTATUS WINAPI LsaLogonUser(HANDLE LsaHandle, PLSA_STRING OriginName, return STATUS_SUCCESS; } -NTSTATUS WINAPI LsaLookupAuthenticationPackage(HANDLE LsaHandle, - PLSA_STRING PackageName, PULONG AuthenticationPackage) +static NTSTATUS NTAPI lsa_CreateLogonSession(LUID *logon_id) +{ + FIXME("%p: stub\n", logon_id); + return STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS NTAPI lsa_DeleteLogonSession(LUID *logon_id) +{ + FIXME("%p: stub\n", logon_id); + return STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS NTAPI lsa_AddCredential(LUID *logon_id, ULONG package_id, + LSA_STRING *primary_key, LSA_STRING *credentials) +{ + FIXME("%p,%u,%p,%p: stub\n", logon_id, package_id, primary_key, credentials); + return STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS NTAPI lsa_GetCredentials(LUID *logon_id, ULONG package_id, ULONG *context, + BOOLEAN retrieve_all, LSA_STRING *primary_key, ULONG *primary_key_len, LSA_STRING *credentials) +{ + FIXME("%p,%#x,%p,%d,%p,%p,%p: stub\n", logon_id, package_id, context, + retrieve_all, primary_key, primary_key_len, credentials); + return STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS NTAPI lsa_DeleteCredential(LUID *logon_id, ULONG package_id, LSA_STRING *primary_key) +{ + FIXME("%p,%#x,%p: stub\n", logon_id, package_id, primary_key); + return STATUS_NOT_IMPLEMENTED; +} + +static void * NTAPI lsa_AllocateLsaHeap(ULONG size) +{ + TRACE("%u\n", size); + return HeapAlloc(GetProcessHeap(), 0, size); +} + +static void NTAPI lsa_FreeLsaHeap(void *p) +{ + TRACE("%p\n", p); + HeapFree(GetProcessHeap(), 0, p); +} + +static NTSTATUS NTAPI lsa_AllocateClientBuffer(PLSA_CLIENT_REQUEST req, ULONG size, void **p) +{ + TRACE("%p,%u,%p\n", req, size, p); + *p = HeapAlloc(GetProcessHeap(), 0, size); + return *p ? STATUS_SUCCESS : STATUS_NO_MEMORY; +} + +static NTSTATUS NTAPI lsa_FreeClientBuffer(PLSA_CLIENT_REQUEST req, void *p) +{ + TRACE("%p,%p\n", req, p); + HeapFree(GetProcessHeap(), 0, p); + return STATUS_SUCCESS; +} + +static NTSTATUS NTAPI lsa_CopyToClientBuffer(PLSA_CLIENT_REQUEST req, ULONG size, void *client, void *buf) { - FIXME("%p %p %p stub\n", LsaHandle, PackageName, AuthenticationPackage); - AuthenticationPackage = NULL; + TRACE("%p,%u,%p,%p\n", req, size, client, buf); + memcpy(client, buf, size); return STATUS_SUCCESS; } +static NTSTATUS NTAPI lsa_CopyFromClientBuffer(PLSA_CLIENT_REQUEST req, ULONG size, void *buf, void *client) +{ + TRACE("%p,%u,%p,%p\n", req, size, buf, client); + memcpy(buf, client, size); + return STATUS_SUCCESS; +} + +static LSA_DISPATCH_TABLE lsa_dispatch = +{ + lsa_CreateLogonSession, + lsa_DeleteLogonSession, + lsa_AddCredential, + lsa_GetCredentials, + lsa_DeleteCredential, + lsa_AllocateLsaHeap, + lsa_FreeLsaHeap, + lsa_AllocateClientBuffer, + lsa_FreeClientBuffer, + lsa_CopyToClientBuffer, + lsa_CopyFromClientBuffer +}; + +static void add_package(struct lsa_package *package) +{ + struct lsa_package *new_loaded_packages; + + if (!loaded_packages) + new_loaded_packages = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_loaded_packages)); + else + new_loaded_packages = HeapReAlloc(GetProcessHeap(), 0, loaded_packages, sizeof(*new_loaded_packages) * (loaded_packages_count + 1)); + + if (new_loaded_packages) + { + loaded_packages = new_loaded_packages; + loaded_packages[loaded_packages_count] = *package; + loaded_packages_count++; + } +} + +static BOOL load_package(const char *name, struct lsa_package *package, ULONG package_id) +{ + NTSTATUS (NTAPI *lsa_mode_init)(ULONG,PULONG,PSECPKG_FUNCTION_TABLE *, PULONG); + + package->mod = LoadLibraryA(name); + if (!package->mod) return FALSE; + + lsa_mode_init = (void *)GetProcAddress(package->mod, "SpLsaModeInitialize"); + if (lsa_mode_init) + { + NTSTATUS status; + + status = lsa_mode_init(SECPKG_INTERFACE_VERSION, &package->version, &package->api, &package->table_count); + if (status == STATUS_SUCCESS) + { + status = package->api->InitializePackage(package_id, &lsa_dispatch, NULL, NULL, &package->name); + if (status == STATUS_SUCCESS) + { + TRACE("%s.dll => %p, name %s, version %#x, api table %p, table count %u\n", + debugstr_a(name), package->mod, debugstr_an(package->name->Buffer, package->name->Length), + package->version, package->api, package->table_count); + package->package_id = package_id; + return TRUE; + } + } + } + + FreeLibrary(package->mod); + return FALSE; +} + +#define MAX_SERVICE_NAME 260 + +static BOOL WINAPI load_auth_packages(INIT_ONCE *init_once, void *param, void **context) +{ + static const WCHAR LSA_KEY[] = { 'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'C','o','n','t','r','o','l','\\','L','s','a',0 }; + DWORD err, i; + HKEY root; + + err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, LSA_KEY, 0, KEY_READ, &root); + if (err != ERROR_SUCCESS) return FALSE; + + i = 0; + for (;;) + { + char name[MAX_SERVICE_NAME]; + struct lsa_package package; + + err = RegEnumKeyA(root, i++, name, MAX_SERVICE_NAME); + if (err == ERROR_NO_MORE_ITEMS) + break; + + if (err != ERROR_SUCCESS) + continue; + + if (!load_package(name, &package, i)) + continue; + + add_package(&package); + } + + RegCloseKey(root); + + return TRUE; +} + +NTSTATUS WINAPI LsaLookupAuthenticationPackage(HANDLE lsa_handle, + PLSA_STRING package_name, PULONG package_id) +{ + static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; + ULONG i; + + TRACE("%p %p %p\n", lsa_handle, package_name, package_id); + + InitOnceExecuteOnce(&init_once, load_auth_packages, NULL, NULL); + + for (i = 0; i < loaded_packages_count; i++) + { + if (!RtlCompareString(loaded_packages[i].name, package_name, FALSE)) + { + *package_id = loaded_packages[i].package_id; + return STATUS_SUCCESS; + } + } + + return STATUS_UNSUCCESSFUL; /* FIXME */ +} + NTSTATUS WINAPI LsaRegisterLogonProcess(PLSA_STRING LogonProcessName, PHANDLE LsaHandle, PLSA_OPERATIONAL_MODE SecurityMode) { diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 0b3c9408bf..787ad7f2a8 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -682,7 +682,7 @@ HKLM,Software\Microsoft\WBEM,"Installation Directory",2,"%11%\wbem" HKLM,Software\Policies,,16 HKLM,Software\Registered Applications,,16 HKLM,System\CurrentControlSet\Control\hivelist,,16 -HKLM,System\CurrentControlSet\Control\Lsa,,16 +HKLM,System\CurrentControlSet\Control\Lsa\Kerberos,,16 HKLM,System\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\SSL 2.0\Client,"DisabledByDefault",0x10003,1 HKLM,System\CurrentControlSet\Control\ServiceGroupOrder,"List",0x00010000,"TDI" HKLM,System\CurrentControlSet\Control\TimeZoneInformation,"StandardName",2,"" -- 2.14.1