Today I’ve decided to republish a post from my original coding blog. This one is in C++ and comes from the days when I used to work on MFC and other C++ applications.
Here’s some code which determines the rights of the user under which the code is executed (pretty sure from memory this only works in determining local group membership, not Active Directory groups). It’s native C using Win32 APIs but could be used in other languages (like Delphi and .NET – with proper Interop etc). Sorry about the formatting!
If anything, it’s a nice reminder of how much simpler life is using .Net and to a lesser extend, LDAP and Active Directory.
I’ll come back through and add some more meaningful comments shortly. Think of it as a lesson in, "Why do I use ADAM or AzMan, today?".
Update: You’ll need these includes for it to compile:
#include <windows.h>
#include <stdlib.h>
Also note that the calls to ‘LogMessage()’ are just a logging routine I was using at the time, comment them out or use your own logging mechanism. Also note that the try..catch block isn’t fully developed, this code is provided as a talking piece! Obviously, you’d want to be checking for NULLs, too.
bool IsAdmin()
{
HANDLE hAccessToken = 0;
DWORD dwInfoBufferSize = 0;
TOKEN_GROUPS *ptg;
DWORD needed;
PSID psidAdministrators;
PSID psidPowerUsers;
bool bRetVal = false;
bool blnResult = false;
SID_IDENTIFIER_AUTHORITY sidIdentifiers = SECURITY_NT_AUTHORITY;
//= //{0,0,0,0,0,5}; // ntifs
// Other Defines
//
// DWORD dwSecBuiltinDomainRID = SECURITY_BUILTIN_DOMAIN_RID;
//= 0x00000020;
// DWORD dwDomainAliasRIDAdmins = DOMAIN_ALIAS_RID_ADMINS;
//= 0x00000220;
// DWORD dwDomainAliasRIDUsers = DOMAIN_ALIAS_RID_USERS;
//= 0x00000221;
// DWORD dwDomainAliasRIDGuests = DOMAIN_ALIAS_RID_GUESTS;
//= 0x00000222;
// DWORD dwDomainAliasRIDPower = DOMAIN_ALIAS_RID_POWER_USERS;
//= 0x00000223;
//
blnResult = OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, true,
&hAccessToken );
if(!blnResult)
{
if(GetLastError() == ERROR_NO_TOKEN)
{
blnResult = OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY, &hAccessToken);
}
else
{
LogMessage("IsAdmin::Couldn’t Check Privileges –
OpenThreadToken/ProcessToken failed", 3);
return false;
}
}
if(blnResult)
{
try
{
ptg = (TOKEN_GROUPS *) malloc( 1024 );
blnResult = GetTokenInformation(hAccessToken, TokenGroups,
ptg, 1024, &needed);
CloseHandle(hAccessToken);
if(blnResult)
{
BOOL bAdminPSID = FALSE;
BOOL bPowerUSER = FALSE;
bAdminPSID = AllocateAndInitializeSid(&sidIdentifiers,
2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
0, &psidAdministrators);
bPowerUSER = AllocateAndInitializeSid(&sidIdentifiers,
2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0,
0, 0, 0, &psidPowerUsers);
if(ptg->GroupCount <= 0)
return bRetVal;
if(bAdminPSID == TRUE || bPowerUSER == TRUE)
{
for(int i = 0; i != ptg->GroupCount; ++i)
{
if(bAdminPSID)
{
if(EqualSid(psidAdministrators, ptg->Groups[i].Sid))
{
LogMessage("IsAdmin::Determined that
User is a member of the Administrators group", 3);
bRetVal = true;
break;
}
}
if(bPowerUSER) //also see if the user is a Power User
{
if(EqualSid(psidPowerUsers, ptg->Groups[i].Sid))
{
LogMessage("IsAdmin::Determined that
User is a member of the Power Users group.", 3);
}
}
}
if(bAdminPSID)
FreeSid(psidAdministrators);
if(bPowerUSER)
FreeSid(psidPowerUsers);
}
}
else
{
LogMessage("IsAdmin::GetTokenInformation Failed", 3);
}
free(ptg);
}
catch(…)
{
LogMessage("IsAdmin::Exception Thrown Checking Privileges", 3);
}
}
if(!bRetVal)
LogMessage("IsAdmin::Looks like user might not have Administrative privileges", 3);
return bRetVal;
}