作为本地系统或本地服务运行的C#Windows服务是否可以在不需要该用户密码的情况下模拟其他用户?
怎么做?
Note: 我的动机是能够在服务中运行用户特定的WMI查询 . WMI调用我希望用户在安装服务时必须输入他们的用户名和密码,所以我想将服务作为本地系统或其他东西运行,并冒充我关心的用户 .
假设您只需要在相关用户登录时启动模拟,您可以:
使用EnumProcesses找到相关的用户会话(例如http://msdn.microsoft.com/en-us/library/windows/desktop/ms682623(v=vs.85).aspx)[winapi]相关用户进程
OpenProcessToken()[winapi]具有模拟权限的
DuplicateToken()[winapi]
使用DuplicateToken的结果创建一个新的WindowsIdentity()
呼叫 . 从第4步开始,对您的新身份进行身份验证
一旦令牌被复制,用户记录 - 服务中的模拟仍然存在也无关紧要 .
显然,未记录的ZwCreateToken winapi函数的API也可以实现这一点,但我从未使用它,并且可能在将来的任何时候中断 .
据我所知,出于明显的安全原因,无法做到这一点 . 您必须拥有密码才能调用LogonUser,然后调用WindowsIdentity.Impersonate .
一个例外:如果您通过远程调用将现有的WindowsIdentity传递给服务,那么您可以在服务中模拟WindowsIdentity,但不会以这种方式运行应用程序 .
Topshelf窗口服务API /工具支持它并且是开源的 . [更新]我错过了你至少需要密码才能进行一次性配置 .
3 回答
假设您只需要在相关用户登录时启动模拟,您可以:
使用EnumProcesses找到相关的用户会话(例如http://msdn.microsoft.com/en-us/library/windows/desktop/ms682623(v=vs.85).aspx)[winapi]
相关用户进程
OpenProcessToken()[winapi]
具有模拟权限的
DuplicateToken()[winapi]
使用DuplicateToken的结果创建一个新的WindowsIdentity()
呼叫 . 从第4步开始,对您的新身份进行身份验证
一旦令牌被复制,用户记录 - 服务中的模拟仍然存在也无关紧要 .
显然,未记录的ZwCreateToken winapi函数的API也可以实现这一点,但我从未使用它,并且可能在将来的任何时候中断 .
据我所知,出于明显的安全原因,无法做到这一点 . 您必须拥有密码才能调用LogonUser,然后调用WindowsIdentity.Impersonate .
一个例外:如果您通过远程调用将现有的WindowsIdentity传递给服务,那么您可以在服务中模拟WindowsIdentity,但不会以这种方式运行应用程序 .
Topshelf窗口服务API /工具支持它并且是开源的 . [更新]我错过了你至少需要密码才能进行一次性配置 .