我正在使用CreateProcessAsUser在用户指定的凭据下创建进程。
我发布了希望代码的相关部分。如果您想再看到更多内容,请与我们联系。
获取令牌的第一个LogonUser:
result = LogonUser(
username,
wcschr(username, '@') ? NULL : (domain ? domain : L"."),
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hrunastoken);
然后我加载配置文件,将STARTUPINFO结构的lpDesktop值设置为NULL(这使得它使用调用进程的桌面),并调用CreateProcessAsUser:
result = CreateProcessAsUser(
hrunastoken,
NULL,
apptorun,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
envblock ? envblock : NULL,
NULL,
&si,
&pi);
这很好用 - 它会成功登录并创建流程,并且流程“有效”。问题是它创建的窗口是黑色的,就像在我的程序启动的记事本流程的屏幕截图中所示:
可能相关的背景:
我的帐户是具有完全管理员权限的Windows 7计算机上的本地帐户,我使用该帐户登录。我使用psexec(Sysinternals实用程序)打开在本地系统帐户下以交互方式运行的命令提示符。我从该命令提示符启动我的程序。我传递给它的凭据来自我的帐户。
我没有对windowstations / desktops的权限做过任何事情;我假设我创建的进程应该拥有权限,因为正在我的会话中创建进程并使用我已经登录的相同帐户 - 尽管首先通过SYSTEM帐户。使用Process Explorer,我看不到通过我的程序正常打开的进程对windowstation / desktop的值和句柄的权限有任何差异。也许这完全不相关。
我也不能使用CreateProcessWithLogonW函数,因为它必须在从SYSTEM帐户运行时起作用 - 该函数以及Windows附带的“runas”程序在SYSTEM下不起作用。
有趣的是,我不能使用我当前的方法来打开进程,除非我在SYSTEM帐户下运行它,因为“客户端没有保留所需的权限”,所以我无法比较创建的窗口在我的帐户下启动我的程序与SYSTEM帐户...
答案 0 :(得分:5)
窗口站和桌面的默认DACL授予对登录SID(当前logon session唯一的)的完全访问权限,而不是用户的SID。 (用户的SID也出现在窗口站的DACL中,但权限有限。它不会出现在桌面DACL中。)
对LogonUser
的调用会生成新会话(以及关联的登录SID),而不是重用现有会话,因此您的进程无权访问桌面,并且只能访问窗口站。 (实际上我对这个过程如何设置运行有点疑惑;当我尝试重现你的结果时,过程会立即退出,退出代码为0xC0000142,正如预期的那样。)
this answer中的第二段代码显示了如何更改窗口站和桌面上的DACL以允许进程正常运行。 (但这可能不是最佳解决方案,具体取决于您的具体目标。)