HOWTO: Look Up Current User Name and Domain Name

ID: Q155698

The information in this article applies to:

SUMMARY

This article describes programmatic approaches to obtaining the user name and domain name of the calling user. Platform specific differences are also described in this article.

MORE INFORMATION

The calling user typically represents the interactively logged on user, but this may not be the case in Windows NT because Windows NT allows multiple security contexts, potentially representing multiple users. A similar scenario may exist when one or more threads in a process are impersonating a client, such as through the ImpersonateNamedPipeClient() Win32 API call. Another example of this scenario occurs when querying the user name and domain name in a service. A service running in the local system account will have a domain name of NT AUTHORITY and a user name of SYSTEM.

Obtaining User Name

If only the user name is required, the GetUserName() API call can be used to retrieve the username of the caller. This Win32 API call works on Windows NT and Windows 95.

In Windows NT, the GetUserName() API 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 impersonation is returned by GetUserName(). Otherwise, the user name associated with the calling process is returned.

Obtaining User Name and Domain Name

In order to obtain the domain name associated with the current user, different approaches are required depending on the operating system where the code is expected to run.

Windows NT

The following code illustrates how to obtain the user name and domain name associated with the calling thread or process by using Win32 security API for Windows NT:

   #include <windows.h>
   #include <lmcons.h>     // DNLEN, UNLEN
   #include <tchar.h>

   BOOL
   GetUserAndDomainName(
       LPTSTR UserName,
       LPDWORD cchUserName,
       LPTSTR DomainName,
       LPDWORD cchDomainName
       );

   #define RTN_OK 0
   #define RTN_ERROR 13

   int
   __cdecl
   main(
       void
       )
   {
       TCHAR User[UNLEN + 1];
       TCHAR Domain[DNLEN + 1];
       DWORD cchUser = UNLEN;
       DWORD cchDomain = DNLEN;

       if(GetUserAndDomainName(User, &cchUser, Domain, &cchDomain)) {
           _tprintf(TEXT("%s\\%s\n"), Domain, User);
           return RTN_OK;
       } else {
           printf("GetUserAndDomainName error! (rc=%lu)\n",
                  GetLastError());
           return RTN_ERROR;
       }
   }

   BOOL
   GetUserAndDomainName(
       LPTSTR UserName,
       LPDWORD cchUserName,
       LPTSTR DomainName,
       LPDWORD cchDomainName
       )
   {
       HANDLE hToken;

       #define MY_BUFSIZE 512  // highly unlikely to exceed 512 bytes
       UCHAR InfoBuffer[ MY_BUFSIZE ];
       DWORD cbInfoBuffer = MY_BUFSIZE;
       SID_NAME_USE snu;

       BOOL bSuccess;

       if(!OpenThreadToken(
           GetCurrentThread(),
           TOKEN_QUERY,
           TRUE,
           &hToken
           )) {

           if(GetLastError() == ERROR_NO_TOKEN) {

               // 
               // attempt to open the process token, since no thread token
               // exists
               // 

               if(!OpenProcessToken(
                   GetCurrentProcess(),
                   TOKEN_QUERY,
                   &hToken
                   )) return FALSE;

           } else {

               // 
               // error trying to get thread token
               // 

               return FALSE;
           }
       }

       bSuccess = GetTokenInformation(
           hToken,
           TokenUser,
           InfoBuffer,
           cbInfoBuffer,
           &cbInfoBuffer
           );

       if(!bSuccess) {
           if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {

               // 
               // alloc buffer and try GetTokenInformation() again
               // 

               CloseHandle(hToken);
               return FALSE;

           } else {

               // 
               // error getting token info
               // 

               CloseHandle(hToken);
               return FALSE;
           }
       }

       CloseHandle(hToken);

       return LookupAccountSid(
           NULL,
           ((PTOKEN_USER)InfoBuffer)->User.Sid,
           UserName,
           cchUserName,
           DomainName,
           cchDomainName,
           &snu
           );
   }

Windows 95 and Windows (16bit)

In Windows 95, there is no 32-bit function for obtaining the domain name associated with the logged on user. However, it is possible to obtain the user name and domain name by calling the 16-bit LAN Manager function NetWkstaGetInfo() at info-level 10. This function is exported by the 16-bit Netapi.dll. The header files and libraries associated with the LAN Manager API calls can be found in the 16-bit LAN Manager SDK, or the Windows for Workgroups SDK, found in the MSDN L2 SDK kits.

For additional information on how to call 16-bit code from 32-bit code, please see the following article(s) in the Microsoft Knowledge Base:

   ARTICLE-ID: Q155763
   TITLE     : HOWTO: Call 16-bit Code from 32-bit Code on Windows 95

The following code fragment illustrates the call to NetWkstaGetInfo().

   #include <windows.h>

   #include <netcons.h>
   #include <wksta.h>
   #include <neterr.h>

       #define BUFFER_SIZE 512

       unsigned short cbTotalAvail;
       char buf[ BUFFER_SIZE + 1 ];

       struct wksta_info_10 far *wi10 = (struct wksta_info_10 far *)buf;
       unsigned short nas;

       nas = NetWkstaGetInfo(
               NULL,
               10,
               (char far *)wi10,
               BUFFER_SIZE,
               &cbTotalAvail
               );

       if( nas == NERR_Succes ) {

           // 
           // success, use
           // wi10->wki10_logon_domain (contains logon domain name)
           // wi10->wki10_username (contains user name)
           // 

       } else {

           // 
           // error occurred
           // 
       }

Additional query words: username domain
Keywords          : kbnetwork kbAPI kbKernBase kbNTOS310 kbNTOS350 kbNTOS351 kbNTOS400 kbSDKPlatform kbSecurity kbWinOS95 kbNetAPI kbCodeSam kbGrpNet 
Issue type        : kbhowto

Last Reviewed: September 11, 1998