[PATCH 0/1] MR10749: secur32: Handle SEC_WINNT_AUTH_IDENTITY_EX in the Negotiate provider.
From: Hans Leidekker <hans@codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59689 --- dlls/secur32/negotiate.c | 49 +++++++++++++++++++++++++++++++--- dlls/secur32/tests/negotiate.c | 40 +++++++++++++++++++++++++++ include/sspi.h | 32 ++++++++++++++++++++++ 3 files changed, 118 insertions(+), 3 deletions(-) diff --git a/dlls/secur32/negotiate.c b/dlls/secur32/negotiate.c index 3cc71b17d0d..c9a254d15a9 100644 --- a/dlls/secur32/negotiate.c +++ b/dlls/secur32/negotiate.c @@ -138,23 +138,66 @@ static NTSTATUS NTAPI nego_SpGetInfo( SecPkgInfoW *info ) return STATUS_SUCCESS; } +static NTSTATUS map_auth_data( const void *auth_data, SEC_WINNT_AUTH_IDENTITY_W *id ) +{ + const SEC_WINNT_AUTH_IDENTITY_EXA *exA = auth_data; + const SEC_WINNT_AUTH_IDENTITY_EXW *exW = auth_data; + + if (exW->Version != SEC_WINNT_AUTH_IDENTITY_VERSION) + { + *id = *(SEC_WINNT_AUTH_IDENTITY_W *)auth_data; + return SEC_E_OK; + } + if (exW->Flags == SEC_WINNT_AUTH_IDENTITY_UNICODE) + { + id->User = exW->User; + id->UserLength = exW->UserLength; + id->Domain = exW->Domain; + id->DomainLength = exW->DomainLength; + id->Password = exW->Password; + id->PasswordLength = exW->PasswordLength; + id->Flags = exW->Flags; + if (exW->PackageList) + FIXME( "ignoring package list %s\n", debugstr_wn(exW->PackageList, exW->PackageListLength) ); + } + else + { + SEC_WINNT_AUTH_IDENTITY_A *idA = (SEC_WINNT_AUTH_IDENTITY_A *)id; + + idA->User = exA->User; + idA->UserLength = exA->UserLength; + idA->Domain = exA->Domain; + idA->DomainLength = exA->DomainLength; + idA->Password = exA->Password; + idA->PasswordLength = exA->PasswordLength; + idA->Flags = exA->Flags; + if (exA->PackageList) + FIXME( "ignoring package list %s\n", debugstr_an((const char *)exA->PackageList, exA->PackageListLength) ); + } + return SEC_E_OK; +} + 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; + NTSTATUS ret; struct sec_handle *cred; SECPKG_FUNCTION_TABLE *package; SECPKG_USER_FUNCTION_TABLE *user; + SEC_WINNT_AUTH_IDENTITY_W id; 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 (auth_data && (ret = map_auth_data( auth_data, &id ))) return ret; + if (!(cred = calloc( 1, sizeof(*cred) ))) return SEC_E_INSUFFICIENT_MEMORY; + ret = SEC_E_NO_CREDENTIALS; if ((package = lsa_find_package( "Kerberos", &user ))) { - ret = package->SpAcquireCredentialsHandle( principal_us, credential_use, logon_id, auth_data, + ret = package->SpAcquireCredentialsHandle( principal_us, credential_use, logon_id, auth_data ? &id : NULL, get_key_fn, get_key_arg, &cred->handle_krb, expiry ); if (ret == SEC_E_OK) { @@ -167,7 +210,7 @@ static NTSTATUS NTAPI nego_SpAcquireCredentialsHandle( { ULONG cred_use = auth_data ? credential_use : credential_use | WINE_NO_CACHED_CREDENTIALS; - ret = package->SpAcquireCredentialsHandle( principal_us, cred_use, logon_id, auth_data, + ret = package->SpAcquireCredentialsHandle( principal_us, cred_use, logon_id, auth_data ? &id : NULL, get_key_fn, get_key_arg, &cred->handle_ntlm, expiry ); if (ret == SEC_E_OK) { diff --git a/dlls/secur32/tests/negotiate.c b/dlls/secur32/tests/negotiate.c index f2d9324ff97..cc73d52d6f6 100644 --- a/dlls/secur32/tests/negotiate.c +++ b/dlls/secur32/tests/negotiate.c @@ -423,6 +423,45 @@ static void test_Negotiate(void) LsaDeregisterLogonProcess(lsa); } +static void test_AcquireCredentialsHandle( void ) +{ + SECURITY_STATUS status; + SEC_WINNT_AUTH_IDENTITY_EXW id; + CredHandle cred; + + memset( &id, 0, sizeof(id) ); + id.Version = SEC_WINNT_AUTH_IDENTITY_VERSION; + id.Length = sizeof(id); + id.User = (USHORT *)L"winetest"; + id.UserLength = ARRAY_SIZE( L"winetest" ) - 1; + id.Domain = (USHORT *)L"winetest"; + id.DomainLength = ARRAY_SIZE( L"winetest" ) - 1; + id.Password = (USHORT *)L"winetest"; + id.PasswordLength = ARRAY_SIZE( L"winetest" ) - 1; + id.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + id.PackageList = (USHORT *)L"kerberos,!ntlm"; + id.PackageListLength = ARRAY_SIZE( L"kerberos,!ntlm" ) - 1; + + status = AcquireCredentialsHandleW( NULL, (SEC_WCHAR *)L"Negotiate", SECPKG_CRED_OUTBOUND, NULL, &id, NULL, + NULL, &cred, NULL ); + ok( status == SEC_E_OK, "got %#lx\n", status ); + FreeCredentialsHandle( &cred ); + + id.PackageList = (USHORT *)L"nosuch"; + id.PackageListLength = ARRAY_SIZE( L"nosuch" ); + + status = AcquireCredentialsHandleW( NULL, (SEC_WCHAR *)L"Negotiate", SECPKG_CRED_OUTBOUND, NULL, &id, NULL, + NULL, &cred, NULL ); + ok( status == SEC_E_OK, "got %#lx\n", status ); + FreeCredentialsHandle( &cred ); + + id.Length = 0; + status = AcquireCredentialsHandleW( NULL, (SEC_WCHAR *)L"Negotiate", SECPKG_CRED_OUTBOUND, NULL, &id, NULL, + NULL, &cred, NULL ); + ok( status == SEC_E_OK, "got %#lx\n", status ); + FreeCredentialsHandle( &cred ); +} + START_TEST(negotiate) { SecPkgInfoA *info; @@ -446,4 +485,5 @@ START_TEST(negotiate) test_authentication(); test_Negotiate(); + test_AcquireCredentialsHandle(); } diff --git a/include/sspi.h b/include/sspi.h index 6d7ea5a5ef2..2ecfcf21e4b 100644 --- a/include/sspi.h +++ b/include/sspi.h @@ -92,6 +92,38 @@ typedef struct _UNICODE_STRING { typedef UNICODE_STRING SECURITY_STRING, *PSECURITY_STRING; +#define SEC_WINNT_AUTH_IDENTITY_VERSION 0x200 + +typedef struct _SEC_WINNT_AUTH_IDENTITY_EXW +{ + ULONG Version; + ULONG Length; + USHORT *User; + ULONG UserLength; + USHORT *Domain; + ULONG DomainLength; + USHORT *Password; + ULONG PasswordLength; + ULONG Flags; + USHORT *PackageList; + ULONG PackageListLength; +} SEC_WINNT_AUTH_IDENTITY_EXW, *PSEC_WINNT_AUTH_IDENTITY_EXW; + +typedef struct _SEC_WINNT_AUTH_IDENTITY_EXA +{ + ULONG Version; + ULONG Length; + UCHAR *User; + ULONG UserLength; + UCHAR *Domain; + ULONG DomainLength; + UCHAR *Password; + ULONG PasswordLength; + ULONG Flags; + UCHAR *PackageList; + ULONG PackageListLength; +} SEC_WINNT_AUTH_IDENTITY_EXA, *PSEC_WINNT_AUTH_IDENTITY_EXA; + #define SSPIPFC_CREDPROV_DO_NOT_SAVE 0x00000001 #define SSPIPFC_NO_CHECKBOX 0x00000002 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10749
participants (2)
-
Hans Leidekker -
Hans Leidekker (@hans)