Search code examples
winapi

How to get the SID of the current machine?


I know how to get the SID for the current user. Conceptually the answer is:

  • Use OpenThreadToken (or OpenProcessToken) to get the security TOKEN of the running user
  • use GetTokenInformation to get the TOKEN_USER structure
  • and then TOKEN_USER.Sid is the Sid

So in pseudocode:

String GetCurrentUserSid()
{
   // Get the calling thread's access token.
   TOKEN hToken;
   if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, true, out hToken)
   { 
       if (GetLastError() != ERROR_NO_TOKEN)
          RaiseLastWin32Error();

       // No thread token exists, try again against the process token
       if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, out hToken)
          RaiseLastWin32Error();
   }
   try
   {
      // Obtain the size of the user information in the token.
      DWORD cbReturned;
      GetTokenInformation(hToken, TokenUser, nil, 0, out cbReturned);

      //Allocate memory and try again for real
      TOKEN_USER* tiUser = GetMemory(cbReturned);
      if (!GetTokenInformation(hToken, TokenUser, tiUser, cbReturned, out cbReturned))
      RaiseLastWin32Error();
   }
   finally
   {
      CloseHandle(hToken);
   }

   //Convert the structure to a string
   return SidToString(tiUser.User.Sid);
}

But how to do it for the current machine?

String GetCurrentMachineSid()
{
   // TODO: Ask Stackoverflow
}

Bonus Reading


Solution

  • You can see the machine SID on your computer by running Sysinternals PsGetSid with no parameters

    so i simply look under debugger how PsGetSid do this.

    it get SID from POLICY_ACCOUNT_DOMAIN_INFO - DomainSid : Pointer to the SID of the account domain

    code can be next

    LSA_HANDLE PolicyHandle;
    
    LSA_OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(ObjectAttributes) };
    
    NTSTATUS status = LsaOpenPolicy(0, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle);
    
    if (0 <= status)
    {
        POLICY_ACCOUNT_DOMAIN_INFO* ppadi;
    
        status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (void**)&ppadi);
    
        if (0 <= status)
        {
            PWSTR szSid;
            BOOL b = ConvertSidToStringSidW(ppadi->DomainSid, &szSid);
            LsaFreeMemory(ppadi);
    
            if (b)
            {
                DbgPrint("%S\n", szSid);
                LocalFree(szSid);
            }
        }
    
        LsaClose(PolicyHandle);
    }