Starting a process with credentials from a Windows Service

后端 未结 8 1616
情话喂你
情话喂你 2020-11-27 05:42

I have a Windows service that runs as mydomain\\userA. I want to be able to run arbitrary .exes from the service. Normally, I use Process.Start() and it works fine, but in s

8条回答
  •  情书的邮戳
    2020-11-27 06:21

    I have reimplemented Martin Prikryl's answer in Python, which I hope someone finds useful.

    I ran into this problem running a subprocess in a Python script. I was using the pythonnet package to run System.Diagnostics.Process as different user. My issue was that the subprocess was not running and I received no stdout or stderr.

    # Import .NET objects using pythonnet
    from System.Diagnostics import Process
    
    # Use .NET API to run a subprocess using the given executable
    # as the target user, in the provided working directory.
    process = Process()
    process.StartInfo.UseShellExecute = False
    process.StartInfo.CreateNoWindow = True
    process.StartInfo.LoadUserProfile = True
    process.StartInfo.RedirectStandardOutput = True
    process.StartInfo.RedirectStandardError = True
    process.StartInfo.WorkingDirectory = working_dir
    process.StartInfo.Domain = "mydomain"
    process.StartInfo.UserName = username.lower().replace("mydomain\\", "")
    process.StartInfo.PasswordInClearText = password
    process.StartInfo.FileName = executable
    process.StartInfo.Arguments = " ".join(args)
    
    # Run the subprocess.
    process.Start()
    
    # Read subprocess console output
    stdout = process.StandardOutput.ReadToEnd()
    stderr = process.StandardError.ReadToEnd()
    log.info(f"\n{executable} subprocess stdout:\n\n{stdout}")
    log.info(f"{executable} subprocess stderr:\n\n{stderr}")
    log.info(f"Done running {executable} as {username}.")
    

    I used Martin Prikryl's answer, but I reimplemented it in Python using the pyWin32 library, which solved my issue.:

    import win32api, win32process, win32service, win32security
    
    WINDOW_STATION_ALL_ACCESS = 983935
    DESKTOP_RIGHTS_ALL_ACCESS = 983551
    SE_WINDOW_OBJECT = 7
    DACL_SECURITY_INFORMATION = 4
    
    
    def set_access(user, handle, access):
        info = win32security.GetSecurityInfo(
            handle, SE_WINDOW_OBJECT, DACL_SECURITY_INFORMATION
        )
        dacl = info.GetSecurityDescriptorDacl()
        dacl.AddAccessAllowedAce(win32security.ACL_REVISION, access, user)
        win32security.SetSecurityInfo(
            handle, SE_WINDOW_OBJECT, DACL_SECURITY_INFORMATION, None, None, dacl, None
        )
    
    
    username = "mattsegal"
    user, domain, user_type = win32security.LookupAccountName("", username)
    thread_id = win32api.GetCurrentThreadId()
    station_handle = win32process.GetProcessWindowStation()
    desktop_handle = win32service.GetThreadDesktop(thread_id)
    set_access(user, station_handle, WINDOW_STATION_ALL_ACCESS)
    set_access(user, desktop_handle, DESKTOP_RIGHTS_ALL_ACCESS)
    

提交回复
热议问题