secur32: Convert "Negotiate" to an LSA package.

Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
This commit is contained in:
Dmitry Timoshkov 2023-07-31 17:25:50 +03:00 committed by Alexandre Julliard
parent ef1b964826
commit 021547cabc
4 changed files with 526 additions and 628 deletions

View file

@ -71,6 +71,24 @@ static const char *debugstr_as(const LSA_STRING *str)
return debugstr_an(str->Buffer, str->Length); return debugstr_an(str->Buffer, str->Length);
} }
SECPKG_FUNCTION_TABLE *lsa_find_package(const char *name, SECPKG_USER_FUNCTION_TABLE **user_api)
{
LSA_STRING package_name;
ULONG i;
RtlInitString(&package_name, name);
for (i = 0; i < loaded_packages_count; i++)
{
if (!RtlCompareString(loaded_packages[i].name, &package_name, FALSE))
{
*user_api = loaded_packages[i].user_api;
return loaded_packages[i].lsa_api;
}
}
return NULL;
}
NTSTATUS WINAPI LsaCallAuthenticationPackage(HANDLE lsa_handle, ULONG package_id, NTSTATUS WINAPI LsaCallAuthenticationPackage(HANDLE lsa_handle, ULONG package_id,
PVOID in_buffer, ULONG in_buffer_length, PVOID in_buffer, ULONG in_buffer_length,
PVOID *out_buffer, PULONG out_buffer_length, PNTSTATUS status) PVOID *out_buffer, PULONG out_buffer_length, PNTSTATUS status)
@ -860,6 +878,39 @@ static void add_package(struct lsa_package *package)
} }
} }
static BOOL initialize_package(struct lsa_package *package,
NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG, PSECPKG_FUNCTION_TABLE *, PULONG),
NTSTATUS (NTAPI *pSpUserModeInitialize)(ULONG, PULONG, PSECPKG_USER_FUNCTION_TABLE *, PULONG))
{
NTSTATUS status;
if (!pSpLsaModeInitialize || !pSpUserModeInitialize)
return FALSE;
status = pSpLsaModeInitialize(SECPKG_INTERFACE_VERSION, &package->lsa_api_version, &package->lsa_api, &package->lsa_table_count);
if (status == STATUS_SUCCESS)
{
status = package->lsa_api->InitializePackage(package->package_id, &lsa_dispatch, NULL, NULL, &package->name);
if (status == STATUS_SUCCESS)
{
TRACE("name %s, version %#lx, api table %p, table count %lu\n",
debugstr_an(package->name->Buffer, package->name->Length),
package->lsa_api_version, package->lsa_api, package->lsa_table_count);
status = package->lsa_api->Initialize(package->package_id, NULL /* FIXME: params */, NULL);
if (status == STATUS_SUCCESS)
{
status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &package->user_api_version, &package->user_api, &package->user_table_count);
if (status == STATUS_SUCCESS)
package->user_api->InstanceInit(SECPKG_INTERFACE_VERSION, &lsa_dll_dispatch, NULL);
}
}
return TRUE;
}
return FALSE;
}
static BOOL load_package(const WCHAR *name, struct lsa_package *package, ULONG package_id) static BOOL load_package(const WCHAR *name, struct lsa_package *package, ULONG package_id)
{ {
NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG, PSECPKG_FUNCTION_TABLE *, PULONG); NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG, PSECPKG_FUNCTION_TABLE *, PULONG);
@ -867,40 +918,15 @@ static BOOL load_package(const WCHAR *name, struct lsa_package *package, ULONG p
memset(package, 0, sizeof(*package)); memset(package, 0, sizeof(*package));
package->package_id = package_id;
package->mod = LoadLibraryW(name); package->mod = LoadLibraryW(name);
if (!package->mod) return FALSE; if (!package->mod) return FALSE;
pSpLsaModeInitialize = (void *)GetProcAddress(package->mod, "SpLsaModeInitialize"); pSpLsaModeInitialize = (void *)GetProcAddress(package->mod, "SpLsaModeInitialize");
if (pSpLsaModeInitialize) pSpUserModeInitialize = (void *)GetProcAddress(package->mod, "SpUserModeInitialize");
{
NTSTATUS status;
status = pSpLsaModeInitialize(SECPKG_INTERFACE_VERSION, &package->lsa_api_version, &package->lsa_api, &package->lsa_table_count); if (initialize_package(package, pSpLsaModeInitialize, pSpUserModeInitialize))
if (status == STATUS_SUCCESS) return TRUE;
{
status = package->lsa_api->InitializePackage(package_id, &lsa_dispatch, NULL, NULL, &package->name);
if (status == STATUS_SUCCESS)
{
TRACE("%s => %p, name %s, version %#lx, api table %p, table count %lu\n",
debugstr_w(name), package->mod, debugstr_an(package->name->Buffer, package->name->Length),
package->lsa_api_version, package->lsa_api, package->lsa_table_count);
package->package_id = package_id;
status = package->lsa_api->Initialize(package_id, NULL /* FIXME: params */, NULL);
if (status == STATUS_SUCCESS)
{
pSpUserModeInitialize = (void *)GetProcAddress(package->mod, "SpUserModeInitialize");
if (pSpUserModeInitialize)
{
status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &package->user_api_version, &package->user_api, &package->user_table_count);
if (status == STATUS_SUCCESS)
package->user_api->InstanceInit(SECPKG_INTERFACE_VERSION, &lsa_dll_dispatch, NULL);
}
}
return TRUE;
}
}
}
FreeLibrary(package->mod); FreeLibrary(package->mod);
return FALSE; return FALSE;
@ -913,6 +939,14 @@ void load_auth_packages(void)
DWORD err, i; DWORD err, i;
HKEY root; HKEY root;
SecureProvider *provider; SecureProvider *provider;
struct lsa_package package;
memset(&package, 0, sizeof(package));
/* "Negotiate" has package id 0, .Net depends on this. */
package.package_id = 0;
if (initialize_package(&package, nego_SpLsaModeInitialize, nego_SpUserModeInitialize))
add_package(&package);
err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Lsa", 0, KEY_READ, &root); err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Lsa", 0, KEY_READ, &root);
if (err != ERROR_SUCCESS) return; if (err != ERROR_SUCCESS) return;
@ -921,19 +955,19 @@ void load_auth_packages(void)
for (;;) for (;;)
{ {
WCHAR name[MAX_SERVICE_NAME]; WCHAR name[MAX_SERVICE_NAME];
struct lsa_package package;
err = RegEnumKeyW(root, i++, name, MAX_SERVICE_NAME); err = RegEnumKeyW(root, i, name, MAX_SERVICE_NAME);
if (err == ERROR_NO_MORE_ITEMS) if (err == ERROR_NO_MORE_ITEMS)
break; break;
if (err != ERROR_SUCCESS) if (err != ERROR_SUCCESS)
continue; continue;
if (!load_package(name, &package, i)) if (!load_package(name, &package, i + 1))
continue; continue;
add_package(&package); add_package(&package);
i++;
} }
RegCloseKey(root); RegCloseKey(root);

