From 62d3309a725fb27f0c606800b43e29be69f4bcea Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 28 Dec 2015 01:18:00 +0300 Subject: [PATCH] advapi32: Make RegOpenCurrentUser() return real key handles for current SID. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/advapi32/registry.c | 48 +++++++++++++++++++++++++++++++++- dlls/advapi32/tests/registry.c | 13 +++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index 83176989603..350840741d0 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -37,6 +37,7 @@ #include "winerror.h" #include "winternl.h" #include "winuser.h" +#include "sddl.h" #include "advapi32_misc.h" #include "wine/unicode.h" @@ -648,6 +649,21 @@ LSTATUS WINAPI RegOpenKeyA( HKEY hkey, LPCSTR name, PHKEY retkey ) return RegOpenKeyExA( hkey, name, 0, MAXIMUM_ALLOWED, retkey ); } +static WCHAR *get_thread_token_user_sid(HANDLE token) +{ + WCHAR *sidstring = NULL; + TOKEN_USER *info; + DWORD len = 0; + + GetTokenInformation(token, TokenUser, NULL, 0, &len); + + info = heap_alloc(len); + if (GetTokenInformation(token, TokenUser, info, len, &len)) + ConvertSidToStringSidW(info->User.Sid, &sidstring); + heap_free(info); + + return sidstring; +} /****************************************************************************** * RegOpenCurrentUser [ADVAPI32.@] @@ -671,7 +687,37 @@ LSTATUS WINAPI RegOpenKeyA( HKEY hkey, LPCSTR name, PHKEY retkey ) */ LSTATUS WINAPI RegOpenCurrentUser( REGSAM access, PHKEY retkey ) { - return RegOpenKeyExA( HKEY_CURRENT_USER, "", 0, access, retkey ); + WCHAR *sidstring = NULL; + HANDLE threadtoken; + LSTATUS ret; + + /* get current user SID */ + if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &threadtoken)) + { + sidstring = get_thread_token_user_sid(threadtoken); + CloseHandle(threadtoken); + } + + if (!sidstring) + { + ImpersonateSelf(SecurityIdentification); + if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &threadtoken)) + { + sidstring = get_thread_token_user_sid(threadtoken); + CloseHandle(threadtoken); + } + RevertToSelf(); + } + + if (sidstring) + { + ret = RegOpenKeyExW( HKEY_USERS, sidstring, 0, access, retkey ); + LocalFree(sidstring); + } + else + ret = RegOpenKeyExA( HKEY_CURRENT_USER, "", 0, access, retkey ); + + return ret; } diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 254a8b66210..ef5d989e7f3 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -3278,6 +3278,18 @@ static void test_delete_key_value(void) RegCloseKey(subkey); } +static void test_RegOpenCurrentUser(void) +{ + HKEY key; + LONG ret; + + key = HKEY_CURRENT_USER; + ret = RegOpenCurrentUser(KEY_READ, &key); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + ok(key != HKEY_CURRENT_USER, "got %p\n", key); + RegCloseKey(key); +} + START_TEST(registry) { /* Load pointers for functions that are not available in all Windows versions */ @@ -3310,6 +3322,7 @@ START_TEST(registry) test_deleted_key(); test_delete_value(); test_delete_key_value(); + test_RegOpenCurrentUser(); /* cleanup */ delete_key( hkey_main );