Microsoft KB Archive/111544

From BetaArchive Wiki

HOWTO: Retrieve Current User and Domain Names on Windows NT

Q111544



The information in this article applies to:


  • Microsoft Win32 Application Programming Interface (API), used with:
    • Microsoft Windows NT Server versions 3.1, 3.5, 4.0
    • Microsoft Windows NT Workstation versions 3.1, 3.5, 4.0
    • the operating system: Microsoft Windows 2000





SUMMARY

A program may sometimes need to display the user name and domain name for the current thread. This article demonstrates how to do this on Windows NT by using security functions within the Win32 Application Programming Interface (API).



MORE INFORMATION

Prior to Windows NT, it could be assumed that a thread was running under the account of the interactively logged on user. Windows NT, however, allows threads to run under multiple security contexts, potentially representing multiple users. For instance, in a client/server application, a thread in the server might impersonate a client through the ImpersonateNamedPipeClient function. In this case, it runs under the user context of the client. Another example of a thread running in a different security context is a service thread, which has a domain name of NT AUTHORITY and a user name of SYSTEM, assuming that the service is running in the local system account.

If you need to obtain both the user name and the domain name for the current thread, you must first extract the user's security identifier (SID) from the thread's access token by using the GetTokenInformation function. Then, a call to the LookupAccountSid function can be used to retrieve the account name and domain name associated with the SID. The sample code at the end of this article demonstrates this technique.

The 32-bit functions just mentioned are not available on Microsoft Windows 95 or Microsoft Windows 98. To retrieve the name and domain of the interactive user on Windows 95 or Windows 98, you must call a 16-bit LAN Manager function. For additional information, click the article number below to view the article in the Microsoft Knowledge Base:

Q155698 HOWTO: Retrieve Current User and Domain Names on Windows 95 and Windows 98

NOTE: If only the user name is required, the GetUserName function can be used on Windows 95, Windows 98, Windows NT, and Windows 2000. On Windows NT and Windows 2000, this function first checks to see if the calling thread has a specific access token, which is typically the result of an impersonation call. In this case, the user name associated with the calling thread is returned. Otherwise, the user name associated with the calling process is returned.

Sample Code

The following sample code demonstrates how to programmatically retrieve the user name and domain name on Windows NT:

//**********************************************************************
// 
//  FUNCTION:     GetCurrentUserAndDomain - This function looks up
//                the user name and domain name for the user account
//                associated with the calling thread.
// 
//  PARAMETERS:   szUser - a buffer that receives the user name
//                pcchUser - the size, in characters, of szUser
//                szDomain - a buffer that receives the domain name
//                pcchDomain - the size, in characters, of szDomain
// 
//  RETURN VALUE: TRUE if the function succeeds. Otherwise, FALSE and
//                GetLastError() will return the failure reason.
// 
//                If either of the supplied buffers are too small, 
//                GetLastError() will return ERROR_INSUFFICIENT_BUFFER
//                and pcchUser and pcchDomain will be adjusted to 
//                reflect the required buffer sizes.
// 
//**********************************************************************

BOOL GetCurrentUserAndDomain(PTSTR szUser, PDWORD pcchUser, 
      PTSTR szDomain, PDWORD pcchDomain) {

   BOOL         fSuccess = FALSE;
   HANDLE       hToken   = NULL;
   PTOKEN_USER  ptiUser  = NULL;
   DWORD        cbti     = 0;
   SID_NAME_USE snu;

   __try {

      // Get the calling thread's access token.
      if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,
            &hToken)) {

         if (GetLastError() != ERROR_NO_TOKEN)
            __leave;

         // Retry against process token if no thread token exists.
         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, 
               &hToken))
            __leave;
      }

      // Obtain the size of the user information in the token.
      if (GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti)) {

         // Call should have failed due to zero-length buffer.
         __leave;
   
      } else {

         // Call should have failed due to zero-length buffer.
         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            __leave;
      }

      // Allocate buffer for user information in the token.
      ptiUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbti);
      if (!ptiUser)
         __leave;

      // Retrieve the user information from the token.
      if (!GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti))
         __leave;

      // Retrieve user name and domain name based on user's SID.
      if (!LookupAccountSid(NULL, ptiUser->User.Sid, szUser, pcchUser, 
            szDomain, pcchDomain, &snu))
         __leave;
      
      fSuccess = TRUE;

   } __finally {

      // Free resources.
      if (hToken)
         CloseHandle(hToken);

      if (ptiUser)
         HeapFree(GetProcessHeap(), 0, ptiUser);
   }

   return fSuccess;
} 

Additional query words:

Keywords : kbAPI kbKernBase kbOSWin2000 kbSecurity kbDSupport kbOSWinNT350 kbGrpDSKernBase
Issue type : kbhowto
Technology : kbAudDeveloper kbWin32sSearch kbWin32API


Last Reviewed: October 27, 2000
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.