C++ - Getusername() When Process Is Run as Administrator

C++ - GetUserName() when process is run as administrator

I believe the question you want to ask Windows is "which user is logged into the current session".

To do this, call ProcessIdToSessionId() with your own process's ID to determine the current session ID.

Then call WTSQuerySessionInformation() with the WTSUserName option to fetch the user name.

C++ Get Username From Process

Use OpenProcessToken to get the token (obviously), then GetTokenInformation with the TokenOwner flag to get the SID of the owner. Then you can use LookupAccountSid to get the username.

Is there any way to get non-admin user name when running app as admin

First off, why are you using SHGetKnownFolderPath() to determine a username? That is not what that API is meant for. There are other APIs better suited for getting usernames.

Passing a NULL token handle to SHGetKnownFolderPath() (or any other API that takes a user token as input) will use the user account that is associated with the calling thread, which in this case is an admin user. For what you are asking, you need to pass in an actual token for the logged-in user instead. Or else impersonate the logged-in user before calling such an API with a NULL user token.

WTQueryUserToken() can certainly be used to get a user token, however it can only be used inside a service that is running under the SYSTEM account. If your app is not running as such a service, you would have to create such a service for your app to communicate with.

Otherwise, you will just have to get the username from some another API.

For instance, you can use ProcessIdToSessionId() to get the ID of the session that your app is running in (see Getting the Session ID of the Current Process), and then you can use WTSQuerySessionInformation(WTSUserName) to get the logged-in username of that session.

Or, you can enumerate all running processes, looking for processes that are running in the same session ID as your app, until you find the explorer.exe process, and then you can use OpenProcess() and OpenProcessHandle() to get the user's access token for that process, and then use GetTokenInformation() (TokenUser or TokenOwner) to get the SID of that token, and then finally use LookupAccountSid() to get the username of that SID.

C# window xp current user when using run as

The work around that I used was to place short cuts on the public desktop so everyone gets it. Basically I was hoping for a way around just using the public desktop. I am going to go ahead and put this down as the answer but if anyone else comes up with a solution I will mark it as the answer.

Checking if the current user is in the administrator group with WinAPI

if user member of BUILTIN\Administrators (S-1-5-32-544) group (alias) this sid present in it token groups. and usually only in this case (of course possible create token for not admin user with S-1-5-32-544 and for admin user without it). so simply and effective check - list token groups and look - are S-1-5-32-544 present here, with any attributes. IsUserAdmin not simply check for this sid, but

Even if a SID is present in the token, the system may not use the
SID in an access check. The SID may be disabled or have the SE_GROUP_USE_FOR_DENY_ONLY attribute. The system uses only enabled SIDs to grant access when performing an access check.

when admin user (member of S-1-5-32-544 Alias) interactive login to system and UAC active - system filter it token, and set SE_GROUP_USE_FOR_DENY_ONLY attribute for S-1-5-32-544 (except built-in Administrator - S-1-5-32-500)

so code can be next:

inline ULONG BOOL_TO_ERROR(BOOL f)
{
return f ? NOERROR : GetLastError();
}

ULONG IsUserInAdminGroup(BOOLEAN* pb)
{
*pb = FALSE;

HANDLE hToken;
ULONG dwError = BOOL_TO_ERROR(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken));

if (dwError == NOERROR)
{
// /RTCs must be disabled !
static volatile UCHAR guz = 0;
PVOID stack = alloca(guz);
ULONG cb = 0, rcb = 0x100;

union {
PVOID buf;
PTOKEN_GROUPS ptg;
};

do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}

dwError = BOOL_TO_ERROR(GetTokenInformation(hToken, ::TokenGroups, buf, cb, &rcb));

} while (dwError == ERROR_INSUFFICIENT_BUFFER);

CloseHandle(hToken);

if (dwError == NOERROR)
{
if (ULONG GroupCount = ptg->GroupCount)
{
static const SID_IDENTIFIER_AUTHORITY NT_AUTHORITY = SECURITY_NT_AUTHORITY;
PSID_AND_ATTRIBUTES Groups = ptg->Groups;
do
{
PSID Sid = Groups++->Sid;
if (*GetSidSubAuthorityCount(Sid) == 2 &&
*GetSidSubAuthority(Sid, 0) == SECURITY_BUILTIN_DOMAIN_RID &&
*GetSidSubAuthority(Sid, 1) == DOMAIN_ALIAS_RID_ADMINS &&
!memcmp(&NT_AUTHORITY, GetSidIdentifierAuthority(Sid), sizeof(SID_IDENTIFIER_AUTHORITY)))
{
*pb = TRUE;
break;
}
} while (--GroupCount);
}

return NOERROR;
}
}

return dwError;
}

also possible do direct check of user sid from token - are it member of DOMAIN_ALIAS_RID_ADMINS alias. here question - how exactly is the task, why this necessary at all. example of code (used ntsam.h and linked with samlib.lib - part of standard windows SDK)

HRESULT IsUserInAdminGroup(PSID UserSid, BOOLEAN* pb)
{
SAM_HANDLE ServerHandle, DomainHandle;

NTSTATUS status = SamConnect(0, &ServerHandle, SAM_SERVER_LOOKUP_DOMAIN, 0);

if (0 <= status)
{
ULONG len = GetSidLengthRequired(1);

PSID BuiltIn = (PSID)alloca(len);
static const SID_IDENTIFIER_AUTHORITY NT_AUTHORITY = SECURITY_NT_AUTHORITY;

InitializeSid(BuiltIn, const_cast<SID_IDENTIFIER_AUTHORITY*>(&NT_AUTHORITY), 1);
*GetSidSubAuthority(BuiltIn, 0) = SECURITY_BUILTIN_DOMAIN_RID;

status = SamOpenDomain(ServerHandle, DOMAIN_READ, BuiltIn, &DomainHandle);

SamCloseHandle(ServerHandle);

if (0 <= status)
{
ULONG MembershipCount, *Aliases;

status = SamGetAliasMembership(DomainHandle, 1, &UserSid, &MembershipCount, &Aliases);

SamCloseHandle(DomainHandle);

if (0 <= status)
{
PVOID buf = Aliases;
if (MembershipCount)
{
do
{
if (*Aliases++ == DOMAIN_ALIAS_RID_ADMINS)
{
*pb = TRUE;
break;
}
} while (--MembershipCount);
}
SamFreeMemory(buf);
}
}
}

return HRESULT_FROM_NT(status);
}

HRESULT IsUserInAdminGroup(BOOLEAN* pb)
{
*pb = FALSE;

HANDLE hToken;
ULONG dwError = BOOL_TO_ERROR(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken));

if (dwError == NOERROR)
{
// /RTCs must be disabled !
static volatile UCHAR guz = 0;
PVOID stack = alloca(guz);
ULONG cb = 0, rcb = 0x80;

union {
PVOID buf;
PTOKEN_USER ptu;
};

do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}

dwError = BOOL_TO_ERROR(GetTokenInformation(hToken, ::TokenUser, buf, cb, &rcb));

} while (dwError == ERROR_INSUFFICIENT_BUFFER);

CloseHandle(hToken);

if (dwError == NOERROR)
{
return IsUserInAdminGroup(ptu->User.Sid, pb);
}
}

return HRESULT_FROM_WIN32(dwError);
}


Related Topics



Leave a reply



Submit