Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting username a process is running under

228 views
Skip to first unread message

J Hall

unread,
Jan 21, 2002, 4:21:42 PM1/21/02
to
Hi,

I understand it is possible to query a running process to get the user
name that is is 'running under' on NT/W2K. Does anyone know how to do
this?

J

Marcel van Brakel

unread,
Jan 21, 2002, 5:17:16 PM1/21/02
to
> I understand it is possible to query a running process to get the user
> name that is is 'running under' on NT/W2K. Does anyone know how to do
> this?

From within the process itself it's as easy as calling GetUserName(). From
outside the process it's a bit more difficult and involves using the various
security API functions to examine the process (or thread) token.

best regards,
Marcel van Brakel


J Hall

unread,
Jan 21, 2002, 5:42:13 PM1/21/02
to
In article <3c4c922b_1@dnews>, bra...@nospam.chello.nl wrote...

Hi,

Its from outside the process I need to obtain the UserName. I have
tried various samples I found on the Web (GetTokenPrivilages etc.), but
keep getting various errors like...

- No such login session exists
- Unable to get user info from LUID
- The Local Security Authority cannot be contacted

As these errors have happened with a number of different samples from
different places, I am wondering if I need to have anything special
running? (I am using NT)

J

Marcel van Brakel

unread,
Jan 22, 2002, 2:33:58 AM1/22/02
to
> Its from outside the process I need to obtain the UserName. I have
> tried various samples I found on the Web (GetTokenPrivilages etc.), but
> keep getting various errors like...

Here's a complete command line application that works on my Win2K system for
most running processes. Just lauch it and specify the PID of the process as
it's sole argument (written and tested with Delphi 6 only). I've only tried
it when logged on as an administrator with the debug privilege assigned (it
will probably fail for processes running under a different account if you
don't have it assigned to your user account). Please note that this will
only return the username the process was running under when it was launched,
it completely ignores impersonation. I don't remember any method to obtain
that information other than from within the process itself (thinking
CreateRemoteThread might help with that).

best regards,
Marcel van Brakel

program psuser;

{$APPTYPE CONSOLE}

uses
Windows,
SysUtils,
AclApi;

function EnableProcessPrivilege(const Enable: Boolean; const Privilege:
string): Boolean;
const
PrivAttrs: array [Boolean] of DWORD = (0, SE_PRIVILEGE_ENABLED);
var
Token: THandle;
ReturnLength: Cardinal;
TokenPriv: TTokenPrivileges;
begin
Result := False;
if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, Token)
then
begin
TokenPriv.PrivilegeCount := 1;
LookupPrivilegeValue(nil, PChar(Privilege),
TokenPriv.Privileges[0].Luid);
TokenPriv.Privileges[0].Attributes := PrivAttrs[Enable];
AdjustTokenPrivileges(Token, False, TokenPriv, SizeOf(TokenPriv), nil,
ReturnLength);
Result := GetLastError = ERROR_SUCCESS;
CloseHandle(Token);
end;
end;

function LookupAccountBySid(Sid: PSID): string;
var
Name, RefDomain: string;
NameSize, RefDomainSize: DWORD;
Use: Cardinal;
begin
NameSize := 0;
RefDomainSize := 0;
LookupAccountSid(nil, Sid, nil, NameSize, nil, RefDomainSize, Use);
SetLength(Name, NameSize);
SetLength(RefDomain, RefDomainSize);
LookupAccountSid(nil, Sid, PChar(Name), NameSize, PChar(RefDomain),
RefDomainSize, Use);
Result := PChar(RefDomain) + '/' + PChar(Name);
end;

procedure QueryTokenInformation(Token: THandle; InformationClass:
TTokenInformationClass; var Buffer: Pointer);
var
B: BOOL;
Length: DWORD;
begin
Buffer := nil;
Length := 0;
B := GetTokenInformation(Token, InformationClass, Buffer, Length, Length);
while (not B) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) do
begin
ReallocMem(Buffer, Length);
B := GetTokenInformation(Token, InformationClass, Buffer, Length,
Length);
end;
if not B then
begin
FreeMem(Buffer);
Buffer := nil;
raise Exception.Create('Unable to get token information');
end;
end;

type
PTokenUser = ^TTokenUser;
TTokenUser = record
User: TSidAndAttributes;
end;

function GetProcessUser(const PID: Longword): string;
var
Token, Handle: THandle;
User: PTokenUser;
begin
Handle := OpenProcess(PROCESS_QUERY_INFORMATION, False, PID);
if Handle <> 0 then
begin
if OpenProcessToken(Handle, TOKEN_QUERY, Token) then
begin
QueryTokenInformation(Token, TokenUser, Pointer(User));
Result := LookupAccountBySid(User.User.Sid);
CloseHandle(Token);
end;
CloseHandle(Handle);
end;
end;

begin

EnableProcessPrivilege(True, 'SeDebugPrivilege');
if ParamCount = 1 then
begin
WriteLn(GetProcessUser(StrToInt(ParamStr(1))));
end
else WriteLn('Usage: psuser <PID>');

end.

Marcel van Brakel

unread,
Jan 22, 2002, 2:35:58 AM1/22/02
to
> if OpenProcessToken(Handle, TOKEN_QUERY, Token) then
> begin
> QueryTokenInformation(Token, TokenUser, Pointer(User));
> Result := LookupAccountBySid(User.User.Sid);

FreeMem(User); // sorry forgot

> CloseHandle(Token);
> end;
> CloseHandle(Handle);
> end;
> end;

best regards,
Marcel van Brakel


J Hall

unread,
Jan 23, 2002, 7:47:30 AM1/23/02
to
In article <3c4d14a7_1@dnews>, bra...@nospam.chello.nl wrote...

Hi,

> > Its from outside the process I need to obtain the UserName. I have
> > tried various samples I found on the Web (GetTokenPrivilages etc.), but
> > keep getting various errors like...
>
> Here's a complete command line application that works on my Win2K system for
> most running processes. Just lauch it and specify the PID of the process as
> it's sole argument

Thanks, that seams to do what I want.

Many thanks

J

0 new messages