I saw IsInRole method but I can't find information on how to use it with C++.
views:
129answers:
4
+1
A:
There's a C++ code snippet in this old answer taken from the UACHelpers project on CodePlex.
Rup
2010-08-23 10:32:34
A:
You might try this piece of code. It gives a sketch of what needs to be done:
const HANDLE hProcess = GetCurrentProcess();
if (hProcess==NULL)
return FAILURE;
HANDLE hToken;
const BOOL lR = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
if (lR == NULL)
return FAILURE;
PSID psidAdministrators;
SID_IDENTIFIER_AUTHORITY x = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(
&x, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
&psidAdministrators))
return FAILURE;
bool isAdmin = false; //dummy init
DWORD size;
GetTokenInformation(hToken, TokenGroups, NULL, 0, &size);
char* buffer = new char[size];
DWORD notUsed;
if (!GetTokenInformation(hToken, TokenGroups, (void*)buffer, size, ¬Used))
return FAILURE;
TOKEN_GROUPS* ptgGroups = (TOKEN_GROUPS*)buffer;
isAdmin = false; //until proven otherwise
for (UINT32 i=0; i<ptgGroups->GroupCount; ++i)
{
if (EqualSid(psidAdministrators, ptgGroups->Groups[i].Sid))
{
isAdmin = true;
break;
}
}
FreeSid(psidAdministrators);
return isAdmin;
Dimitri C.
2010-08-23 10:39:11
This code is the NT4 way to check if a SID is part of a users token, it does not work correctly on newer systems and should not be used. See Rup's SO link for my answer and which function to call...
Anders
2010-08-23 16:38:14
@Anders: It works on Windows XP, Windows Vista and Windows 7 for sure. This code was tested rather extensively on these three systems. Why do you think it wouldn't work?
Dimitri C.
2010-08-24 06:17:12
@Dimitri C.: I KNOW its broken, so you just did not test properly. There is a thing called a deny-only SID and your current code does not handle those, you are supposed to use CheckTokenMembership.
Anders
2010-08-24 11:50:17
-1: Yes, this code is broken since Windows 2000 and the introduction of so called restricted tokens. (check MSDN: CreateRestrictedToken). A token has a list of group memberships. Every token group has also a flag variable that may contain SE_GROUP_USE_FOR_DENY_ONLY. If this flag is set for a group Windows will use the group for access checking only for DENY access control elements (ACEs). So an admin group membership with SE_GROUP_USE_FOR_DENY_ONLY won't be able to access any resource with allow ACE. The solution is to check for this flag in your code in addition, or use CheckTokenMembership.
ChristianWimmer
2010-10-29 09:17:55
+1
A:
The documentation of IsUSerAnAdmin
explains that it's deprecated since Vista, but points you to CheckTokenMembership
. That should do the job for you.
MSalters
2010-08-24 07:11:56
+1
A:
This code solves your problem. Feel free to use it. It works with SE_GROUP_USE_FOR_DENY_ONLY.
/**
IsGroupMember determines if the current thread or process has a token that contais a given and enabled user group.
Parameters
dwRelativeID: Defines a relative ID (par of a SID) of a user group (e.g. Administrators DOMAIN_ALIAS_RID_ADMINS (544) = S-1-5-32-544)
bProcessRelative: Defines whether to use the process token (TRUE) instead of the thread token (FALSE). If FALSE and no thread token is present
the process token will be used though.
bIsMember: Returns the result of the function. The value returns TRUE if the user is an enabled member of the group; otherwise FALSE.
Return Value
If the function succeeds, the return value is TRUE; otherwise FALSE. Call GetLastError for more information.
*/
BOOL IsGroupMember(DWORD dwRelativeID, BOOL bProcessRelative, BOOL* pIsMember)
{
HANDLE hToken, hDupToken;
PSID pSid = NULL;
SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
if (!pIsMember)
{
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (bProcessRelative || !OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &hToken))
{
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &hToken))
{
return FALSE;
}
}
if (!DuplicateToken(hToken, SecurityIdentification, &hDupToken))
{
CloseHandle(hToken);
return FALSE;
}
CloseHandle(hToken);
hToken = hDupToken;
if (!AllocateAndInitializeSid(&SidAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID, dwRelativeID, 0, 0, 0, 0, 0, 0,
&pSid))
{
CloseHandle(hToken);
return FALSE;
}
if (!CheckTokenMembership(hToken, pSid, pIsMember))
{
CloseHandle(hToken);
FreeSid(pSid);
*pIsMember = FALSE;
return FALSE;
}
CloseHandle(hToken);
FreeSid(pSid);
return TRUE;
}
BOOL IsUserAdministrator(BOOL* pIsAdmin)
{
return IsGroupMember(DOMAIN_ALIAS_RID_ADMINS, FALSE, pIsAdmin);
}
ChristianWimmer
2010-10-29 10:57:59