HOWTO: Determine if Running In User Context of Local Admin Acct

ID: Q118626

The information in this article applies to:

SUMMARY

To determine whether or not a thread is running in the user context of the local Administrator account, you need to examine the access token associated with that thread using the GetTokenInformation() API, since this access token represents the user under which the thread is running. By default the token associated with a thread is that of its containing process, but this user context will be superceded by any token attached directly to the thread. So to determine a thread?s user context, first attempt to obtain any token attached directly to the thread with OpenThreadToken(). If this fails, and GetLastError() reports ERROR_NO_TOKEN, then obtain the token of the thread?s containing process with OpenProcessToken().

The sample code below uses the APIs mentioned in the previous paragraph to test whether or not the current user is an administrator on the local machine.

MORE INFORMATION

Sample code

   /* BOOL IsAdmin(void)

      returns TRUE if user is an admin
              FALSE if user is not an admin
   */ 

   BOOL IsAdmin(void)
   {
      HANDLE hAccessToken;
      UCHAR InfoBuffer[1024];
      PTOKEN_GROUPS ptgGroups = (PTOKEN_GROUPS)InfoBuffer;
      DWORD dwInfoBufferSize;
      PSID psidAdministrators;
      SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
      UINT x;
      BOOL bSuccess;

      if(!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,
         &hAccessToken )) {
         if(GetLastError() != ERROR_NO_TOKEN)
            return FALSE;
         // 
         // retry against process token if no thread token exists
         // 
         if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
            &hAccessToken))
            return FALSE;
      }

      bSuccess = GetTokenInformation(hAccessToken,TokenGroups,InfoBuffer,
         1024, &dwInfoBufferSize);

      CloseHandle(hAccessToken);

      if(!bSuccess )
         return FALSE;

      if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
         SECURITY_BUILTIN_DOMAIN_RID,
         DOMAIN_ALIAS_RID_ADMINS,
         0, 0, 0, 0, 0, 0,
         &psidAdministrators))
         return FALSE;

   // assume that we don't find the admin SID.
      bSuccess = FALSE;

      for(x=0;x<ptgGroups->GroupCount;x++)
      {
         if( EqualSid(psidAdministrators, ptgGroups->Groups[x].Sid) )
         {
            bSuccess = TRUE;
            break;
         }

      }
      FreeSid(psidAdministrators);
      return bSuccess;
   }
Keywords          : kbAPI kbKernBase kbGrpKernBase 
Version           : 3.51 4.0
Platform          : NT WINDOWS
Issue type        : kbhowto

Last Reviewed: March 6, 1998