Current User and Domain Names
Added 31 Jul 2008
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). 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 following sample code demonstrates how to programmatically retrieve the user name and domain name on Windows NT:
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 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.
//
//**********************************************************************
function GetCurrentUserAndDomain(szUser : PChar; pcchUser : DWORD;
szDomain : PChar; pcchDomain: DWORD) : boolean;
var
fSuccess : boolean;
hToken : THandle;
ptiUser : PSIDAndAttributes;
cbti : DWORD;
snu : SID_NAME_USE;
begin
ptiUser := nil;
Result := false;
try
// Get the calling thread's access token.
if (not OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,
hToken)) then
begin
if (GetLastError() <> ERROR_NO_TOKEN) then
exit;
// Retry against process token if no thread token exists.
if (not OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
hToken)) then
exit;
end;
// Obtain the size of the user information in the token.
if (GetTokenInformation(hToken, TokenUser, nil, 0, cbti)) then
// Call should have failed due to zero-length buffer.
Exit
else
// Call should have failed due to zero-length buffer.
if (GetLastError() <> ERROR_INSUFFICIENT_BUFFER) then
Exit;
// Allocate buffer for user information in the token.
ptiUser := HeapAlloc(GetProcessHeap(), 0, cbti);
if (ptiUser= nil) then
Exit;
// Retrieve the user information from the token.
if ( not GetTokenInformation(hToken, TokenUser, ptiUser, cbti, cbti)) then
Exit;
// Retrieve user name and domain name based on user's SID.
if ( not LookupAccountSid(nil, ptiUser.Sid, szUser, pcchUser,
szDomain, pcchDomain, snu)) then
Exit;
fSuccess := TRUE;
finally
// Free resources.
if (hToken > 0) then
CloseHandle(hToken);
if (ptiUser <> nil) then
HeapFree(GetProcessHeap(), 0, ptiUser);
end;
Result := fSuccess;
end;