Reputation: 22255
I'm trying to use this code to check security group membership for an arbitrary process that I have a handle for. But in my code below CheckTokenMembership
fails with error code 1309, or ERROR_NO_IMPERSONATION_TOKEN
. I'm not sure I understand how I can get that impersonation token...
So what am I doing wrong here?
void check_membership(HANDLE hProc)
{
HANDLE hToken;
if(OpenProcessToken(hProc, TOKEN_QUERY, &hToken))
{
check_group_membership(hToken, L"Local Group", DOMAIN_ALIAS_RID_USERS);
check_group_membership(hToken, L"Admin Group", DOMAIN_ALIAS_RID_ADMINS);
check_group_membership(hToken, L"Domain Admin Group", DOMAIN_GROUP_RID_ADMINS);
check_group_membership(hToken, L"Schema Admin Group", DOMAIN_GROUP_RID_SCHEMA_ADMINS);
check_group_membership(hToken, L"Enterprise Admin Group", DOMAIN_GROUP_RID_ENTERPRISE_ADMINS);
CloseHandle(hToken);
}
}
void check_group_membership(HANDLE hToken, LPCTSTR pStrName, DWORD nSubauthority)
{
BOOL bIsMember;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
wprintf(L"Local %s: ", pStrName);
PSID pSID = NULL;
if(AllocateAndInitializeSid(&NtAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
nSubauthority,
0, 0, 0, 0, 0, 0, &pSID))
{
bIsMember = FALSE;
if(CheckTokenMembership(hToken, pSID, &bIsMember))
{
wprintf(L"%s", bIsMember ? L"Yes" : L"No");
}
else
{
wprintf(L"<CheckErr: (%d)>", GetLastError());
}
}
else
{
wprintf(L"<SidErr: (%d)>", GetLastError());
}
wprintf(L"\n");
if(pSID)
{
FreeSid(pSID) == NULL);
pSID = NULL;
}
}
Upvotes: 1
Views: 726
Reputation: 101616
MSDN does confirm that it is a requirement:
The token must be an impersonation token.
It also says for the NULL handle case:
CheckTokenMembership
uses the impersonation token of the calling thread. If the thread is not impersonating, the function duplicates the thread's primary token to create an impersonation token.
You could try this:
HANDLE hImpToken;
if (DuplicateTokenEx(hToken, TOKEN_QUERY, NULL, SecurityImpersonation, TokenImpersonation, &hImpToken))
{
CheckTokenMembership(hImpToken, ...);
CloseHandle(hImpToken);
}
Upvotes: 3