.Net assumes that Negotiate LSA package has index 0: https://github.com/dotnet/runtime/blob/f1d2be8f443a599a142506d622a35e1c2e683...
-- v3: secur32/tests: Add some tests for "Negotiate" LSA package. secur32: Add a better stub for LsaApCallPackageUntrusted(NegGetCallerName). secur32: Convert "Negotiate" to an LSA package.
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/secur32/lsa.c | 74 +++- dlls/secur32/negotiate.c | 700 +++++++++++++++--------------------- dlls/secur32/secur32.c | 4 - dlls/secur32/secur32_priv.h | 6 +- 4 files changed, 343 insertions(+), 441 deletions(-)
diff --git a/dlls/secur32/lsa.c b/dlls/secur32/lsa.c index 3cbd49e6b0e..857c7d451d0 100644 --- a/dlls/secur32/lsa.c +++ b/dlls/secur32/lsa.c @@ -71,6 +71,24 @@ static const char *debugstr_as(const LSA_STRING *str) 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, PVOID in_buffer, ULONG in_buffer_length, PVOID *out_buffer, PULONG out_buffer_length, PNTSTATUS status) @@ -860,17 +878,11 @@ static void add_package(struct lsa_package *package) } }
-static BOOL load_package(const WCHAR *name, struct lsa_package *package, ULONG package_id) +static BOOL initialize_package(struct lsa_package *package, void *lsa_mode_init, void *user_mode_init) { - NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG, PSECPKG_FUNCTION_TABLE *, PULONG); - NTSTATUS (NTAPI *pSpUserModeInitialize)(ULONG, PULONG, PSECPKG_USER_FUNCTION_TABLE *, PULONG); - - memset(package, 0, sizeof(*package)); + NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG, PSECPKG_FUNCTION_TABLE *, PULONG) = lsa_mode_init; + NTSTATUS (NTAPI *pSpUserModeInitialize)(ULONG, PULONG, PSECPKG_USER_FUNCTION_TABLE *, PULONG) = user_mode_init;
- package->mod = LoadLibraryW(name); - if (!package->mod) return FALSE; - - pSpLsaModeInitialize = (void *)GetProcAddress(package->mod, "SpLsaModeInitialize"); if (pSpLsaModeInitialize) { NTSTATUS status; @@ -878,18 +890,16 @@ static BOOL load_package(const WCHAR *name, struct lsa_package *package, ULONG p 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_id, &lsa_dispatch, NULL, NULL, &package->name); + status = package->lsa_api->InitializePackage(package->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), + 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); - package->package_id = package_id;
- status = package->lsa_api->Initialize(package_id, NULL /* FIXME: params */, NULL); + status = package->lsa_api->Initialize(package->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); @@ -902,6 +912,26 @@ static BOOL load_package(const WCHAR *name, struct lsa_package *package, ULONG p } }
+ return FALSE; +} + +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 *pSpUserModeInitialize)(ULONG, PULONG, PSECPKG_USER_FUNCTION_TABLE *, PULONG); + + memset(package, 0, sizeof(*package)); + + package->package_id = package_id; + package->mod = LoadLibraryW(name); + if (!package->mod) return FALSE; + + pSpLsaModeInitialize = (void *)GetProcAddress(package->mod, "SpLsaModeInitialize"); + pSpUserModeInitialize = (void *)GetProcAddress(package->mod, "SpUserModeInitialize"); + + if (initialize_package(package, pSpLsaModeInitialize, pSpUserModeInitialize)) + return TRUE; + FreeLibrary(package->mod); return FALSE; } @@ -913,6 +943,14 @@ void load_auth_packages(void) DWORD err, i; HKEY root; 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); if (err != ERROR_SUCCESS) return; @@ -921,19 +959,19 @@ void load_auth_packages(void) for (;;) { 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) break;
if (err != ERROR_SUCCESS) continue;
- if (!load_package(name, &package, i)) + if (!load_package(name, &package, i + 1)) continue;
add_package(&package); + i++; }
RegCloseKey(root); diff --git a/dlls/secur32/negotiate.c b/dlls/secur32/negotiate.c index a63e458750f..c5d89a38228 100644 --- a/dlls/secur32/negotiate.c +++ b/dlls/secur32/negotiate.c @@ -19,88 +19,153 @@
#include <stdarg.h> #include <stdlib.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" #include "sspi.h" #include "rpc.h" #include "wincred.h" +#include "ntsecapi.h" +#include "ntsecpkg.h" +#include "winternl.h"
#include "wine/debug.h" #include "secur32_priv.h"
WINE_DEFAULT_DEBUG_CHANNEL(secur32);
-/*********************************************************************** - * QueryCredentialsAttributesA - */ -static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA( - PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) +struct sec_handle { - FIXME("%p, %lu, %p\n", phCredential, ulAttribute, pBuffer); + SECPKG_FUNCTION_TABLE *krb; + SECPKG_FUNCTION_TABLE *ntlm; + SECPKG_USER_FUNCTION_TABLE *user_krb; + SECPKG_USER_FUNCTION_TABLE *user_ntlm; + LSA_SEC_HANDLE handle_krb; + LSA_SEC_HANDLE handle_ntlm; +}; + +#define WINE_NO_CACHED_CREDENTIALS 0x10000000 +#define NEGO_MAX_TOKEN 12000 + +static WCHAR nego_name_W[] = {'N','e','g','o','t','i','a','t','e',0}; +static char nego_name_A[] = "Negotiate"; +static WCHAR negotiate_comment_W[] = + {'M','i','c','r','o','s','o','f','t',' ','P','a','c','k','a','g','e',' ', + 'N','e','g','o','t','i','a','t','o','r',0}; + +#define CAPS ( \ + SECPKG_FLAG_INTEGRITY | \ + SECPKG_FLAG_PRIVACY | \ + SECPKG_FLAG_CONNECTION | \ + SECPKG_FLAG_MULTI_REQUIRED | \ + SECPKG_FLAG_EXTENDED_ERROR | \ + SECPKG_FLAG_IMPERSONATION | \ + SECPKG_FLAG_ACCEPT_WIN32_NAME | \ + SECPKG_FLAG_NEGOTIABLE | \ + SECPKG_FLAG_GSS_COMPATIBLE | \ + SECPKG_FLAG_LOGON | \ + SECPKG_FLAG_RESTRICTED_TOKENS ) + +static NTSTATUS NTAPI nego_LsaApCallPackageUntrusted( PLSA_CLIENT_REQUEST req, void *in_buf, + void *client_buf_base, ULONG in_buf_len, void **out_buf, ULONG *out_buf_len, NTSTATUS *ret_status ) +{ + FIXME("%p, %p, %p, %lu, %p, %p, %p: stub\n", req, in_buf, client_buf_base, in_buf_len, out_buf, out_buf_len, ret_status); + return SEC_E_UNSUPPORTED_FUNCTION; }
-/*********************************************************************** - * QueryCredentialsAttributesW - */ -static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW( - PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) +static NTSTATUS NTAPI nego_LsaApInitializePackage( ULONG package_id, PLSA_DISPATCH_TABLE dispatch, + PLSA_STRING database, PLSA_STRING confidentiality, PLSA_STRING *package_name ) { - FIXME("%p, %lu, %p\n", phCredential, ulAttribute, pBuffer); - return SEC_E_UNSUPPORTED_FUNCTION; + char *name; + + name = dispatch->AllocateLsaHeap( sizeof(nego_name_A) ); + if (!name) return STATUS_NO_MEMORY; + + memcpy(name, nego_name_A, sizeof(nego_name_A)); + + *package_name = dispatch->AllocateLsaHeap( sizeof(**package_name) ); + if (!*package_name) + { + dispatch->FreeLsaHeap( name ); + return STATUS_NO_MEMORY; + } + + RtlInitString( *package_name, name ); + + return STATUS_SUCCESS; }
-struct sec_handle +static NTSTATUS NTAPI nego_SpInitialize( ULONG_PTR package_id, SECPKG_PARAMETERS *params, + LSA_SECPKG_FUNCTION_TABLE *lsa_function_table ) { - SecureProvider *krb; - SecureProvider *ntlm; - SecHandle handle_krb; - SecHandle handle_ntlm; -}; + TRACE( "%Iu, %p, %p\n", package_id, params, lsa_function_table ); + return STATUS_SUCCESS; +}
-#define WINE_NO_CACHED_CREDENTIALS 0x10000000 +static NTSTATUS NTAPI nego_SpShutdown( void ) +{ + TRACE( "\n" ); + return STATUS_SUCCESS; +}
-/*********************************************************************** - * AcquireCredentialsHandleW - */ -static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW( - SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, - PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, - PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry ) +static NTSTATUS NTAPI nego_SpGetInfo( SecPkgInfoW *info ) { - static SEC_WCHAR ntlmW[] = {'N','T','L','M',0}; - static SEC_WCHAR kerberosW[] = {'K','e','r','b','e','r','o','s',0}; - SECURITY_STATUS ret = SEC_E_NO_CREDENTIALS; + const SecPkgInfoW infoW = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN, + nego_name_W, negotiate_comment_W}; + + TRACE( "%p\n", info ); + + /* LSA will make a copy before forwarding the structure, so + * it's safe to put pointers to dynamic or constant data there. + */ + *info = infoW; + return STATUS_SUCCESS; +} + +static NTSTATUS NTAPI nego_SpAcquireCredentialsHandle( + UNICODE_STRING *principal_us, ULONG credential_use, LUID *logon_id, void *auth_data, + void *get_key_fn, void *get_key_arg, LSA_SEC_HANDLE *credential, TimeStamp *expiry ) +{ + NTSTATUS ret = SEC_E_NO_CREDENTIALS; struct sec_handle *cred; - SecurePackage *package; + SECPKG_FUNCTION_TABLE *package; + SECPKG_USER_FUNCTION_TABLE *user;
- TRACE("%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p\n", - debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse, - pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); + TRACE( "%p, %#lx, %p, %p, %p, %p, %p, %p\n", principal_us, credential_use, + logon_id, auth_data, get_key_fn, get_key_arg, credential, expiry );
- if (!pszPackage) return SEC_E_SECPKG_NOT_FOUND; if (!(cred = calloc( 1, sizeof(*cred) ))) return SEC_E_INSUFFICIENT_MEMORY;
- if ((package = SECUR32_findPackageW( kerberosW ))) + if ((package = lsa_find_package( "Kerberos", &user ))) { - ret = package->provider->fnTableW.AcquireCredentialsHandleW( pszPrincipal, kerberosW, - fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, &cred->handle_krb, ptsExpiry ); - if (ret == SEC_E_OK) cred->krb = package->provider; + ret = package->SpAcquireCredentialsHandle( principal_us, credential_use, logon_id, auth_data, + get_key_fn, get_key_arg, &cred->handle_krb, expiry ); + if (ret == SEC_E_OK) + { + cred->krb = package; + cred->user_krb = user; + } }
- if ((package = SECUR32_findPackageW( ntlmW ))) + if ((package = lsa_find_package( "NTLM", &user ))) { - ULONG cred_use = pAuthData ? fCredentialUse : fCredentialUse | WINE_NO_CACHED_CREDENTIALS; + ULONG cred_use = auth_data ? credential_use : credential_use | WINE_NO_CACHED_CREDENTIALS;
- ret = package->provider->fnTableW.AcquireCredentialsHandleW( pszPrincipal, ntlmW, - cred_use, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, &cred->handle_ntlm, ptsExpiry ); - if (ret == SEC_E_OK) cred->ntlm = package->provider; + ret = package->SpAcquireCredentialsHandle( principal_us, cred_use, logon_id, auth_data, + get_key_fn, get_key_arg, &cred->handle_ntlm, expiry ); + if (ret == SEC_E_OK) + { + cred->ntlm = package; + cred->user_ntlm = user; + } }
if (cred->krb || cred->ntlm) { - phCredential->dwLower = (ULONG_PTR)cred; - phCredential->dwUpper = 0; + *credential = (LSA_SEC_HANDLE)cred; return SEC_E_OK; }
@@ -108,78 +173,41 @@ static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW( return ret; }
-/*********************************************************************** - * AcquireCredentialsHandleA - */ -static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA( - SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, - PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, - PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry ) +static NTSTATUS NTAPI nego_SpFreeCredentialsHandle( LSA_SEC_HANDLE credential ) { - SECURITY_STATUS ret = SEC_E_INSUFFICIENT_MEMORY; - SEC_WCHAR *package = NULL; - SEC_WINNT_AUTH_IDENTITY_A *id = pAuthData; - SEC_WINNT_AUTH_IDENTITY_W idW = {}; - - TRACE("%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p\n", - debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse, - pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); - - if (pszPackage) - { - int package_len = MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, NULL, 0 ); - if (!(package = malloc( package_len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY; - MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, package, package_len ); - } - if (id && id->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI) - { - idW.UserLength = MultiByteToWideChar( CP_ACP, 0, (const char *)id->User, id->UserLength, NULL, 0 ); - if (!(idW.User = malloc( idW.UserLength * sizeof(SEC_WCHAR) ))) goto done; - MultiByteToWideChar( CP_ACP, 0, (const char *)id->User, id->UserLength, idW.User, idW.UserLength ); + struct sec_handle *cred;
- idW.DomainLength = MultiByteToWideChar( CP_ACP, 0, (const char *)id->Domain, id->DomainLength, NULL, 0 ); - if (!(idW.Domain = malloc( idW.DomainLength * sizeof(SEC_WCHAR) ))) goto done; - MultiByteToWideChar( CP_ACP, 0, (const char *)id->Domain, id->DomainLength, idW.Domain, idW.DomainLength ); + TRACE( "%Ix\n", credential );
- idW.PasswordLength = MultiByteToWideChar( CP_ACP, 0, (const char *)id->Password, id->PasswordLength, NULL, 0 ); - if (!(idW.Password = malloc( idW.PasswordLength * sizeof(SEC_WCHAR) ))) goto done; - MultiByteToWideChar( CP_ACP, 0, (const char *)id->Password, id->PasswordLength, idW.Password, idW.PasswordLength ); + if (!credential) return SEC_E_INVALID_HANDLE;
- idW.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - pAuthData = &idW; - } + cred = (struct sec_handle *)credential; + if (cred->krb) cred->krb->FreeCredentialsHandle( cred->handle_krb ); + if (cred->ntlm) cred->ntlm->FreeCredentialsHandle( cred->handle_ntlm );
- ret = nego_AcquireCredentialsHandleW( NULL, package, fCredentialUse, pLogonID, pAuthData, - pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry ); -done: - free( package ); - return ret; + free( cred ); + return SEC_E_OK; }
-/*********************************************************************** - * InitializeSecurityContextW - */ -static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW( - PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, - ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry ) +static NTSTATUS NTAPI nego_SpInitLsaModeContext( LSA_SEC_HANDLE credential, LSA_SEC_HANDLE context, + UNICODE_STRING *target_name, ULONG context_req, ULONG target_data_rep, SecBufferDesc *input, + LSA_SEC_HANDLE *new_context, SecBufferDesc *output, ULONG *context_attr, TimeStamp *expiry, + BOOLEAN *mapped_context, SecBuffer *context_data ) { - SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; + NTSTATUS ret = SEC_E_INVALID_HANDLE; struct sec_handle *handle = NULL, *ctxt, *new_ctxt = NULL, *cred = NULL;
- TRACE("%p, %p, %s, 0x%08lx, %lu, %lu, %p, %lu, %p, %p, %p, %p\n", - phCredential, phContext, debugstr_w(pszTargetName), fContextReq, - Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput, - pfContextAttr, ptsExpiry); + TRACE( "%Ix, %Ix, %p, %#lx, %lu, %p, %p, %p, %p, %p, %p, %p\n", credential, context, target_name, + context_req, target_data_rep, input, new_context, output, context_attr, expiry, + mapped_context, context_data );
- if (phContext) + if (context) { - handle = ctxt = (struct sec_handle *)phContext->dwLower; + handle = ctxt = (struct sec_handle *)context; } - else if (phCredential) + else if (credential) { - handle = cred = (struct sec_handle *)phCredential->dwLower; + handle = cred = (struct sec_handle *)credential; if (!(new_ctxt = ctxt = calloc( 1, sizeof(*ctxt) ))) return SEC_E_INSUFFICIENT_MEMORY; ctxt->krb = cred->krb; ctxt->ntlm = cred->ntlm; @@ -188,28 +216,26 @@ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
if (handle->krb) { - ret = handle->krb->fnTableW.InitializeSecurityContextW( phCredential ? &cred->handle_krb : NULL, - phContext ? &ctxt->handle_krb : NULL, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, - Reserved2, phNewContext ? &ctxt->handle_krb : NULL, pOutput, pfContextAttr, ptsExpiry ); - if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext) + ret = handle->krb->InitLsaModeContext( credential ? cred->handle_krb : 0, + context ? ctxt->handle_krb : 0, target_name, context_req, target_data_rep, input, + new_context ? &ctxt->handle_krb : NULL, output, context_attr, expiry, mapped_context, context_data ); + if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && new_context) { ctxt->ntlm = NULL; - phNewContext->dwLower = (ULONG_PTR)ctxt; - phNewContext->dwUpper = 0; + *new_context = (LSA_SEC_HANDLE)ctxt; if (new_ctxt == ctxt) new_ctxt = NULL; } }
if (ret != SEC_E_OK && ret != SEC_I_CONTINUE_NEEDED && handle->ntlm) { - ret = handle->ntlm->fnTableW.InitializeSecurityContextW( phCredential ? &cred->handle_ntlm : NULL, - phContext ? &ctxt->handle_ntlm : NULL, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, - Reserved2, phNewContext ? &ctxt->handle_ntlm : NULL, pOutput, pfContextAttr, ptsExpiry ); - if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext) + ret = handle->ntlm->InitLsaModeContext( credential ? cred->handle_ntlm : 0, + context ? ctxt->handle_ntlm : 0, target_name, context_req, target_data_rep, input, + new_context ? &ctxt->handle_ntlm : NULL, output, context_attr, expiry, mapped_context, context_data ); + if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && new_context) { ctxt->krb = NULL; - phNewContext->dwLower = (ULONG_PTR)ctxt; - phNewContext->dwUpper = 0; + *new_context = (LSA_SEC_HANDLE)ctxt; if (new_ctxt == ctxt) new_ctxt = NULL; } } @@ -218,58 +244,23 @@ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW( return ret; }
-/*********************************************************************** - * InitializeSecurityContextA - */ -static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA( - PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, - ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry ) -{ - SECURITY_STATUS ret; - SEC_WCHAR *target = NULL; - - TRACE("%p, %p, %s, 0x%08lx, %lu, %lu, %p, %lu, %p, %p, %p, %p\n", - phCredential, phContext, debugstr_a(pszTargetName), fContextReq, - Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput, - pfContextAttr, ptsExpiry); - - if (pszTargetName) - { - int target_len = MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, NULL, 0 ); - if (!(target = malloc( target_len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY; - MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, target, target_len ); - } - ret = nego_InitializeSecurityContextW( phCredential, phContext, target, fContextReq, - Reserved1, TargetDataRep, pInput, Reserved2, - phNewContext, pOutput, pfContextAttr, ptsExpiry ); - free( target ); - return ret; -} - -/*********************************************************************** - * AcceptSecurityContext - */ -static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext( - PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, - ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) +static NTSTATUS NTAPI nego_SpAcceptLsaModeContext( LSA_SEC_HANDLE credential, LSA_SEC_HANDLE context, + SecBufferDesc *input, ULONG context_req, ULONG target_data_rep, LSA_SEC_HANDLE *new_context, + SecBufferDesc *output, ULONG *context_attr, TimeStamp *expiry, BOOLEAN *mapped_context, SecBuffer *context_data ) { SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; struct sec_handle *handle = NULL, *ctxt, *new_ctxt = NULL, *cred = NULL;
- TRACE("%p, %p, %p, 0x%08lx, %lu, %p, %p, %p, %p\n", phCredential, phContext, - pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, - ptsExpiry); + TRACE( "%Ix, %Ix, %#lx, %lu, %p, %p, %p, %p, %p, %p, %p\n", credential, context, context_req, target_data_rep, + input, new_context, output, context_attr, expiry, mapped_context, context_data );
- if (phContext) + if (context) { - handle = ctxt = (struct sec_handle *)phContext->dwLower; + handle = ctxt = (struct sec_handle *)context; } - else if (phCredential) + else if (credential) { - handle = cred = (struct sec_handle *)phCredential->dwLower; + handle = cred = (struct sec_handle *)credential; if (!(new_ctxt = ctxt = calloc( 1, sizeof(*ctxt) ))) return SEC_E_INSUFFICIENT_MEMORY; ctxt->krb = cred->krb; ctxt->ntlm = cred->ntlm; @@ -278,28 +269,28 @@ static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
if (handle->krb) { - ret = handle->krb->fnTableW.AcceptSecurityContext( phCredential ? &cred->handle_krb : NULL, - phContext ? &ctxt->handle_krb : NULL, pInput, fContextReq, TargetDataRep, - phNewContext ? &ctxt->handle_krb : NULL, pOutput, pfContextAttr, ptsExpiry ); - if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext) + ret = handle->krb->AcceptLsaModeContext( credential ? cred->handle_krb : 0, + context ? ctxt->handle_krb : 0, input, context_req, target_data_rep, + new_context ? &ctxt->handle_krb : NULL, + output, context_attr, expiry, mapped_context, context_data ); + if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && new_context) { ctxt->ntlm = NULL; - phNewContext->dwLower = (ULONG_PTR)ctxt; - phNewContext->dwUpper = 0; + *new_context = (LSA_SEC_HANDLE)ctxt; if (new_ctxt == ctxt) new_ctxt = NULL; } }
if (ret != SEC_E_OK && ret != SEC_I_CONTINUE_NEEDED && handle->ntlm) { - ret = handle->ntlm->fnTableW.AcceptSecurityContext( phCredential ? &cred->handle_ntlm : NULL, - phContext ? &ctxt->handle_ntlm : NULL, pInput, fContextReq, TargetDataRep, - phNewContext ? &ctxt->handle_ntlm : NULL, pOutput, pfContextAttr, ptsExpiry ); - if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext) + ret = handle->ntlm->AcceptLsaModeContext( credential ? cred->handle_ntlm : 0, + context ? ctxt->handle_ntlm : 0, input, context_req, target_data_rep, + new_context ? &ctxt->handle_ntlm : NULL, + output, context_attr, expiry, mapped_context, context_data ); + if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && new_context) { ctxt->krb = NULL; - phNewContext->dwLower = (ULONG_PTR)ctxt; - phNewContext->dwUpper = 0; + *new_context = (LSA_SEC_HANDLE)ctxt; if (new_ctxt == ctxt) new_ctxt = NULL; } } @@ -308,347 +299,220 @@ static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext( return ret; }
-/*********************************************************************** - * CompleteAuthToken - */ -static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext, - PSecBufferDesc pToken) -{ - SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; - - TRACE("%p %p\n", phContext, pToken); - - if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION; - return ret; -} - -/*********************************************************************** - * DeleteSecurityContext - */ -static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext) +static NTSTATUS NTAPI nego_SpDeleteContext( LSA_SEC_HANDLE context ) { SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; struct sec_handle *ctxt;
- TRACE("%p\n", phContext); + TRACE( "%Ix\n", context );
- if (!phContext) return SEC_E_INVALID_HANDLE; + if (!context) return SEC_E_INVALID_HANDLE;
- ctxt = (struct sec_handle *)phContext->dwLower; + ctxt = (struct sec_handle *)context; if (ctxt->krb) { - ret = ctxt->krb->fnTableW.DeleteSecurityContext( &ctxt->handle_krb ); + ret = ctxt->krb->DeleteContext( ctxt->handle_krb ); } else if (ctxt->ntlm) { - ret = ctxt->ntlm->fnTableW.DeleteSecurityContext( &ctxt->handle_ntlm ); + ret = ctxt->ntlm->DeleteContext( ctxt->handle_ntlm ); } TRACE( "freeing %p\n", ctxt ); free( ctxt ); return ret; }
-/*********************************************************************** - * ApplyControlToken - */ -static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext, - PSecBufferDesc pInput) -{ - SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; - - TRACE("%p %p\n", phContext, pInput); - - if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION; - return ret; -} - -/*********************************************************************** - * QueryContextAttributesW - */ -static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW( - PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) +static NTSTATUS NTAPI nego_SpQueryContextAttributes( LSA_SEC_HANDLE context, ULONG attribute, void *buffer ) { SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; struct sec_handle *ctxt;
- TRACE("%p, %lu, %p\n", phContext, ulAttribute, pBuffer); + TRACE( "%Ix, %lu, %p\n", context, attribute, buffer );
- if (!phContext) return SEC_E_INVALID_HANDLE; + if (!context) return SEC_E_INVALID_HANDLE;
- ctxt = (struct sec_handle *)phContext->dwLower; + ctxt = (struct sec_handle *)context; if (ctxt->krb) { - ret = ctxt->krb->fnTableW.QueryContextAttributesW( &ctxt->handle_krb, ulAttribute, pBuffer ); + ret = ctxt->krb->SpQueryContextAttributes( ctxt->handle_krb, attribute, buffer ); } else if (ctxt->ntlm) { - ret = ctxt->ntlm->fnTableW.QueryContextAttributesW( &ctxt->handle_ntlm, ulAttribute, pBuffer ); + ret = ctxt->ntlm->SpQueryContextAttributes( ctxt->handle_ntlm, attribute, buffer ); } return ret; }
-/*********************************************************************** - * QueryContextAttributesA - */ -static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext, - ULONG ulAttribute, void *pBuffer) +static SECPKG_FUNCTION_TABLE nego_lsa_table = { - SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; - struct sec_handle *ctxt; - - TRACE("%p, %lu, %p\n", phContext, ulAttribute, pBuffer); - - if (!phContext) return SEC_E_INVALID_HANDLE; - - ctxt = (struct sec_handle *)phContext->dwLower; - if (ctxt->krb) - { - ret = ctxt->krb->fnTableA.QueryContextAttributesA( &ctxt->handle_krb, ulAttribute, pBuffer ); - } - else if (ctxt->ntlm) - { - ret = ctxt->ntlm->fnTableA.QueryContextAttributesA( &ctxt->handle_ntlm, ulAttribute, pBuffer ); - } - return ret; -} + nego_LsaApInitializePackage, + NULL, /* LsaLogonUser */ + NULL, /* CallPackage */ + NULL, /* LogonTerminated */ + nego_LsaApCallPackageUntrusted, + NULL, /* CallPackagePassthrough */ + NULL, /* LogonUserEx */ + NULL, /* LogonUserEx2 */ + nego_SpInitialize, + nego_SpShutdown, + nego_SpGetInfo, + NULL, /* AcceptCredentials */ + nego_SpAcquireCredentialsHandle, + NULL, /* SpQueryCredentialsAttributes */ + nego_SpFreeCredentialsHandle, + NULL, /* SaveCredentials */ + NULL, /* GetCredentials */ + NULL, /* DeleteCredentials */ + nego_SpInitLsaModeContext, + nego_SpAcceptLsaModeContext, + nego_SpDeleteContext, + NULL, /* ApplyControlToken */ + NULL, /* GetUserInfo */ + NULL, /* GetExtendedInformation */ + nego_SpQueryContextAttributes, + NULL, /* SpAddCredentials */ + NULL, /* SetExtendedInformation */ + NULL, /* SetContextAttributes */ + NULL, /* SetCredentialsAttributes */ + NULL, /* ChangeAccountPassword */ + NULL, /* QueryMetaData */ + NULL, /* ExchangeMetaData */ + NULL, /* GetCredUIContext */ + NULL, /* UpdateCredentials */ + NULL, /* ValidateTargetInfo */ + NULL, /* PostLogonUser */ +};
-/*********************************************************************** - * ImpersonateSecurityContext - */ -static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext) +NTSTATUS NTAPI nego_SpLsaModeInitialize(ULONG lsa_version, PULONG package_version, + PSECPKG_FUNCTION_TABLE *table, PULONG table_count) { - SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; + TRACE("%#lx, %p, %p, %p\n", lsa_version, package_version, table, table_count);
- TRACE("%p\n", phContext); - - if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION; - return ret; + *package_version = SECPKG_INTERFACE_VERSION; + *table = &nego_lsa_table; + *table_count = 1; + return STATUS_SUCCESS; }
-/*********************************************************************** - * RevertSecurityContext - */ -static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext) +static NTSTATUS NTAPI nego_SpInstanceInit(ULONG version, SECPKG_DLL_FUNCTIONS *dll_function_table, void **user_functions) { - SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; - - TRACE("%p\n", phContext); - - if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION; - return ret; + TRACE("%#lx, %p, %p\n", version, dll_function_table, user_functions); + return STATUS_SUCCESS; }
-/*********************************************************************** - * MakeSignature - */ -static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, - ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) +static NTSTATUS NTAPI nego_SpMakeSignature( LSA_SEC_HANDLE context, ULONG quality_of_protection, + SecBufferDesc *message, ULONG message_seq_no ) { SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; struct sec_handle *ctxt;
- TRACE("%p, 0x%08lx, %p, %lu\n", phContext, fQOP, pMessage, MessageSeqNo); + TRACE( "%Ix, %#lx, %p, %lu\n", context, quality_of_protection, message, message_seq_no );
- if (!phContext) return SEC_E_INVALID_HANDLE; + if (!context) return SEC_E_INVALID_HANDLE;
- ctxt = (struct sec_handle *)phContext->dwLower; - if (ctxt->krb) + ctxt = (struct sec_handle *)context; + if (ctxt->user_krb) { - ret = ctxt->krb->fnTableW.MakeSignature( &ctxt->handle_krb, fQOP, pMessage, MessageSeqNo ); + ret = ctxt->user_krb->MakeSignature( ctxt->handle_krb, quality_of_protection, message, message_seq_no ); } - else if (ctxt->ntlm) + else if (ctxt->user_ntlm) { - ret = ctxt->ntlm->fnTableW.MakeSignature( &ctxt->handle_ntlm, fQOP, pMessage, MessageSeqNo ); + ret = ctxt->user_ntlm->MakeSignature( ctxt->handle_ntlm, quality_of_protection, message, message_seq_no ); } return ret; }
-/*********************************************************************** - * VerifySignature - */ -static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext, - PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +static NTSTATUS NTAPI nego_SpVerifySignature( LSA_SEC_HANDLE context, SecBufferDesc *message, + ULONG message_seq_no, ULONG *quality_of_protection ) { SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; struct sec_handle *ctxt;
- TRACE("%p, %p, %lu, %p\n", phContext, pMessage, MessageSeqNo, pfQOP); + TRACE( "%Ix, %p, %lu, %p\n", context, message, message_seq_no, quality_of_protection );
- if (!phContext) return SEC_E_INVALID_HANDLE; + if (!context) return SEC_E_INVALID_HANDLE;
- ctxt = (struct sec_handle *)phContext->dwLower; - if (ctxt->krb) + ctxt = (struct sec_handle *)context; + if (ctxt->user_krb) { - ret = ctxt->krb->fnTableW.VerifySignature( &ctxt->handle_krb, pMessage, MessageSeqNo, pfQOP ); + ret = ctxt->user_krb->VerifySignature( ctxt->handle_krb, message, message_seq_no, quality_of_protection ); } - else if (ctxt->ntlm) + else if (ctxt->user_ntlm) { - ret = ctxt->ntlm->fnTableW.VerifySignature( &ctxt->handle_ntlm, pMessage, MessageSeqNo, pfQOP ); + ret = ctxt->user_ntlm->VerifySignature( ctxt->handle_ntlm, message, message_seq_no, quality_of_protection ); } return ret; }
-/*********************************************************************** - * FreeCredentialsHandle - */ -static SECURITY_STATUS SEC_ENTRY nego_FreeCredentialsHandle(PCredHandle phCredential) -{ - struct sec_handle *cred; - - TRACE("%p\n", phCredential); - - if (!phCredential) return SEC_E_INVALID_HANDLE; - - cred = (struct sec_handle *)phCredential->dwLower; - if (cred->krb) cred->krb->fnTableW.FreeCredentialsHandle( &cred->handle_krb ); - if (cred->ntlm) cred->ntlm->fnTableW.FreeCredentialsHandle( &cred->handle_ntlm ); - - free( cred ); - return SEC_E_OK; -} - -/*********************************************************************** - * EncryptMessage - */ -static SECURITY_STATUS SEC_ENTRY nego_EncryptMessage(PCtxtHandle phContext, - ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) +static NTSTATUS NTAPI nego_SpSealMessage( LSA_SEC_HANDLE context, ULONG quality_of_protection, + SecBufferDesc *message, ULONG message_seq_no ) { SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; struct sec_handle *ctxt;
- TRACE("%p, 0x%08lx, %p, %lu\n", phContext, fQOP, pMessage, MessageSeqNo); + TRACE( "%Ix, %#lx, %p, %lu\n", context, quality_of_protection, message, message_seq_no );
- if (!phContext) return SEC_E_INVALID_HANDLE; + if (!context) return SEC_E_INVALID_HANDLE;
- ctxt = (struct sec_handle *)phContext->dwLower; - if (ctxt->krb) + ctxt = (struct sec_handle *)context; + if (ctxt->user_krb) { - ret = ctxt->krb->fnTableW.EncryptMessage( &ctxt->handle_krb, fQOP, pMessage, MessageSeqNo ); + ret = ctxt->user_krb->SealMessage( ctxt->handle_krb, quality_of_protection, message, message_seq_no ); } - else if (ctxt->ntlm) + else if (ctxt->user_ntlm) { - ret = ctxt->ntlm->fnTableW.EncryptMessage( &ctxt->handle_ntlm, fQOP, pMessage, MessageSeqNo ); + ret = ctxt->user_ntlm->SealMessage( ctxt->handle_ntlm, quality_of_protection, message, message_seq_no ); } return ret; }
-/*********************************************************************** - * DecryptMessage - */ -static SECURITY_STATUS SEC_ENTRY nego_DecryptMessage(PCtxtHandle phContext, - PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +static NTSTATUS NTAPI nego_SpUnsealMessage( LSA_SEC_HANDLE context, SecBufferDesc *message, + ULONG message_seq_no, ULONG *quality_of_protection ) { SECURITY_STATUS ret = SEC_E_INVALID_HANDLE; struct sec_handle *ctxt;
- TRACE("%p, %p, %lu, %p\n", phContext, pMessage, MessageSeqNo, pfQOP); + TRACE( "%Ix, %p, %lu, %p\n", context, message, message_seq_no, quality_of_protection );
- if (!phContext) return SEC_E_INVALID_HANDLE; + if (!context) return SEC_E_INVALID_HANDLE;
- ctxt = (struct sec_handle *)phContext->dwLower; - if (ctxt->krb) + ctxt = (struct sec_handle *)context; + if (ctxt->user_krb) { - ret = ctxt->krb->fnTableW.DecryptMessage( &ctxt->handle_krb, pMessage, MessageSeqNo, pfQOP ); + ret = ctxt->user_krb->UnsealMessage( ctxt->handle_krb, message, message_seq_no, quality_of_protection ); } - else if (ctxt->ntlm) + else if (ctxt->user_ntlm) { - ret = ctxt->ntlm->fnTableW.DecryptMessage( &ctxt->handle_ntlm, pMessage, MessageSeqNo, pfQOP ); + ret = ctxt->user_ntlm->UnsealMessage( ctxt->handle_ntlm, message, message_seq_no, quality_of_protection ); } return ret; }
-static const SecurityFunctionTableA negoTableA = { - 1, - NULL, /* EnumerateSecurityPackagesA */ - nego_QueryCredentialsAttributesA, /* QueryCredentialsAttributesA */ - nego_AcquireCredentialsHandleA, /* AcquireCredentialsHandleA */ - nego_FreeCredentialsHandle, /* FreeCredentialsHandle */ - NULL, /* Reserved2 */ - nego_InitializeSecurityContextA, /* InitializeSecurityContextA */ - nego_AcceptSecurityContext, /* AcceptSecurityContext */ - nego_CompleteAuthToken, /* CompleteAuthToken */ - nego_DeleteSecurityContext, /* DeleteSecurityContext */ - nego_ApplyControlToken, /* ApplyControlToken */ - nego_QueryContextAttributesA, /* QueryContextAttributesA */ - nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */ - nego_RevertSecurityContext, /* RevertSecurityContext */ - nego_MakeSignature, /* MakeSignature */ - nego_VerifySignature, /* VerifySignature */ - FreeContextBuffer, /* FreeContextBuffer */ - NULL, /* QuerySecurityPackageInfoA */ - NULL, /* Reserved3 */ - NULL, /* Reserved4 */ - NULL, /* ExportSecurityContext */ - NULL, /* ImportSecurityContextA */ - NULL, /* AddCredentialsA */ - NULL, /* Reserved8 */ - NULL, /* QuerySecurityContextToken */ - nego_EncryptMessage, /* EncryptMessage */ - nego_DecryptMessage, /* DecryptMessage */ - NULL, /* SetContextAttributesA */ -}; - -static const SecurityFunctionTableW negoTableW = { - 1, - NULL, /* EnumerateSecurityPackagesW */ - nego_QueryCredentialsAttributesW, /* QueryCredentialsAttributesW */ - nego_AcquireCredentialsHandleW, /* AcquireCredentialsHandleW */ - nego_FreeCredentialsHandle, /* FreeCredentialsHandle */ - NULL, /* Reserved2 */ - nego_InitializeSecurityContextW, /* InitializeSecurityContextW */ - nego_AcceptSecurityContext, /* AcceptSecurityContext */ - nego_CompleteAuthToken, /* CompleteAuthToken */ - nego_DeleteSecurityContext, /* DeleteSecurityContext */ - nego_ApplyControlToken, /* ApplyControlToken */ - nego_QueryContextAttributesW, /* QueryContextAttributesW */ - nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */ - nego_RevertSecurityContext, /* RevertSecurityContext */ - nego_MakeSignature, /* MakeSignature */ - nego_VerifySignature, /* VerifySignature */ - FreeContextBuffer, /* FreeContextBuffer */ - NULL, /* QuerySecurityPackageInfoW */ - NULL, /* Reserved3 */ - NULL, /* Reserved4 */ - NULL, /* ExportSecurityContext */ - NULL, /* ImportSecurityContextW */ - NULL, /* AddCredentialsW */ - NULL, /* Reserved8 */ - NULL, /* QuerySecurityContextToken */ - nego_EncryptMessage, /* EncryptMessage */ - nego_DecryptMessage, /* DecryptMessage */ - NULL, /* SetContextAttributesW */ +static SECPKG_USER_FUNCTION_TABLE nego_user_table = +{ + nego_SpInstanceInit, + NULL, /* SpInitUserModeContext */ + nego_SpMakeSignature, + nego_SpVerifySignature, + nego_SpSealMessage, + nego_SpUnsealMessage, + NULL, /* SpGetContextToken */ + NULL, /* SpQueryContextAttributes */ + NULL, /* SpCompleteAuthToken */ + NULL, /* SpDeleteContext */ + NULL, /* SpFormatCredentialsFn */ + NULL, /* SpMarshallSupplementalCreds */ + NULL, /* SpExportSecurityContext */ + NULL /* SpImportSecurityContext */ };
-#define NEGO_MAX_TOKEN 12000 - -static WCHAR nego_name_W[] = {'N','e','g','o','t','i','a','t','e',0}; -static char nego_name_A[] = "Negotiate"; - -static WCHAR negotiate_comment_W[] = - {'M','i','c','r','o','s','o','f','t',' ','P','a','c','k','a','g','e',' ', - 'N','e','g','o','t','i','a','t','o','r',0}; -static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator"; - -#define CAPS ( \ - SECPKG_FLAG_INTEGRITY | \ - SECPKG_FLAG_PRIVACY | \ - SECPKG_FLAG_CONNECTION | \ - SECPKG_FLAG_MULTI_REQUIRED | \ - SECPKG_FLAG_EXTENDED_ERROR | \ - SECPKG_FLAG_IMPERSONATION | \ - SECPKG_FLAG_ACCEPT_WIN32_NAME | \ - SECPKG_FLAG_NEGOTIABLE | \ - SECPKG_FLAG_GSS_COMPATIBLE | \ - SECPKG_FLAG_LOGON | \ - SECPKG_FLAG_RESTRICTED_TOKENS ) - -void SECUR32_initNegotiateSP(void) +NTSTATUS NTAPI nego_SpUserModeInitialize(ULONG lsa_version, PULONG package_version, + PSECPKG_USER_FUNCTION_TABLE *table, PULONG table_count) { - SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW, NULL); + TRACE("%#lx, %p, %p, %p\n", lsa_version, package_version, table, table_count);
- const SecPkgInfoW infoW = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN, - nego_name_W, negotiate_comment_W}; - const SecPkgInfoA infoA = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN, - nego_name_A, negotiate_comment_A}; - SECUR32_addPackages(provider, 1L, &infoA, &infoW); + *package_version = SECPKG_INTERFACE_VERSION; + *table = &nego_user_table; + *table_count = 1; + return STATUS_SUCCESS; } diff --git a/dlls/secur32/secur32.c b/dlls/secur32/secur32.c index d703757bae7..46a80c9a76c 100644 --- a/dlls/secur32/secur32.c +++ b/dlls/secur32/secur32.c @@ -501,10 +501,6 @@ static void SECUR32_initializeProviders(void) SECUR32_initSchannelSP(); /* Load SSP/AP packages (Kerberos and others) */ 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 */ apiRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\CurrentControlSet\Control\SecurityProviders", 0, KEY_READ, &key); diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h index 1275a713896..0b410c9970c 100644 --- a/dlls/secur32/secur32_priv.h +++ b/dlls/secur32/secur32_priv.h @@ -24,6 +24,8 @@ #include <sys/types.h> #include <limits.h> #include "schannel.h" +#include "ntsecapi.h" +#include "ntsecpkg.h" #include "wine/list.h"
typedef struct _SecureProvider @@ -70,8 +72,10 @@ SecurePackage *SECUR32_findPackageA(PCSTR packageName) DECLSPEC_HIDDEN;
/* Initialization functions for built-in providers */ void SECUR32_initSchannelSP(void) DECLSPEC_HIDDEN; -void SECUR32_initNegotiateSP(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 */ void SECUR32_deinitSchannelSP(void) DECLSPEC_HIDDEN;
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/secur32/lsa.c | 6 +++++- dlls/secur32/negotiate.c | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/dlls/secur32/lsa.c b/dlls/secur32/lsa.c index 857c7d451d0..745b97d35a9 100644 --- a/dlls/secur32/lsa.c +++ b/dlls/secur32/lsa.c @@ -98,6 +98,10 @@ NTSTATUS WINAPI LsaCallAuthenticationPackage(HANDLE lsa_handle, ULONG package_id TRACE("%p,%lu,%p,%lu,%p,%p,%p\n", lsa_handle, package_id, in_buffer, in_buffer_length, out_buffer, out_buffer_length, status);
+ if (out_buffer) *out_buffer = NULL; + if (out_buffer_length) *out_buffer_length = 0; + if (status) *status = STATUS_SUCCESS; + for (i = 0; i < loaded_packages_count; i++) { if (loaded_packages[i].package_id == package_id) @@ -110,7 +114,7 @@ NTSTATUS WINAPI LsaCallAuthenticationPackage(HANDLE lsa_handle, ULONG package_id } }
- return STATUS_INVALID_PARAMETER; + return STATUS_NO_SUCH_PACKAGE; }
static struct lsa_handle *alloc_lsa_handle(ULONG magic) diff --git a/dlls/secur32/negotiate.c b/dlls/secur32/negotiate.c index c5d89a38228..323d14e9eaa 100644 --- a/dlls/secur32/negotiate.c +++ b/dlls/secur32/negotiate.c @@ -71,9 +71,23 @@ static WCHAR negotiate_comment_W[] = static NTSTATUS NTAPI nego_LsaApCallPackageUntrusted( PLSA_CLIENT_REQUEST req, void *in_buf, void *client_buf_base, ULONG in_buf_len, void **out_buf, ULONG *out_buf_len, NTSTATUS *ret_status ) { + ULONG *MessageType; + FIXME("%p, %p, %p, %lu, %p, %p, %p: stub\n", req, in_buf, client_buf_base, in_buf_len, out_buf, out_buf_len, ret_status);
- return SEC_E_UNSUPPORTED_FUNCTION; + if (!in_buf || in_buf_len < sizeof(*MessageType) || !out_buf || !out_buf_len || !ret_status) + return STATUS_INVALID_PARAMETER; + + MessageType = in_buf; + switch (*MessageType) + { + case 1: /* NegGetCallerName */ + *ret_status = STATUS_NO_SUCH_LOGON_SESSION; + return STATUS_SUCCESS; + + default: + return SEC_E_UNSUPPORTED_FUNCTION; + } }
static NTSTATUS NTAPI nego_LsaApInitializePackage( ULONG package_id, PLSA_DISPATCH_TABLE dispatch,
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/secur32/tests/negotiate.c | 66 ++++++++++++++++++++++++++++++++++ include/ntsecapi.h | 21 +++++++++++ 2 files changed, 87 insertions(+)
diff --git a/dlls/secur32/tests/negotiate.c b/dlls/secur32/tests/negotiate.c index 22a0e7793df..385615a18be 100644 --- a/dlls/secur32/tests/negotiate.c +++ b/dlls/secur32/tests/negotiate.c @@ -21,6 +21,9 @@
#include <stdarg.h> #include <stdio.h> + +#include <ntstatus.h> +#define WIN32_NO_STATUS #include <windef.h> #include <winbase.h> #define SECURITY_WIN32 @@ -28,6 +31,9 @@ #include <rpc.h> #include <rpcdce.h> #include <secext.h> +#include <security.h> +#include <ntsecapi.h> +#include <winternl.h>
#include "wine/test.h"
@@ -346,6 +352,65 @@ done: } }
+static void test_Negotiate(void) +{ + HANDLE lsa; + NTSTATUS status, call_status; + LSA_STRING name; + ULONG size, id; + NEGOTIATE_CALLER_NAME_REQUEST req; + NEGOTIATE_CALLER_NAME_RESPONSE *resp; + + status = LsaConnectUntrusted(&lsa); + ok(!status, "got %08lx\n", status); + + RtlInitAnsiString(&name, "Negotiate"); + id = 0xdeadbeef; + status = LsaLookupAuthenticationPackage(lsa, &name, &id); + ok(!status, "got %08lx\n", status); + ok(id == 0, "got %lu\n", id); + + req.MessageType = NegGetCallerName; + req.LogonId.LowPart = 0; + req.LogonId.HighPart = 0; + resp = (void *)(ULONG_PTR)0xdeadbeef; + size = 0xdeadbeef; + call_status = 0xdeadbeef; + status = LsaCallAuthenticationPackage(lsa, 0, &req, sizeof(req), (void **)&resp, &size, &call_status); + ok(status == STATUS_SUCCESS, "got %08lx\n", status); + ok(call_status == STATUS_NO_SUCH_LOGON_SESSION, "got %08lx\n", call_status); + ok(size == 0, "got %lu\n", size); + ok(resp == NULL, "got %p\n", resp); + + size = 0xdeadbeef; + call_status = 0xdeadbeef; + status = LsaCallAuthenticationPackage(lsa, 0, NULL, 0, NULL, &size, &call_status); + ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status); + ok(call_status == STATUS_SUCCESS, "got %08lx\n", call_status); + ok(size == 0, "got %08lx\n", size); + + size = 0xdeadbeef; + status = LsaCallAuthenticationPackage(lsa, 0, NULL, 0, NULL, &size, NULL); + ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status); + ok(size == 0, "got %08lx\n", size); + + call_status = 0xdeadbeef; + status = LsaCallAuthenticationPackage(lsa, 0, NULL, 0, NULL, NULL, &call_status); + ok(status == STATUS_INVALID_PARAMETER, "got %08lx\n", status); + ok(call_status == STATUS_SUCCESS, "got %08lx\n", call_status); + + resp = (void *)(ULONG_PTR)0xdeadbeef; + size = 0xdeadbeef; + call_status = 0xdeadbeef; + status = LsaCallAuthenticationPackage(lsa, 0xdeadbeef, NULL, 0, (void **)&resp, &size, &call_status); + ok(status == STATUS_NO_SUCH_PACKAGE, "got %08lx\n", status); + ok(call_status == STATUS_SUCCESS, "got %08lx\n", call_status); + ok(size == 0, "got %08lx\n", size); + ok(resp == NULL, "got %p\n", resp); + + LsaDeregisterLogonProcess(lsa); +} + START_TEST(negotiate) { SecPkgInfoA *info; @@ -367,4 +432,5 @@ START_TEST(negotiate) FreeContextBuffer( info );
test_authentication(); + test_Negotiate(); } diff --git a/include/ntsecapi.h b/include/ntsecapi.h index 992aebf66d2..ded31b41e56 100644 --- a/include/ntsecapi.h +++ b/include/ntsecapi.h @@ -356,6 +356,27 @@ typedef struct _AUDIT_POLICY_INFORMATION GUID AuditCategoryGuid; } AUDIT_POLICY_INFORMATION, *PAUDIT_POLICY_INFORMATION;
+enum NEGOTIATE_MESSAGES +{ + NegEnumPackagePrefixes, + NegGetCallerName, + NegTransferCredentials, + NegMsgReserved1, + NegCallPackageMax +}; + +typedef struct _NEGOTIATE_CALLER_NAME_REQUEST +{ + ULONG MessageType; + LUID LogonId; +} NEGOTIATE_CALLER_NAME_REQUEST, *PNEGOTIATE_CALLER_NAME_REQUEST; + +typedef struct _NEGOTIATE_CALLER_NAME_RESPONSE +{ + ULONG MessageType; + PWSTR CallerName; +} NEGOTIATE_CALLER_NAME_RESPONSE, *PNEGOTIATE_CALLER_NAME_RESPONSE; + #define MICROSOFT_KERBEROS_NAME_A "Kerberos" #if defined(_MSC_VER) || defined(__MINGW32__) #define MICROSOFT_KERBEROS_NAME_W L"Kerberos"
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=135560
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 40 negotiate.c:383: Test failed: got 003D0000
=== w7u_el (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 40 negotiate.c:383: Test failed: got 00280000
=== w8 (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 38 negotiate.c:383: Test failed: got 004A0000
=== w864 (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 50 negotiate.c:383: Test failed: got 00350000
=== w1064v1507 (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 52 negotiate.c:383: Test failed: got 003D0000
=== w1064v1809 (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 52 negotiate.c:383: Test failed: got 001B0000
=== w1064_tsign (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 52 negotiate.c:383: Test failed: got 001F0000
=== w10pro64 (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 58 negotiate.c:383: Test failed: got 00110000
=== w11pro64 (32 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 58 negotiate.c:383: Test failed: got 00950000
=== w7pro64 (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 56 negotiate.c:383: Test failed: got 00000000002C0000
=== w864 (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 50 negotiate.c:383: Test failed: got 00000000002F0000
=== w1064v1507 (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 52 negotiate.c:383: Test failed: got 0000000000020000
=== w1064v1809 (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 52 negotiate.c:383: Test failed: got 0000000000020000
=== w1064_2qxl (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 52 negotiate.c:383: Test failed: got 00000000001A0000
=== w1064_tsign (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 52 negotiate.c:383: Test failed: got 00000000001A0000
=== w10pro64 (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 58 negotiate.c:383: Test failed: got 00000000001B0000
=== w10pro64_en_AE_u8 (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 58 negotiate.c:383: Test failed: got 00000000001D0000
=== w10pro64_ar (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 58 negotiate.c:383: Test failed: got 00000000001A0000
=== w10pro64_ja (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 58 negotiate.c:383: Test failed: got 00000000001A0000
=== w10pro64_zh_CN (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 58 negotiate.c:383: Test failed: got 00000000001D0000
=== w11pro64_amd (64 bit report) ===
secur32: negotiate.c:381: Test failed: got 00000000 negotiate.c:382: Test failed: got 58 negotiate.c:383: Test failed: got 00000000006E0000