我的目标是从系统服务为有权访问网络驱动器(映射或UNC)的不同用户启动一个子进程。 为了简化测试场景,我为可以访问网络驱动器的帐户创建了一个应用程序,并使用该帐户的凭据通过
CreateProcessWithLogonW
创建一个子进程。
对于我正在使用的登录标志
LOGON_WITH_PROFILE
,对于创建标志 CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT
以及对于环境和当前目录 NULL
。
从属进程启动,但
FindFirstFileEx
失败,代码为 1326 - ERROR_LOGON_FAILURE,这也是我从 sysinternals 的进程监视器看到的信息。
但是,如果我通过
WTSQueryUserToken
从用户会话中窃取令牌,则 CreateProcessAsUser
就像魅力一样,后续进程可以通过 FindFirstFileEx
访问映射的网络驱动器。不幸的是,这不是一个有效的解决方案,因为这应该在没有任何人登录系统的情况下工作。
如果您提供有关如何使用
CreateProcessWithLogonW
或 LogonUser
和 CreateProcessAsUser
的组合解决问题的建议,我将不胜感激。
提前致谢,
阿希姆
从 Windows 2000 SP2 开始,网络凭据与特定的登录会话身份验证 ID (LUID) 绑定。如果您调用
LogonUser
或任何内部创建新登录会话的 API,该新会话将不会继承任何映射驱动器等。
在简单 UAC 提升的情况下,可以将 EnableLinkedConnections 注册表值设置为允许所有提升的进程继承在登录屏幕上创建的“原始登录会话”的网络凭据(对 Superuser 的评论声称此注册表值不再适用于 Windows 10)。如果您是 NT 服务,则此解决方法不适用于您。
如果您控制正在创建的子进程,则子进程需要调用
NetUseAdd
或 WNetAddConnection
为其登录会话建立网络凭据和映射驱动器。这将需要访问用户密码。子进程也许可以(通过管道)向服务询问密码。
如果您不控制子进程,则必须创建一个充当中间人的进程,首先设置网络,然后调用常规
CreateProcess
来创建预期的子进程。