Run program as domain user from Windows service (before user logon)

0

I've already asked this question in the past, but without a real solution. So I want to ask it once again because I really need a solution for this problem. What I have is a service running in session 0 as "Network Service" user, which needs to start a command line program (with access to local network) as a domain user from time to time. The domain user is different from the logged in user and it should also work if nobody is logged in. What I have so far are the following 2 code snippets:

token = win32security.LogonUser(userName, domainName, pw, win32security.LOGON32_LOGON_INTERACTIVE, win32security.LOGON32_PROVIDER_DEFAULT)
sessionId = win32ts.WTSGetActiveConsoleSessionId()
userToken = win32ts.WTSQueryUserToken(sessionId)
startup = win32process.STARTUPINFO()
priority = win32con.CREATE_NEW_CONSOLE | win32con.CREATE_NEW_PROCESS_GROUP | win32con.CREATE_UNICODE_ENVIRONMENT | win32con.NORMAL_PRIORITY_CLASS
environment = win32profile.CreateEnvironmentBlock(userToken, False)
handle, thread_id ,pid, tid = win32process.CreateProcessAsUser(userToken, appName, cmdLine, None, None, False, priority, environment, None, startup)
hPrc = ctypes.windll.kernel32.OpenProcess(SYNCHRONIZE, False, pid)
waitHandles = ( hPrc, )
rc = win32event.WaitForMultipleObjects(waitHandles, 0, 120000)

The above code snipped works if parent process runs as SYSTEM user.

userToken = win32security.LogonUser(userName, domainName, pw,
                                    win32con.LOGON32_LOGON_INTERACTIVE,
                                    win32con.LOGON32_PROVIDER_DEFAULT)
secAttrs = win32security.SECURITY_ATTRIBUTES()
secAttrs.bInheritHandle = 1
stdout_r, stdout_w = win32pipe.CreatePipe(secAttrs, 0)
stderr_r, stderr_w = win32pipe.CreatePipe(secAttrs, 0)

startupInfo = win32process.STARTUPINFO()
startupInfo.dwFlags = win32con.STARTF_USESTDHANDLES
startupInfo.hStdOutput = stdout_w
startupInfo.hStdError = stderr_w

ppid = win32api.GetCurrentProcess()
tmp = win32api.DuplicateHandle(ppid, stdout_r, ppid, 0, 0, win32con.DUPLICATE_SAME_ACCESS)
win32file.CloseHandle(stdout_r)
stdout_r = tmp

environment = win32profile.CreateEnvironmentBlock(userToken, False)

procArgs = (None,       # appName
            cmd_line,   # commandLine
            None,       # processAttributes
            None,       # threadAttributes
            1,          # bInheritHandles
            #win32process.CREATE_NEW_CONSOLE, # dwCreationFlags
            win32process.CREATE_NO_WINDOW | win32process.CREATE_UNICODE_ENVIRONMENT, # dwCreationFlags
            environment,       # newEnvironment
            None,       # currentDirectory
            startupInfo)

procHandles = win32process.CreateProcessAsUser(userToken, *procArgs)

win32file.CloseHandle(stderr_w)
win32file.CloseHandle(stdout_w)
win32security.RevertToSelf()

# Wait for process to complete
hProcess, hThread, pid, tid = procHandles

stdout_buf = os.fdopen(msvcrt.open_osfhandle(stdout_r, 0), "rb")
stdout = stdout_buf.read()
stderr_buf = os.fdopen(msvcrt.open_osfhandle(stderr_r, 0), "rb")
stderr = stderr_buf.read()
print(stdout)
print(stderr)

win32event.WaitForSingleObject(hProcess, 3600*1000)
rc = win32process.GetExitCodeProcess(hProcess)

The above solution works if parent process runs as SYSTEM and Network Service user. But both code snippets do not work if started from session 0. The return code is 0xC0000142. My assumption is that the access right to the desktop, and maybe also to the window station need to be set correctly. But how is this done? Does anybody have a working solution?

python
windows
service
process
asked on Stack Overflow Nov 2, 2017 by Martin Bammer

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0