Searching for a SID in an Access Token Program Example 1
The following example uses the OpenProcessToken() and GetTokenInformation() functions to get the group memberships in an access token. Then it uses the AllocateAndInitializeSid() function to create a SID that identifies the well-known SID of the administrator group for the local computer. Next, it uses the EqualSid() function to compare the well-known SID with the group SIDs from the access token. If the SID is present in the token, the function checks the attributes of the SID to determine whether it is enabled.
The CheckTokenMembership() function used to determine whether a specified SID is present and enabled in an access token. This function eliminates potential misinterpretations of the active group membership if changes to access tokens are made in future releases.
Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.
Then, add the source file and give it a suitable name.
Next, add the following source code.
// Searching for a SID in an Access Token.
// This program run on the standalone Windows Xp Pro
#include <windows.h>
#include <stdio.h>
// A constant
#define MAX_NAME 256
BOOL SearchTokenGroupsForSID(void)
{
DWORD i, dwSize = 0, dwResult = 0;
HANDLE hToken;
PTOKEN_GROUPS pGroupInfo;
SID_NAME_USE SidType;
WCHAR lpName[MAX_NAME];
WCHAR lpDomain[MAX_NAME];
BYTE sidBuffer[100];
PSID pSID = (PSID)&sidBuffer;
// Open a handle to the access token for the calling process,
// that is, this running program (process). So we get the handle
// to the token for the current user that run this program and/or login to this machine.
// Depend on your task, change the TOKEN_QUERY to others accordingly...
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
wprintf(LOpenProcessToken() failed, error %u\n, GetLastError());
return FALSE;
}
else
wprintf(LOpenProcessToken() - got the handle to the access token!\n);
// By assuming that we got the handle to the token...
// Call GetTokenInformation() to get the buffer size for storage.
// This is for Tokengroups, change accordingly for others such
// as TokenUser, TokenOwner, TokenType etc.
if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
{
dwResult = GetLastError();
if(dwResult != ERROR_INSUFFICIENT_BUFFER)
{
wprintf(LGetTokenInformation() failed, error %u\n, dwResult);
return FALSE;
}
else
wprintf(LGetTokenInformation() - have an ample buffer...\n);
}
else
wprintf(LGetTokenInformation() - buffer for Token group is OK\n);
// By assuming that we got the storage, then allocate the buffer.
pGroupInfo = (PTOKEN_GROUPS)GlobalAlloc(GPTR, dwSize);
// Call GetTokenInformation() again to get the group information.
if(!GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, &dwSize))
{
wprintf(LGetTokenInformation() failed, error %u\n, GetLastError());
return FALSE;
}
else
wprintf(LGetTokenInformation() for getting the TokenGroups is OK\n);
//****************** Playing with SIDs *****************************
// Create a SID for the BUILTIN\Administrators group...
// You can try other groups also lol as commented out on the following
// codes. Uncomment/comment out the SIDs for testing....
// This is 32 bit RID value. Applications that require longer RID values,
// use CreateWellKnownSid() instead
//*********************** Administrator group ***********************
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
if(!AllocateAndInitializeSid(&SIDAuth, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSID))
{
wprintf(LAllocateAndInitializeSid() failed, error %u\n, GetLastError());
return FALSE;
}
else
wprintf(LBUILTIN\\Administrators group SID was allocated and initialized!\n);
//************************ Local group ********************
// An example for creating a SID for the Local group...
// SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_LOCAL_SID_AUTHORITY;
//
// if(!AllocateAndInitializeSid(&SIDAuth, 1,
// SECURITY_LOCAL_RID,
// 0, 0, 0, 0, 0, 0, 0,
// &pSID))
// {
// wprintf(LAllocateAndInitializeSid() error %u\n, GetLastError());
// return FALSE;
// }
// else
// wprintf(LAllocateAndInitializeSid(), SID for Local group is\n successfully created\n);
//********************* Authenticated users ***********************
// Another example for creating a SID for the Authenticated users...
// SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
// if(!AllocateAndInitializeSid(&SIDAuth, 1,
// SECURITY_AUTHENTICATED_USER_RID,
// 0, 0, 0, 0, 0, 0, 0,
// &pSID))
// {
// wprintf(LAllocateAndInitializeSid() error %u\n, GetLastError());
// return FALSE;
// }
// else
// wprintf(LAllocateAndInitializeSid(), SID for Local group is\n successfully created\n);
//******************************************************************
// Loop through the group SIDs looking for the created group SID.
for(i=0; i<pGroupInfo->GroupCount; i++)
{
// Compare the created SID with the available group SIDs
if(EqualSid(pSID, pGroupInfo->Groups[i].Sid))
{
// Lookup the account name and print it.
dwSize = MAX_NAME;
if(!LookupAccountSid(NULL,
pGroupInfo->Groups[i].Sid,
lpName,
&dwSize,
lpDomain,
&dwSize,
&SidType))
{
// If not found or something wrong...
dwResult = GetLastError();
if(dwResult == ERROR_NONE_MAPPED)
wcscpy_s(lpName, sizeof(lpName), LNONE_MAPPED);
else
{
wprintf(LLookupAccountSid() failed, error %u\n, GetLastError());
return FALSE;
}
}
// If found...
else
{
//******************* Built-in\Administrators group *********************
wprintf(LBUILTIN\\Administrators group SID found!\n);
wprintf(LYES, current user is a member of the %s\\%s group\n, lpDomain, lpName);
//******************* Local group ***************************************
// wprintf(LLookupAccountSid() for Local group is OK\n);
// wprintf(LCurrent user is a member of the %s group\n, lpName);
//******************** Authenticated users *******************************
// wprintf(LLookupAccountSid() for Authenticated users is OK\n);
// wprintf(LCurrent user is a member of the %s\\%s group\n, lpDomain, lpName);
}
//**************** End playing with SIDs *********************************
// Find out whether the SID is enabled in the token.
if(pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)
wprintf(L and the group SID is enabled!\n);
else if (pGroupInfo->Groups[i].Attributes & SE_GROUP_USE_FOR_DENY_ONLY)
wprintf(L and the group SID is a deny-only SID!\n);
else
wprintf(Land the group SID is not enabled!\n);
}
}
// Release resources back to system
if(pSID)
FreeSid(pSID);
if(pGroupInfo)
GlobalFree(pGroupInfo);
return TRUE;
}
//******** main() ********
int wmain(int argc, WCHAR **argv)
{
// Call the user defined SearchTokenGroupsForSID() function to search the token group SID
BOOL bRetVal = SearchTokenGroupsForSID();
// Verify
wprintf(LThe return value of SearchTokenGroupsForSID() is: %d\n, bRetVal);
return 0;
}
Build and run the project. The following screenshot is a sample output.