diff --git a/dlls/secur32/secur32.spec b/dlls/secur32/secur32.spec index 8135958fd2a..0d6895ac305 100644 --- a/dlls/secur32/secur32.spec +++ b/dlls/secur32/secur32.spec @@ -73,6 +73,7 @@ @ stdcall SspiEncodeStringsAsAuthIdentity(wstr wstr wstr ptr) sspicli.SspiEncodeStringsAsAuthIdentity @ stdcall SspiFreeAuthIdentity(ptr) sspicli.SspiFreeAuthIdentity @ stdcall SspiLocalFree(ptr) sspicli.SspiLocalFree +@ stdcall SspiPrepareForCredWrite(ptr wstr ptr ptr ptr ptr ptr) sspicli.SspiPrepareForCredWrite @ stdcall SspiZeroAuthIdentity(ptr) sspicli.SspiZeroAuthIdentity @ stdcall TranslateNameA(str long long ptr ptr) @ stdcall TranslateNameW(wstr long long ptr ptr) diff --git a/dlls/secur32/tests/secur32.c b/dlls/secur32/tests/secur32.c index 49103bdea3f..df9e627f8ea 100644 --- a/dlls/secur32/tests/secur32.c +++ b/dlls/secur32/tests/secur32.c @@ -27,6 +27,7 @@ #define SECURITY_WIN32 #include #include +#include #include "wine/test.h" @@ -40,6 +41,8 @@ static void (SEC_ENTRY *pSspiFreeAuthIdentity) (PSEC_WINNT_AUTH_IDENTITY_OPAQUE); static void (SEC_ENTRY *pSspiLocalFree) (void *); +static SECURITY_STATUS (SEC_ENTRY *pSspiPrepareForCredWrite) + (PSEC_WINNT_AUTH_IDENTITY_OPAQUE, PCWSTR, PULONG, PCWSTR *, PCWSTR *, PUCHAR *, PULONG); static void (SEC_ENTRY *pSspiZeroAuthIdentity) (PSEC_WINNT_AUTH_IDENTITY_OPAQUE); @@ -317,6 +320,60 @@ static void test_SspiEncodeStringsAsAuthIdentity(void) pSspiFreeAuthIdentity( id ); } +static void test_SspiPrepareForCredWrite(void) +{ + static const WCHAR usernameW[] = + {'u','s','e','r','n','a','m','e',0}; + static const WCHAR domainnameW[] = + {'d','o','m','a','i','n','n','a','m','e',0}; + static const WCHAR passwordW[] = + {'p','a','s','s','w','o','r','d',0}; + static const WCHAR targetW[] = + {'d','o','m','a','i','n','n','a','m','e','\\','u','s','e','r','n','a','m','e',0}; + static const WCHAR target2W[] = + {'d','o','m','a','i','n','n','a','m','e','2','\\','u','s','e','r','n','a','m','e','2',0}; + const WCHAR *target, *username; + PSEC_WINNT_AUTH_IDENTITY_OPAQUE id; + SECURITY_STATUS status; + ULONG type, size; + UCHAR *blob; + + if (!pSspiPrepareForCredWrite) + { + win_skip( "SspiPrepareForCredWrite not exported by secur32.dll\n" ); + return; + } + + status = pSspiEncodeStringsAsAuthIdentity( usernameW, domainnameW, passwordW, &id ); + ok( status == SEC_E_OK, "got %08x\n", status ); + + type = size = 0; + status = pSspiPrepareForCredWrite( id, NULL, &type, &target, &username, &blob, &size ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( type == CRED_TYPE_DOMAIN_PASSWORD, "got %u\n", type ); + ok( !lstrcmpW( target, targetW ), "got %s\n", wine_dbgstr_w(target) ); + ok( !lstrcmpW( username, targetW ), "got %s\n", wine_dbgstr_w(username) ); + ok( !memcmp( blob, passwordW, sizeof(passwordW) - sizeof(WCHAR) ), "wrong data\n" ); + ok( size == sizeof(passwordW) - sizeof(WCHAR), "got %u\n", size ); + pSspiLocalFree( (void *)target ); + pSspiLocalFree( (void *)username ); + pSspiLocalFree( blob ); + + type = size = 0; + status = pSspiPrepareForCredWrite( id, target2W, &type, &target, &username, &blob, &size ); + ok( status == SEC_E_OK, "got %08x\n", status ); + ok( type == CRED_TYPE_DOMAIN_PASSWORD, "got %u\n", type ); + ok( !lstrcmpW( target, target2W ), "got %s\n", wine_dbgstr_w(target) ); + ok( !lstrcmpW( username, targetW ), "got %s\n", wine_dbgstr_w(username) ); + ok( !memcmp( blob, passwordW, sizeof(passwordW) - sizeof(WCHAR) ), "wrong data\n" ); + ok( size == sizeof(passwordW) - sizeof(WCHAR), "got %u\n", size ); + pSspiLocalFree( (void *)target ); + pSspiLocalFree( (void *)username ); + pSspiLocalFree( blob ); + + pSspiFreeAuthIdentity( id ); +} + static void test_kerberos(void) { SecPkgInfoA *info; @@ -379,6 +436,7 @@ START_TEST(secur32) pSspiEncodeStringsAsAuthIdentity = (void *)GetProcAddress(secdll, "SspiEncodeStringsAsAuthIdentity"); pSspiFreeAuthIdentity = (void *)GetProcAddress(secdll, "SspiFreeAuthIdentity"); pSspiLocalFree = (void *)GetProcAddress(secdll, "SspiLocalFree"); + pSspiPrepareForCredWrite = (void *)GetProcAddress(secdll, "SspiPrepareForCredWrite"); pSspiZeroAuthIdentity = (void *)GetProcAddress(secdll, "SspiZeroAuthIdentity"); pGetComputerObjectNameA = (PVOID)GetProcAddress(secdll, "GetComputerObjectNameA"); pGetComputerObjectNameW = (PVOID)GetProcAddress(secdll, "GetComputerObjectNameW"); @@ -386,7 +444,7 @@ START_TEST(secur32) pGetUserNameExW = (PVOID)GetProcAddress(secdll, "GetUserNameExW"); pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA"); pInitSecurityInterfaceW = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceW"); - + if (pGetComputerObjectNameA) testGetComputerObjectNameA(); else @@ -409,6 +467,7 @@ START_TEST(secur32) test_InitSecurityInterface(); test_SspiEncodeStringsAsAuthIdentity(); + test_SspiPrepareForCredWrite(); FreeLibrary(secdll); } diff --git a/dlls/sspicli/main.c b/dlls/sspicli/main.c index 34f0a643745..dfcc1cc02fb 100644 --- a/dlls/sspicli/main.c +++ b/dlls/sspicli/main.c @@ -22,6 +22,7 @@ #include "winbase.h" #include "rpc.h" #include "sspi.h" +#include "wincred.h" #include "wine/debug.h" #include "wine/unicode.h" @@ -140,3 +141,59 @@ void SEC_ENTRY SspiLocalFree( void *ptr ) TRACE( "%p\n", ptr ); HeapFree( GetProcessHeap(), 0, ptr ); } + +/*********************************************************************** + * SspiPrepareForCredWrite (SECUR32.0) + */ +SECURITY_STATUS SEC_ENTRY SspiPrepareForCredWrite( PSEC_WINNT_AUTH_IDENTITY_OPAQUE opaque_id, + PCWSTR target, PULONG type, PCWSTR *targetname, PCWSTR *username, PUCHAR *blob, PULONG size ) +{ + SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)opaque_id; + WCHAR *str, *str2; + UCHAR *password; + ULONG len; + + FIXME( "%p %s %p %p %p %p %p\n", opaque_id, debugstr_w(target), type, targetname, username, + blob, size ); + + if (id->DomainLength) + { + len = (id->DomainLength + id->UserLength + 2) * sizeof(WCHAR); + if (!(str = HeapAlloc(GetProcessHeap(), 0 , len ))) return SEC_E_INSUFFICIENT_MEMORY; + memcpy( str, id->Domain, id->DomainLength * sizeof(WCHAR) ); + str[id->DomainLength] = '\\'; + memcpy( str + id->DomainLength + 1, id->User, id->UserLength * sizeof(WCHAR) ); + str[id->DomainLength + 1 + id->UserLength] = 0; + } + else + { + len = (id->UserLength + 1) * sizeof(WCHAR); + if (!(str = HeapAlloc(GetProcessHeap(), 0 , len ))) return SEC_E_INSUFFICIENT_MEMORY; + memcpy( str, id->User, id->UserLength * sizeof(WCHAR) ); + str[id->UserLength] = 0; + } + + str2 = target ? strdupW( target ) : strdupW( str ); + if (!str2) + { + HeapFree( GetProcessHeap(), 0, str ); + return SEC_E_INSUFFICIENT_MEMORY; + } + + len = id->PasswordLength * sizeof(WCHAR); + if (!(password = HeapAlloc(GetProcessHeap(), 0 , len ))) + { + HeapFree( GetProcessHeap(), 0, str ); + HeapFree( GetProcessHeap(), 0, str2 ); + return SEC_E_INSUFFICIENT_MEMORY; + } + memcpy( password, id->Password, len ); + + *type = CRED_TYPE_DOMAIN_PASSWORD; + *username = str; + *targetname = str2; + *blob = password; + *size = len; + + return SEC_E_OK; +} diff --git a/dlls/sspicli/sspicli.spec b/dlls/sspicli/sspicli.spec index 8876bc07226..e18d359a4b0 100644 --- a/dlls/sspicli/sspicli.spec +++ b/dlls/sspicli/sspicli.spec @@ -95,7 +95,7 @@ @ stdcall SspiLocalFree(ptr) @ stub SspiMarshalAuthIdentity @ stub SspiPrepareForCredRead -@ stub SspiPrepareForCredWrite +@ stdcall SspiPrepareForCredWrite(ptr wstr ptr ptr ptr ptr ptr) @ stub SspiUnmarshalAuthIdentity @ stub SspiUnmarshalAuthIdentityInternal @ stub SspiValidateAuthIdentity diff --git a/include/sspi.h b/include/sspi.h index 9e44a6d3420..0e248fbef05 100644 --- a/include/sspi.h +++ b/include/sspi.h @@ -98,6 +98,9 @@ SECURITY_STATUS SEC_ENTRY SspiEncodeAuthIdentityAsStrings( SECURITY_STATUS SEC_ENTRY SspiEncodeStringsAsAuthIdentity( PCWSTR, PCWSTR, PCWSTR, PSEC_WINNT_AUTH_IDENTITY_OPAQUE *); +SECURITY_STATUS SEC_ENTRY SspiPrepareForCredWrite( + PSEC_WINNT_AUTH_IDENTITY_OPAQUE, PCWSTR, PULONG, PCWSTR*, PCWSTR*, PUCHAR*, PULONG); + ULONG SEC_ENTRY SspiPromptForCredentialsA(PCSTR, void *, ULONG, PCSTR, PSEC_WINNT_AUTH_IDENTITY_OPAQUE, PSEC_WINNT_AUTH_IDENTITY_OPAQUE *, int *, ULONG);