Windows Access Control List (ACL) Example 24

 

 

 

 

 

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.

 

Searching for a SID in an Access Token Program Example 1: New Win32 C++ Console mode application

 

Then, add the source file and give it a suitable name.

 

Searching for a SID in an Access Token Program Example 1: Adding new C++ source file to the existing project

 

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(L"OpenProcessToken() failed, error %u\n", GetLastError());

            return FALSE;

      }

      else

            wprintf(L"OpenProcessToken() - 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(L"GetTokenInformation() failed, error %u\n", dwResult);

                  return FALSE;

            }

            else

                  wprintf(L"GetTokenInformation() - have an ample buffer...\n");

      }

      else

            wprintf(L"GetTokenInformation() - 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(L"GetTokenInformation() failed, error %u\n", GetLastError());

            return FALSE;

      }

      else

            wprintf(L"GetTokenInformation() 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(L"AllocateAndInitializeSid() failed, error %u\n", GetLastError());

            return FALSE;

      }

      else

            wprintf(L"BUILTIN\\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(L"AllocateAndInitializeSid() error %u\n", GetLastError());

      //    return FALSE;

      // }

      // else

      //          wprintf(L"AllocateAndInitializeSid(), 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(L"AllocateAndInitializeSid() error %u\n", GetLastError());

      // return FALSE;

      // }

      // else

      // wprintf(L"AllocateAndInitializeSid(), 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), L"NONE_MAPPED");

                        else

                        {

                              wprintf(L"LookupAccountSid() failed, error %u\n", GetLastError());

                              return FALSE;

                        }

                  }

                  // If found...

                  else

                  {

                        //******************* Built-in\Administrators group *********************

                        wprintf(L"BUILTIN\\Administrators group SID found!\n");

                        wprintf(L"YES, current user is a member of the %s\\%s group\n", lpDomain, lpName);

 

                        //******************* Local group ***************************************

                        // wprintf(L"LookupAccountSid() for Local group is OK\n");

                        // wprintf(L"Current user is a member of the %s group\n", lpName);

                        //******************** Authenticated users *******************************

                        // wprintf(L"LookupAccountSid() for Authenticated users is OK\n");

                        // wprintf(L"Current 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(L"and 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(L"The return value of SearchTokenGroupsForSID() is: %d\n", bRetVal);

 

      return 0;

}

 

Build and run the project. The following screenshot is a sample output.

 

Searching for a SID in an Access Token Program Example 1: A sample output with the found SID

 

 

 

 

< Windows ACL Example 23 | Windows Access Control List (ACL) Main | Win32 Programming | Windows ACL Example 25 >