调用WTSQueryUserToken()返回错误码1314的问题排查请求
解决WTSQueryUserToken返回错误码1314的问题
错误码1314对应ERROR_PRIVILEGE_NOT_HELD,即便你确认LocalSystem账户持有SE_TCB_NAME特权,仍可能因以下遗漏操作导致失败,逐一排查:
确保特权在当前线程显式启用
账户拥有特权不代表当前线程已激活该特权,必须通过代码显式启用。在调用WTSQueryUserToken前添加以下代码:BOOL EnablePrivilege(LPCWSTR privilegeName) { HANDLE hToken; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return FALSE; } TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; LookupPrivilegeValueW(NULL, privilegeName, &tp.Privileges[0].Luid); tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; BOOL ret = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); CloseHandle(hToken); return ret; } // 调用WTSQueryUserToken前执行 EnablePrivilege(SE_TCB_NAME);确认会话ID为用户交互会话
WTSEnumerateSessions返回的Active会话可能包含系统会话(通常ID为0),这类会话无关联用户令牌。可通过WTSQuerySessionInformation获取会话用户名,筛选出实际用户登录的会话后再调用WTSQueryUserToken:WCHAR* pUsername = NULL; DWORD bytesReturned; if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, &pUsername, &bytesReturned)) { if (wcslen(pUsername) > 0) { // 排除空用户名的系统会话 // 在此处调用WTSQueryUserToken } WTSFreeMemory(pUsername); }检查是否需要SE_ASSIGNPRIMARYTOKEN_NAME特权
部分场景(如后续用令牌创建进程)中,除SE_TCB_NAME外,还需启用SE_ASSIGNPRIMARYTOKEN_NAME特权,可在上述EnablePrivilege函数中同时激活这两个特权。UAC相关限制
若目标用户是管理员且UAC启用,WTSQueryUserToken返回的是受限令牌。如需完整管理员令牌,需在获取令牌后调用GetTokenInformation获取LinkedToken,但此操作不影响WTSQueryUserToken本身的调用结果。
内容的提问来源于stack exchange,提问作者Arun Kumar S
相关产品推荐
相关产品推荐