File diff suppressed because it is too large Load diff

View file

@ -501,10 +501,6 @@ static void SECUR32_initializeProviders(void)
SECUR32_initSchannelSP(); SECUR32_initSchannelSP();
/* Load SSP/AP packages (Kerberos and others) */ /* Load SSP/AP packages (Kerberos and others) */
load_auth_packages(); load_auth_packages();
/* Load the Negotiate provider last so apps stumble over the working NTLM
* provider first. Attempting to fix bug #16905 while keeping the
* application reported on wine-users on 2006-09-12 working. */
SECUR32_initNegotiateSP();
/* Now load providers from registry */ /* Now load providers from registry */
apiRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\SecurityProviders", 0, apiRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\SecurityProviders", 0,
KEY_READ, &key); KEY_READ, &key);

View file

@ -24,6 +24,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <limits.h> #include <limits.h>
#include "schannel.h" #include "schannel.h"
#include "ntsecapi.h"
#include "ntsecpkg.h"
#include "wine/list.h" #include "wine/list.h"
typedef struct _SecureProvider typedef struct _SecureProvider
@ -70,8 +72,10 @@ SecurePackage *SECUR32_findPackageA(PCSTR packageName) DECLSPEC_HIDDEN;
/* Initialization functions for built-in providers */ /* Initialization functions for built-in providers */
void SECUR32_initSchannelSP(void) DECLSPEC_HIDDEN; void SECUR32_initSchannelSP(void) DECLSPEC_HIDDEN;
void SECUR32_initNegotiateSP(void) DECLSPEC_HIDDEN;
void load_auth_packages(void) DECLSPEC_HIDDEN; void load_auth_packages(void) DECLSPEC_HIDDEN;
NTSTATUS NTAPI nego_SpLsaModeInitialize(ULONG, PULONG, PSECPKG_FUNCTION_TABLE *, PULONG) DECLSPEC_HIDDEN;
NTSTATUS NTAPI nego_SpUserModeInitialize(ULONG, PULONG, PSECPKG_USER_FUNCTION_TABLE *, PULONG) DECLSPEC_HIDDEN;
SECPKG_FUNCTION_TABLE *lsa_find_package(const char *name, SECPKG_USER_FUNCTION_TABLE **user_api) DECLSPEC_HIDDEN;
/* Cleanup functions for built-in providers */ /* Cleanup functions for built-in providers */
void SECUR32_deinitSchannelSP(void) DECLSPEC_HIDDEN; void SECUR32_deinitSchannelSP(void) DECLSPEC_HIDDEN;