Как получить токен текущего пользователя для физического сеанса?

У меня есть код, с помощью которого я пытаюсь получить токен текущего сеанса пользователя:

#include <Wtsapi32.h>

DWORD activeSessionId = WTSGetActiveConsoleSessionId();

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

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

Значение ошибки 1314.

Обновление 1

Пока что не повезло, попытался предоставить текущий процесс SE_TCB_NAME - но все равно получаю ту же ошибку от 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;
}

Обновление 2:

Добавлена ​​дополнительная информация об отладке, но prevState.PrivilegeCount равно 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;
}

Решение:

Похоже, WTSQueryUserToken может использоваться только при запуске в качестве LocalSystem, что означает, что мне придется запускать как службу и отлаживать оттуда... Дох!

1 ответ

Решение

Ошибка 1314: ERROR_PRIVILEGE_NOT_HELD. Вам нужна привилегия SE_TCB_NAME для вызова WTSQueryUserToken.

Эта привилегия обычно поддерживается только кодом, работающим как локальная система. Если эта привилегия присутствует в вашем токене, но отключена, вы можете использовать AdjustTokenPrivileges, чтобы включить ее. Поскольку SE_TCB_NAME является потенциально очень опасной привилегией, вы должны снова отключить ее сразу после ее использования. Простой способ проверить, есть ли у вас эта привилегия, с помощью Process Explorer в таблице Security окна свойств процесса.

Для обновления 1 - возвращает ли AdjustTokenPrivileges успех, но для GetLastError() установлено значение ERROR_NOT_ALL_ASSIGNED? MSDN указывает, что может вернуть это, если привилегии не были включены. Можете ли вы проверить, что у вашего процесса есть привилегия SE_TCB_NAME, но он отключен? Какую учетную запись запускает ваш процесс?

Другие вопросы по тегам