Reputation: 416
I have a program runs as SYSTEM and try to query logon user token by the following code:
WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
for (i = 0; i < dwCount; i++) {
WTS_SESSION_INFO si = pSessionInfo[i];
if (WTSActive == si.State) {
WTSQueryUserToken(si.SessionId, &hUserToken)
}
}
The above codes run successfully in Win10. But in Win7 32-bit, WTSQueryUserToken() always return False with error 5 (ERROR_ACCESS_DENIED).
Did I miss any configuration in Win7 environment?
=== Edit ====
My program run as a service which follows the example.
I expect that my program is run as LocalSystem account as the last second argument (NULL) in CreateServer().
Upvotes: 1
Views: 983
Reputation: 33716
The previous version of MSDN documentation for WTSQueryUserToken
was more complete in terms of possible error values
ERROR_ACCESS_DENIED:
The caller does not have the appropriate permissions to call this function. The caller must be running within the context of the LocalSystem account and have the
SE_TCB_NAME
privilege.
But when the caller does not have SE_TCB_NAME
privilege, a different error code is returned:
ERROR_PRIVILEGE_NOT_HELD:
The caller does not have the
SE_TCB_NAME
privilege.
So ERROR_ACCESS_DENIED
is returned when the caller does not run as LocalSystem. Specifically, this means that TokenUser
of the caller's token is not S-1-5-18
( NT AUTHORITY\SYSTEM - WellKnownGroup )
Internally WTSQueryUserToken
first checks if SE_TCB_NAME
privilege is held and enabled and if it's not it returns ERROR_PRIVILEGE_NOT_HELD
.
Otherwise, WinStationQueryInformationW
is called with WinStationUserToken
. The WINSTATIONUSERTOKEN
is returned on success. This is remote call to LSM service, it usually runs in the svchost.exe process with LSM in its command line. A call is handled by lsm.dll, where
RPC_STATUS CALLBACK CPrivateRpc::staticRpcSecurityCallback(void *,int);
is called (this function is inside lsm.dll). Inside it, a function
HRESULT CUtils::IsCallerSystem();
is called. This function checks that TokenUser
of the caller's token is S-1-5-18
and if not - CPrivateRpc::staticRpcSecurityCallback
drops the call with ERROR_ACCESS_DENIED
- and error returned for caller.
So check in which context your code really runs.
Upvotes: 1