views:

653

answers:

1

I have some code, with which I'm trying to get the current session user token:

#include <Wtsapi32.h>

DWORD activeSessionId = WTSGetActiveConsoleSessionId();

HANDLE currentToken;
BOOL queryRet = WTSQueryUserToken(activeSessionId, &currentToken);

if (!queryRet) {
 DWORD err = GetLastError();
 return 0;
}

Value of err is 1314.

Update 1

No luck so far, tried to grant the current process SE_TCB_NAME - but still get same error from WTSQueryUserToken (1314).

HANDLE process = GetCurrentProcess();

HANDLE processToken;
BOOL openTokenRet = OpenProcessToken(
 process, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &processToken);

if (!openTokenRet)
{
 DWORD err = GetLastError();
 return 0;
}

TOKEN_PRIVILEGES tokenPrivs;
BOOL lookupRet = LookupPrivilegeValue(
 NULL, SE_TCB_NAME, &tokenPrivs.Privileges[0].Luid);

if (!lookupRet)
{
 DWORD err = GetLastError();
 return 0;
}

tokenPrivs.PrivilegeCount = 1;
tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

BOOL adjustRet = AdjustTokenPrivileges(
 processToken, FALSE, &tokenPrivs, 0, (PTOKEN_PRIVILEGES)NULL, 0);

if (!adjustRet)
{
 DWORD err = GetLastError();
 return 0;
}

// get the user in the active session
HANDLE currentToken;
BOOL queryRet = WTSQueryUserToken(activeSessionId, &currentToken);

if (!queryRet) {
 DWORD err = GetLastError();
 return 0;
}

Update 2:

Added some more debug info, but prevState.PrivilegeCount is 0...

TOKEN_PRIVILEGES prevState;
DWORD prevStateLen = 0;

BOOL adjustRet = AdjustTokenPrivileges(
 processToken, FALSE, &tokenPrivs, 
 sizeof(TOKEN_PRIVILEGES), &prevState, &prevStateLen);

DWORD adjustErr = GetLastError();
if (!adjustRet)
{
 return 0;
}

Solution:

Looks like WTSQueryUserToken can only be used when running as LocalSystem, which means I'll have to run as a service and debug from there... Doh!

+2  A: 

Error 1314 is ERROR_PRIVILEGE_NOT_HELD. You need SE_TCB_NAME privilege to call WTSQueryUserToken.

This privilege is typically held only by code running as Local System. If this privilege is present in your token, but disabled, you can use AdjustTokenPrivileges to enable it. Since SE_TCB_NAME is a potentially very dangerous privilege to have, you should disable it again immediately after you use it. An easy way to see if you have this privilege is with Process Explorer in the Security table of the process properties window.

Per Update 1 - is AdjustTokenPrivileges return success, but GetLastError() is set to ERROR_NOT_ALL_ASSIGNED? MSDN indicates it could return this if privileges weren't enabled. Can you verify that your process does have SE_TCB_NAME privilege, but it is disabled? What account is your process running as?

Michael
Hmm, tried but with no luck. Please check update 1.
nbolton
From MSDN:The token does not have one or more of the privileges specified in the NewState parameter. The function may succeed with this error value even if no privileges were adjusted. The PreviousState parameter indicates the privileges that were adjusted.It looks like this function could succeed but not enable privileges.
Michael
Aha, I can confirm GetLastError() gives ERROR_NOT_ALL_ASSIGNED - but value of adjustRet is TRUE. So, I've populated a TOKEN_PRIVILEGES struct, but the value of PrivilegeCount is 0... Does this mean nothing was changed? See update 2.
nbolton
@Nick - What account is your process running as? Are you running on a thread thas is impersonating another user?
Michael
Michael: Normal user account which is a member of Administrators on Vista. I have also tried run as Administrator with no difference.
nbolton
Administrators don't have TCB. You need to run as LocalSystem to do this.Are you trying to grab another user's token or your own?
Michael
Well, I'm trying to launch a process under the user who is in the active session. When deployed, this will be called from a service running as LocalSystem (so there will be no problems there), however, I want to debug it right now, so I need to launch from my user account. I've got the active session ok, but as you know, WTSQueryUserToken gives ERROR_PRIVILEGE_NOT_HELD.
nbolton
@Nick - No easy way to get around the TCB issue, you need to get your code installed and running as a service. You can still use normal debugging tools to debug a service.
Michael
Hmm, ok will do that, thanks.
nbolton