WTSQueryUserToken 返回 5(ERROR_ACCESS_DENIED)

问题描述 投票:0回答:1

我有一个程序以 SYSTEM 身份运行,并尝试通过以下代码查询登录用户令牌:

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)
    }
}

以上代码在Win10中运行成功。但在 Win7 32 位中,WTSQueryUserToken() 总是返回 False,错误为 5 (ERROR_ACCESS_DENIED)。

我是否遗漏了Win7环境下的任何配置?

===编辑====

我的程序作为服务运行,遵循示例

我希望我的程序作为 LocalSystem 帐户运行,作为 CreateServer() 中的最后第二个参数 (NULL)。

c++ windows winapi
1个回答
1
投票

之前版本的 MSDN 文档

WTSQueryUserToken
在可能的错误值方面更加完整

错误_访问_拒绝

调用者没有适当的权限来调用此函数。调用者必须在上下文中运行 LocalSystem 帐户并拥有

SE_TCB_NAME
权限。

但是当调用者没有

SE_TCB_NAME
权限时,会返回不同的错误代码:

错误_PRIVILEGE_NOT_HELD

调用者没有

SE_TCB_NAME
权限。

因此,当调用者不作为

LocalSystem 运行时,会返回 ERROR_ACCESS_DENIED。具体来说,这意味着调用者令牌的 
TokenUser
不是
S-1-5-18
( NT AUTHORITY\SYSTEM - WellKnownGroup )

在内部

WTSQueryUserToken
首先检查是否持有并启用
SE_TCB_NAME
权限,如果不是,则返回
ERROR_PRIVILEGE_NOT_HELD

否则,将使用

WinStationQueryInformationW
来调用
WinStationUserToken
。成功时会返回
WINSTATIONUSERTOKEN
。这是对 LSM 服务的远程调用,它通常在 svchost.exe 进程中运行,命令行中带有 LSM。调用由 lsm.dll 处理,其中

RPC_STATUS CALLBACK CPrivateRpc::staticRpcSecurityCallback(void *,int);

被调用(该函数位于lsm.dll内部)。里面有一个函数

HRESULT CUtils::IsCallerSystem();

被称为。此函数检查调用者令牌的

TokenUser
是否为
S-1-5-18
,如果不是 -
CPrivateRpc::staticRpcSecurityCallback
使用
ERROR_ACCESS_DENIED
删除调用 - 并向调用者返回错误。

因此请检查您的代码真正在哪个上下文中运行。

© www.soinside.com 2019 - 2024. All rights reserved.