Hans Leidekker : advapi32: Read host credentials through mountmgr.
Alexandre Julliard
julliard at winehq.org
Wed Sep 2 15:24:32 CDT 2020
Module: wine
Branch: master
Commit: faef38479c8519d95d6947f920497c0f020f712b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=faef38479c8519d95d6947f920497c0f020f712b
Author: Hans Leidekker <hans at codeweavers.com>
Date: Wed Sep 2 15:08:00 2020 +0200
advapi32: Read 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 | 154 +++++++++++++++++++++++++++++----------------------
1 file changed, 88 insertions(+), 66 deletions(-)
diff --git a/dlls/advapi32/cred.c b/dlls/advapi32/cred.c
index 49a1c34d1c..07f4b9b03a 100644
--- a/dlls/advapi32/cred.c
+++ b/dlls/advapi32/cred.c
@@ -33,6 +33,9 @@
#include "winreg.h"
#include "wincred.h"
#include "winternl.h"
+#include "winioctl.h"
+#define WINE_MOUNTMGR_EXTENSIONS
+#include "ddk/mountmgr.h"
#include "crypt.h"
@@ -1389,6 +1392,86 @@ BOOL WINAPI CredReadA(LPCSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALA *
return TRUE;
}
+static DWORD host_read_credential( const WCHAR *targetname, CREDENTIALW **ret_credential )
+{
+ struct mountmgr_credential *cred_in, *cred_out = NULL, *tmp;
+ DWORD err = ERROR_OUTOFMEMORY, size_in, size_out, size_name = (strlenW( targetname ) + 1) * sizeof(WCHAR);
+ HANDLE mgr;
+ WCHAR *ptr;
+ BOOL ret;
+
+ 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_in = sizeof(*cred_in) + size_name;
+ if (!(cred_in = heap_alloc( size_in )))
+ {
+ CloseHandle( mgr );
+ return ERROR_OUTOFMEMORY;
+ }
+ cred_in->targetname_offset = sizeof(*cred_in);
+ cred_in->targetname_size = size_name;
+ ptr = (WCHAR *)(cred_in + 1);
+ strcpyW( ptr, targetname );
+
+ size_out = 256;
+ if (!(cred_out = heap_alloc( size_out ))) goto done;
+
+ for (;;)
+ {
+ ret = DeviceIoControl( mgr, IOCTL_MOUNTMGR_READ_CREDENTIAL, cred_in, size_in, cred_out, size_out, NULL, NULL );
+ if (ret || (err = GetLastError()) != ERROR_MORE_DATA) break;
+ size_out *= 2;
+ if (!(tmp = heap_realloc( cred_out, size_out ))) goto done;
+ cred_out = tmp;
+ }
+
+ if (ret)
+ {
+ CREDENTIALW *credential;
+ DWORD size = sizeof(*credential) + cred_out->targetname_size + cred_out->username_size + cred_out->comment_size +
+ cred_out->blob_size;
+
+ if (!(credential = heap_alloc_zero( size )))
+ {
+ err = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+ ptr = (WCHAR *)(credential + 1);
+
+ credential->Type = CRED_TYPE_DOMAIN_PASSWORD;
+ memcpy( ptr, (char *)cred_out + cred_out->targetname_offset, cred_out->targetname_size );
+ credential->TargetName = ptr;
+ ptr += strlenW( ptr ) + 1;
+ if (cred_out->comment_size)
+ {
+ memcpy( ptr, (char *)cred_out + cred_out->comment_offset, cred_out->comment_size );
+ credential->Comment = ptr;
+ ptr += strlenW( ptr ) + 1;
+ }
+ credential->LastWritten = cred_out->last_written;
+ if ((credential->CredentialBlobSize = cred_out->blob_size))
+ {
+ memcpy( ptr, (char *)cred_out + cred_out->blob_offset, cred_out->blob_size );
+ credential->CredentialBlob = (BYTE *)ptr;
+ ptr += cred_out->blob_size / sizeof(WCHAR);
+ }
+ credential->Persist = CRED_PERSIST_LOCAL_MACHINE;
+ memcpy( ptr, (char *)cred_out + cred_out->username_offset, cred_out->username_size );
+ credential->UserName = ptr;
+
+ *ret_credential = credential;
+ err = ERROR_SUCCESS;
+ }
+
+done:
+ heap_free( cred_in );
+ heap_free( cred_out );
+ CloseHandle( mgr );
+ return err;
+}
+
/******************************************************************************
* CredReadW [ADVAPI32.@]
*/
@@ -1423,77 +1506,16 @@ BOOL WINAPI CredReadW(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW
return FALSE;
}
-#ifdef __APPLE__
if (Type == CRED_TYPE_DOMAIN_PASSWORD)
{
- int status;
- SecKeychainSearchRef search;
- status = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, NULL, &search);
- if (status == noErr)
+ ret = host_read_credential( TargetName, Credential );
+ if (ret != ERROR_SUCCESS && ret != ERROR_NOT_SUPPORTED)
{
- SecKeychainItemRef item;
- while (SecKeychainSearchCopyNext(search, &item) == noErr)
- {
- SecKeychainAttributeInfo info;
- SecKeychainAttributeList *attr_list;
- UInt32 info_tags[] = { kSecServiceItemAttr };
- LPWSTR target_name;
- INT str_len;
- info.count = ARRAY_SIZE(info_tags);
- info.tag = info_tags;
- info.format = NULL;
- status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, NULL, NULL);
- len = sizeof(**Credential);
- if (status != noErr)
- {
- WARN("SecKeychainItemCopyAttributesAndData returned status %d\n", status);
- continue;
- }
- if (attr_list->count != 1 || attr_list->attr[0].tag != kSecServiceItemAttr)
- {
- CFRelease(item);
- continue;
- }
- str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, NULL, 0);
- target_name = heap_alloc((str_len + 1) * sizeof(WCHAR));
- MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, target_name, str_len);
- /* nul terminate */
- target_name[str_len] = '\0';
- if (strcmpiW(TargetName, target_name))
- {
- CFRelease(item);
- heap_free(target_name);
- continue;
- }
- heap_free(target_name);
- SecKeychainItemFreeAttributesAndData(attr_list, NULL);
- ret = mac_read_credential_from_item(item, TRUE, NULL, NULL, &len);
- if (ret == ERROR_SUCCESS)
- {
- *Credential = heap_alloc(len);
- if (*Credential)
- {
- len = sizeof(**Credential);
- ret = mac_read_credential_from_item(item, TRUE, *Credential,
- (char *)(*Credential + 1), &len);
- }
- else
- ret = ERROR_OUTOFMEMORY;
- CFRelease(item);
- CFRelease(search);
- if (ret != ERROR_SUCCESS)
- {
- SetLastError(ret);
- return FALSE;
- }
- return TRUE;
- }
- CFRelease(item);
- }
- CFRelease(search);
+ SetLastError(ret);
+ return FALSE;
}
+ 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