【问题标题】:Python Windows Service: access denied when calling SetTokenInformationPython Windows 服务:调用 SetTokenInformation 时拒绝访问
【发布时间】:2017-06-20 07:54:10
【问题描述】:

我有用 Python 编写的 Windows 服务。我需要做的是在指定的用户会话中从此服务启动一些应用程序。该服务在会话 0 中运行,所以我使用的算法是下一个:

  1. 从当前服务中获取令牌,该服务拥有(实际上应该)完整的系统权限。

  2. 复制它。

  3. 将我想要的会话 ID 分配给重复的令牌。
  4. 使用“CreateProcessAsUser”函​​数使用重复的令牌运行应用程序。

我在 C++ windows 服务上写了同样的东西,而且效果很好。至于 Python,我在尝试调用“SetTokenInformation”函数时遇到“访问被拒绝”。可能有人有一个想法,为什么会发生这种情况,或者可以共享另一种方式来通过 Windows 服务的 ID 在某些用户会话中启动进程?

这里有一些代码:

class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"

def __init__(self,args):
    win32serviceutil.ServiceFramework.__init__(self,args)
    self.hWaitStop = win32event.CreateEvent(None,0,0,None)

def SvcStop(self):
    self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
    win32event.SetEvent(self.hWaitStop)

def SvcDoRun(self):
    servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                          servicemanager.PYS_SERVICE_STARTED,
                          (self._svc_name_,''))
    self.main()

def get_next_msg(self):
    address = ('localhost', 6000)
    listener = Listener(address, authkey='secret password')
    conn = listener.accept()
    msg = conn.recv()
    listener.close()
    return msg

def process_msg(self):
    token = win32security.OpenProcessToken(win32process.GetCurrentProcess(), 
                 win32security.TOKEN_ALL_ACCESS)

    duplicated = win32security.DuplicateToken(token, 2)

    curr_proc_id = win32process.GetCurrentProcessId()
    curr_session_id = win32ts.ProcessIdToSessionId(curr_proc_id)

    # access denied! error code: 5
    win32security.SetTokenInformation(duplicated, win32security.TokenSessionId, curr_session_id)

def main(self):
    while True:
        msg = self.get_next_msg()
        self.process_msg()


if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

【问题讨论】:

    标签: python session windows-services access-denied


    【解决方案1】:

    在 Windows 10 上,以管理员身份运行,使用 activepython 2.7 32 位最新版本 + pywin32 最新版本,您的代码可以完美运行。

    我建议尝试使用 ActivePython 并更新您的 pywin32,然后关闭您的防病毒软件并重试您的代码。

    【讨论】:

    • 非常感谢您花时间回答这个问题并尝试这个例子。在调用 SetTokenInformation 之后,您是否设法运行上面的代码并且没有出现任何错误?
    【解决方案2】:

    解决方法是使用 DuplicateTokenEx 代替 DuplicateToken:

        duplicated = win32security.DuplicateTokenEx(token, 
                                                    impersonation_lvl, 
                                                    win32security.TOKEN_ALL_ACCESS, 
                                                    win32security.TokenPrimary)
    

    然后 SetTokenInformation 运行良好,不会因访问被拒绝错误而失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-06
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 1970-01-01
      相关资源
      最近更新 更多