Как получить токен текущего пользователя для физического сеанса?
У меня есть код, с помощью которого я пытаюсь получить токен текущего сеанса пользователя:
#include <Wtsapi32.h>
DWORD activeSessionId = WTSGetActiveConsoleSessionId();
HANDLE currentToken;
BOOL queryRet = WTSQueryUserToken(activeSessionId, ¤tToken);
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, ¤tToken);
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, но он отключен? Какую учетную запись запускает ваш процесс?