如何获取 CreateProcessAsUser 的有效用户令牌?
我有一个以普通用户身份运行的应用程序,以及一个以本地系统身份运行的服务。 我希望应用程序能够告诉服务在服务完成其他一些操作后再次启动应用程序。 (因此,当服务正在执行“操作”时,应用程序将不会运行。)为了使服务能够以首次启动应用程序的用户身份启动应用程序,它需要一个用户令牌。 应用程序在退出之前将令牌发送到服务,但当服务尝试使用令牌/句柄时,该令牌/句柄无效。 (它做的第一件事是 DuplicateTokenEx 获取主令牌。)
用户令牌是否始终仅在调用 OpenProcessToken 的进程中有效?
还有其他方法可以做到这一点吗? 我不希望用户必须使用 logonuser“登录”应用程序。 那太愚蠢了。 我想我可以将“explorer.exe”的进程句柄从应用程序移交给服务,服务可以使用该进程句柄获取用户令牌,但这需要 PROCESS DUP HANDLE 访问权限。 我对这个解决方案并不感到兴奋,但也许这就是实现这一目标的方法?
I have an application that is running as normal user, and a service running as local system. I want the application to be able to tell the service to start the application again, once the service has done some other stuff. (So the application will not be running while the service is doing it's "thing".) In order for the service to be able to start the application as the user that first started it, it needs a user token. The application sends the token to the service before it quits, but the token/handle is invalid when the service is trying to use it. (First thing it does with it is DuplicateTokenEx to get a primary token.)
Is a user token always only valid in the process that called OpenProcessToken?
Is there some other way this could be done? I don't want the user having to "log on" to the application with logonuser. That would just be silly. I guess I could hand over a process handle for "explorer.exe" from the app to the service, which the service could use to get a user token, but that would require PROCESS DUP HANDLE access right. I'm not thrilled about that solution, but maybe it's the way to do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在这里遇到多个问题,因此我将尝试分别解决它们,如果我误解了,您可以纠正我:
您似乎有一个服务和一个用户应用程序无法同时执行某些功能。 为了实现此目的,您需要服务停止应用程序,执行特殊功能,然后重新启动应用程序。 如果这是正确的,那么在我看来,你就有设计缺陷。 您应该使用命名互斥体和/或使用 IPC 方法(例如命名管道)进行互斥来协调对共享资源的访问,而不是停止然后重新启动应用程序来传达意图。
用户令牌是否始终仅在调用 OpenProcessToken 的进程中有效? 是的,您收到的令牌句柄是进程句柄表的索引,它不能直接传输。 您需要使用 DuplicateHandle,这可能是您想要的,但可能会很混乱。
您希望找到获取用户令牌的最佳方法,以将应用程序启动到用户的(交互式?)会话中。 如果是这种情况,最好的方法是检索用户的会话令牌并使用它。 您可以查看这篇文章示例代码采用 C# 语言,但应该相对容易转换为您选择的语言。
编辑:更新为包括 Windows 2000。由于您在 SYSTEM 帐户下运行该服务,因此它可以打开进程本身的句柄(如果需要,进程可以发送其进程 ID)。 然后,它可以打开附加到该进程的令牌,复制它并使用生成的令牌来启动(或重新启动)目标应用程序。
You have multiple issues here so I'll try to address them separately and you can correct me if I have misunderstood:
You appear to have a service and a user application that cannot execute certain functionality at the same time. In order to achieve this you have the service stop the application, execute the special functionality, then restart the application. If this is correct then, in my opinion, you have a design flaw. Rather than stopping, then restarting the application you should be coordinating access to the shared resource through mutual exclusion using a named mutex and/or using an IPC method such as named pipes to communicate intentions.
Is a user token always only valid in the process that called OpenProcessToken? Yes, the token handle you received is an index into the handle table of the process, it is not directly transferable. You would need to use DuplicateHandle which may be what you want but could be messy.
You wish to find the best way to get the user's token to launch the application into the user's (interactive?) session. If this is the case, the best way is to retrieve the user's session token and use that. You can check out this article and the sample code, it's in C# but should be relatively easy to transfer to your language of choice.
EDIT: Updated to include Windows 2000. Since you are running the service under the SYSTEM account it can open a handle to the process itself (if necessary the process can send its process ID). It can then open the token attached to that process, duplicate it and use the resultant token to launch (or re-launch) the target application.