Hans Leidekker : advapi32: Write host credentials through mountmgr.
Alexandre Julliard
julliard at winehq.org
Thu Sep 3 15:26:46 CDT 2020
Module: wine
Branch: master
Commit: 98a3986c7d613af8f5c782c7890e2f2ca17926f5
URL: https://source.winehq.org/git/wine.git/?a=commit;h=98a3986c7d613af8f5c782c7890e2f2ca17926f5
Author: Hans Leidekker <hans at codeweavers.com>
Date: Thu Sep 3 14:59:05 2020 +0200
advapi32: Write host credentials through mountmgr.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/advapi32/cred.c | 126 +++++++++++++++++++++++----------------------------
1 file changed, 56 insertions(+), 70 deletions(-)
diff --git a/dlls/advapi32/cred.c b/dlls/advapi32/cred.c
index 07f4b9b03a..c17023959f 100644
--- a/dlls/advapi32/cred.c
+++ b/dlls/advapi32/cred.c
@@ -497,85 +497,73 @@ static DWORD registry_write_credential(HKEY hkey, const CREDENTIALW *credential,
return ret;
}
-#ifdef __APPLE__
-static DWORD mac_write_credential(const CREDENTIALW *credential, BOOL preserve_blob)
+static DWORD host_write_credential( const CREDENTIALW *credential, BOOL preserve_blob )
{
- int status;
- SecKeychainItemRef keychain_item;
- char *username, *password, *servername;
- UInt32 userlen, pwlen, serverlen;
- SecKeychainAttribute attrs[1];
- SecKeychainAttributeList attr_list;
+ struct mountmgr_credential *cred;
+ HANDLE mgr;
+ DWORD size;
+ WCHAR *ptr;
+ BOOL ret;
if (credential->Flags)
- FIXME("Flags 0x%x not written\n", credential->Flags);
+ FIXME( "flags 0x%x not written\n", credential->Flags );
if (credential->Type != CRED_TYPE_DOMAIN_PASSWORD)
- FIXME("credential type of %d not supported\n", credential->Type);
+ FIXME( "credential type of %d not supported\n", credential->Type );
if (credential->Persist != CRED_PERSIST_LOCAL_MACHINE)
- FIXME("persist value of %d not supported\n", credential->Persist);
+ FIXME( "persist value of %d not supported\n", credential->Persist );
if (credential->AttributeCount)
- FIXME("custom attributes not supported\n");
-
- userlen = WideCharToMultiByte(CP_UTF8, 0, credential->UserName, -1, NULL, 0, NULL, NULL);
- username = heap_alloc(userlen * sizeof(*username));
- WideCharToMultiByte(CP_UTF8, 0, credential->UserName, -1, username, userlen, NULL, NULL);
-
- serverlen = WideCharToMultiByte(CP_UTF8, 0, credential->TargetName, -1, NULL, 0, NULL, NULL);
- servername = heap_alloc(serverlen * sizeof(*servername));
- WideCharToMultiByte(CP_UTF8, 0, credential->TargetName, -1, servername, serverlen, NULL, NULL);
- pwlen = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)credential->CredentialBlob,
- credential->CredentialBlobSize / sizeof(WCHAR), NULL, 0, NULL, NULL);
- password = heap_alloc(pwlen * sizeof(*password));
- WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)credential->CredentialBlob,
- credential->CredentialBlobSize / sizeof(WCHAR), password, pwlen, NULL, NULL);
-
- TRACE("adding server %s, username %s using Keychain\n", servername, username);
- status = SecKeychainAddGenericPassword(NULL, strlen(servername), servername, strlen(username),
- username, strlen(password), password, &keychain_item);
- if (status != noErr)
- ERR("SecKeychainAddGenericPassword returned %d\n", status);
- if (status == errSecDuplicateItem)
+ FIXME( "custom attributes not supported\n" );
+
+ if (credential->CredentialBlobSize % sizeof(WCHAR)) return ERROR_NOT_SUPPORTED;
+
+ mgr = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, 0, 0 );
+ if (mgr == INVALID_HANDLE_VALUE) return GetLastError();
+
+ size = sizeof(*cred) + (strlenW( credential->TargetName ) + strlenW( credential->UserName ) + 2) * sizeof(WCHAR);
+ size += credential->CredentialBlobSize;
+ if (credential->Comment) size += (strlenW( credential->Comment ) + 1) * sizeof(WCHAR);
+ if (!(cred = heap_alloc( size )))
{
- status = SecKeychainFindGenericPassword(NULL, strlen(servername), servername, strlen(username),
- username, NULL, NULL, &keychain_item);
- if (status != noErr)
- ERR("SecKeychainFindGenericPassword returned %d\n", status);
+ CloseHandle( mgr );
+ return ERROR_OUTOFMEMORY;
}
- heap_free(username);
- heap_free(servername);
- if (status != noErr)
+ ptr = (WCHAR *)(cred + 1);
+
+ cred->targetname_offset = sizeof(*cred);
+ cred->targetname_size = (strlenW( credential->TargetName ) + 1) * sizeof(WCHAR);
+ strcpyW( ptr, credential->TargetName );
+ ptr += cred->targetname_size / sizeof(WCHAR);
+
+ cred->username_offset = cred->targetname_offset + cred->targetname_size;
+ cred->username_size = (strlenW( credential->UserName ) + 1) * sizeof(WCHAR);
+ strcpyW( ptr, credential->UserName );
+ ptr += cred->username_size / sizeof(WCHAR);
+
+ cred->blob_offset = cred->username_offset + cred->username_size;
+ if (credential->CredentialBlob)
{
- heap_free(password);
- return ERROR_GEN_FAILURE;
+ cred->blob_size = credential->CredentialBlobSize;
+ memcpy( ptr, credential->CredentialBlob, credential->CredentialBlobSize );
+ ptr += cred->blob_size / sizeof(WCHAR);
}
+ else cred->blob_size = 0;
+ cred->blob_preserve = preserve_blob;
+
+ cred->comment_offset = cred->blob_offset + cred->blob_size;
if (credential->Comment)
{
- attr_list.count = 1;
- attr_list.attr = attrs;
- attrs[0].tag = kSecCommentItemAttr;
- attrs[0].length = WideCharToMultiByte(CP_UTF8, 0, credential->Comment, -1, NULL, 0, NULL, NULL);
- if (attrs[0].length) attrs[0].length--;
- attrs[0].data = heap_alloc(attrs[0].length);
- WideCharToMultiByte(CP_UTF8, 0, credential->Comment, -1, attrs[0].data, attrs[0].length, NULL, NULL);
- }
- else
- {
- attr_list.count = 0;
- attr_list.attr = NULL;
+ cred->comment_size = (strlenW( credential->Comment ) + 1) * sizeof(WCHAR);
+ strcpyW( ptr, credential->Comment );
}
- status = SecKeychainItemModifyAttributesAndData(keychain_item, &attr_list,
- preserve_blob ? 0 : strlen(password),
- preserve_blob ? NULL : password);
- if (credential->Comment)
- heap_free(attrs[0].data);
- heap_free(password);
- /* FIXME: set TargetAlias attribute */
- CFRelease(keychain_item);
- if (status != noErr)
- return ERROR_GEN_FAILURE;
- return ERROR_SUCCESS;
+ else cred->comment_size = 0;
+
+ ret = DeviceIoControl( mgr, IOCTL_MOUNTMGR_WRITE_CREDENTIAL, cred, size, NULL, 0, NULL, NULL );
+ heap_free( cred );
+ CloseHandle( mgr );
+
+ return ret ? ERROR_SUCCESS : GetLastError();
}
-#endif
static DWORD open_cred_mgr_key(HKEY *hkey, BOOL open_for_write)
{
@@ -1823,20 +1811,18 @@ BOOL WINAPI CredWriteW(PCREDENTIALW Credential, DWORD Flags)
}
}
-#ifdef __APPLE__
if (!Credential->AttributeCount &&
Credential->Type == CRED_TYPE_DOMAIN_PASSWORD &&
(Credential->Persist == CRED_PERSIST_LOCAL_MACHINE || Credential->Persist == CRED_PERSIST_ENTERPRISE))
{
- ret = mac_write_credential(Credential, Flags & CRED_PRESERVE_CREDENTIAL_BLOB);
- if (ret != ERROR_SUCCESS)
+ ret = host_write_credential(Credential, Flags & CRED_PRESERVE_CREDENTIAL_BLOB);
+ if (ret != ERROR_SUCCESS && ret != ERROR_NOT_SUPPORTED)
{
SetLastError(ret);
return FALSE;
}
- return TRUE;
+ if (ret == ERROR_SUCCESS) return TRUE;
}
-#endif
ret = open_cred_mgr_key(&hkeyMgr, FALSE);
if (ret != ERROR_SUCCESS)
More information about the wine-cvs
mailing list