diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index db7d028efc5..7dd39a4a75d 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -625,8 +625,10 @@ BOOL WINAPI CheckTokenMembership( HANDLE token, PSID sid_to_check, PBOOL is_member ) { - PTOKEN_GROUPS token_groups; + PTOKEN_GROUPS token_groups = NULL; + HANDLE thread_token = NULL; DWORD size, i; + BOOL ret; TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member); @@ -634,26 +636,37 @@ CheckTokenMembership( HANDLE token, PSID sid_to_check, if (!token) { - if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token)) - return FALSE; + if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token)) + { + HANDLE process_token; + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token); + if (!ret) + goto exit; + ret = DuplicateTokenEx(process_token, TOKEN_QUERY, + NULL, SecurityImpersonation, TokenImpersonation, + &thread_token); + CloseHandle(process_token); + if (!ret) + goto exit; + } + token = thread_token; } - if (!GetTokenInformation(token, TokenGroups, NULL, 0, &size)) - { - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return FALSE; - } + ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size); + if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + goto exit; token_groups = HeapAlloc(GetProcessHeap(), 0, size); if (!token_groups) - return FALSE; - - if (!GetTokenInformation(token, TokenGroups, token_groups, size, &size)) { - HeapFree(GetProcessHeap(), 0, token_groups); - return FALSE; + ret = FALSE; + goto exit; } + ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size); + if (!ret) + goto exit; + for (i = 0; i < token_groups->GroupCount; i++) { TRACE("Groups[%d]: {0x%x, %s}\n", i, @@ -668,9 +681,11 @@ CheckTokenMembership( HANDLE token, PSID sid_to_check, } } +exit: HeapFree(GetProcessHeap(), 0, token_groups); + if (thread_token != NULL) CloseHandle(thread_token); - return TRUE; + return ret; } /****************************************************************************** diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index eaa9e2c4c07..b71d64f6837 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3249,6 +3249,10 @@ static void test_CheckTokenMembership(void) ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError()); ok(is_member, "CheckTokenMembership should have detected sid as member\n"); + ret = pCheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member); + ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError()); + ok(is_member, "CheckTokenMembership should have detected sid as member\n"); + ret = pCheckTokenMembership(process_token, token_groups->Groups[i].Sid, &is_member); todo_wine { ok(!ret && GetLastError() == ERROR_NO_IMPERSONATION_TOKEN,