def __init__(self, path): self.hInRead = None self.hInWrite = None self.hOutRead = None self.hOutWrite = None sa = pywintypes.SECURITY_ATTRIBUTES() sa.SetSecurityDescriptorDacl(1, None, 0) self.hInRead, self.hInWrite = win32pipe.CreatePipe(sa, 0) self.hOutRead, self.hOutWrite = win32pipe.CreatePipe(sa, 0) si = win32process.STARTUPINFO() si.dwFlags = win32con.STARTF_USESTDHANDLES | \ win32process.STARTF_USESHOWWINDOW si.hStdError = self.hOutWrite si.hStdOutput = self.hOutWrite si.hStdInput = self.hInRead si.wShowWindow = win32con.SW_HIDE create_flags = win32process.CREATE_NEW_CONSOLE self.info = win32process.CreateProcess(None, path, None, None, \ True, create_flags, None, None, si) if self.info[0]: print('create process success')
def start(self, cmd): sAttr = win32security.SECURITY_ATTRIBUTES() sAttr.bInheritHandle = True stdout_r, stdout_w = win32pipe.CreatePipe(sAttr, 0) stdin_r, stdin_w = win32pipe.CreatePipe(sAttr, 0) self.read_handle = stdout_r self.write_handle = stdout_w self.stdin_write = stdin_w si = win32process.STARTUPINFO() si.dwFlags = win32process.STARTF_USESHOWWINDOW | win32process.STARTF_USESTDHANDLES si.wShowWindow = win32con.SW_HIDE si.hStdInput = stdin_r # file descriptor of origin stdin si.hStdOutput = stdout_w si.hStdError = stdout_w hProcess, hThread, dwProcessID, dwThreadID = win32process.CreateProcess( None, "cmd", None, None, True, win32process.CREATE_NEW_CONSOLE, None, None, si) self.dwProcessID = dwProcessID self.hProcess = hProcess sleep(0.5) if self.hProcess == 0: DebugOutput("Start Process Fail:{:d}".format( win32api.GetLastError())) DebugOutput('[*] pid: {:x}'.format(self.dwProcessID)) self.Console_hwnd = get_hwnds_for_pid(self.dwProcessID) if len(self.Console_hwnd) == 0: raise Exception("Fail to run,No Process!") DebugOutput('[*] hwnd:{:x}'.format(self.Console_hwnd[0]))
def __init__(self, cmd, shell=False): self.queue = Queue.Queue() self.is_terminated = False self.wake_up_event = win32event.CreateEvent(None, 0, 0, None) exec_dir = os.getcwd() comspec = os.environ.get("COMSPEC", "cmd.exe") cmd = comspec + ' /c ' + cmd win32event.ResetEvent(self.wake_up_event) currproc = win32api.GetCurrentProcess() sa = win32security.SECURITY_ATTRIBUTES() sa.bInheritHandle = 1 child_stdout_rd, child_stdout_wr = win32pipe.CreatePipe(sa, 0) child_stdout_rd_dup = win32api.DuplicateHandle( currproc, child_stdout_rd, currproc, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(child_stdout_rd) child_stderr_rd, child_stderr_wr = win32pipe.CreatePipe(sa, 0) child_stderr_rd_dup = win32api.DuplicateHandle( currproc, child_stderr_rd, currproc, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(child_stderr_rd) child_stdin_rd, child_stdin_wr = win32pipe.CreatePipe(sa, 0) child_stdin_wr_dup = win32api.DuplicateHandle( currproc, child_stdin_wr, currproc, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(child_stdin_wr) startup_info = win32process.STARTUPINFO() startup_info.hStdInput = child_stdin_rd startup_info.hStdOutput = child_stdout_wr startup_info.hStdError = child_stderr_wr startup_info.dwFlags = win32process.STARTF_USESTDHANDLES cr_flags = 0 cr_flags = win32process.CREATE_NEW_PROCESS_GROUP env = os.environ.copy() self.h_process, h_thread, dw_pid, dw_tid = win32process.CreateProcess( None, cmd, None, None, 1, cr_flags, env, os.path.abspath(exec_dir), startup_info) win32api.CloseHandle(h_thread) win32file.CloseHandle(child_stdin_rd) win32file.CloseHandle(child_stdout_wr) win32file.CloseHandle(child_stderr_wr) self.__child_stdout = child_stdout_rd_dup self.__child_stderr = child_stderr_rd_dup self.__child_stdin = child_stdin_wr_dup self.exit_code = -1
def _launch_idle_process(self, command_line, dir=None): (hChildStdinRd, hChildStdinWr) = win32pipe.CreatePipe(None, 0) (hChildStdoutRd, hChildStdoutWr) = win32pipe.CreatePipe(None, 0) hChildStdinRd = self.make_inheritable(hChildStdinRd) hChildStdoutWr = self.make_inheritable(hChildStdoutWr) startupinfo = win32process.STARTUPINFO() startupinfo.dwFlags = \ win32process.STARTF_USESTDHANDLES | \ win32process.STARTF_USESHOWWINDOW startupinfo.hStdInput = hChildStdinRd startupinfo.hStdOutput = hChildStdoutWr startupinfo.hStdError = hChildStdoutWr appName = None commandLine = command_line processAttributes = None threadAttributes = None bInheritHandles = 1 dwCreationFlags = win32process.IDLE_PRIORITY_CLASS newEnvironment = os.environ currentDirectory = None if dir: currentDirectory = os.path.normpath(os.path.join(os.getcwd(), dir)) ## no dialog boxes that hang the build system SEM_FAILCRITICALERRORS = 0x0001 SEM_NOGPFAULTERRORBOX = 0x0002 SEM_NOALIGNMENTFAULTEXCEPT = 0x0004 SEM_NOOPENFILEERRORBOX = 0x8000 win32api.SetErrorMode( SEM_FAILCRITICALERRORS|\ SEM_NOGPFAULTERRORBOX|\ SEM_NOOPENFILEERRORBOX) try: (hProcess, hThread, dwProcessId, dwThreadId) = \ win32process.CreateProcess( appName, commandLine, processAttributes, threadAttributes, bInheritHandles, dwCreationFlags, newEnvironment, currentDirectory, startupinfo) except pywintypes.error: return None ## close the thread handle, as well as the other I/O handles win32api.CloseHandle(hThread) win32api.CloseHandle(hChildStdinRd) win32api.CloseHandle(hChildStdoutWr) return hProcess, hChildStdinWr, hChildStdoutRd
def __init__(self): # Pipes to stream outputs. security_attributes = win32security.SECURITY_ATTRIBUTES() security_attributes.bInheritHandle = 1 stdout_r, stdout_w = win32pipe.CreatePipe(security_attributes, 0) stderr_r, stderr_w = win32pipe.CreatePipe(security_attributes, 0) self.stdout_r = stdout_r.Detach() self.stdout_w = self._MakeInheritable(stdout_w) self.stderr_r = stderr_r.Detach() self.stderr_w = self._MakeInheritable(stderr_w) # Threads to read pipes and the actual contents returned. self.stdout_read_thread = None self.stdout = None self.stderr_read_thread = None self.stderr = None
def run_command_win32(cmd): sa = win32security.SECURITY_ATTRIBUTES() sa.bInheritHandle = True stdout_r, stdout_w = win32pipe.CreatePipe(sa, 0) si = win32process.STARTUPINFO() si.dwFlags = (win32process.STARTF_USESTDHANDLES | win32process.STARTF_USESHOWWINDOW) si.wShowWindow = win32con.SW_HIDE si.hStdOutput = stdout_w process, thread, pid, tid = \ win32process.CreateProcess(None, cmd, None, None, True, 0, None, None, si) if process == None: return -1, "" # Must close the write handle in this process, or ReadFile will hang. stdout_w.Close() # Read the pipe until we get an error (including ERROR_BROKEN_PIPE, # which is okay because it happens when child process ends). data = "" error = 0 while 1: try: hr, buffer = win32file.ReadFile(stdout_r, 4096) if hr != winerror.ERROR_IO_PENDING: data = data + buffer except pywintypes.error, e: if e.args[0] != winerror.ERROR_BROKEN_PIPE: error = 1 break
def startBackgroundProcess(self): """Method to start a process running in the background. """ with process_lock: # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create pipes for the process to write to hStdin_r, hStdin = win32pipe.CreatePipe(sAttrs, 0) hStdout = win32file.CreateFile( _stringToUnicode(self.stdout), win32file.GENERIC_WRITE | win32file.GENERIC_READ, win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_NORMAL, None) hStderr = win32file.CreateFile( _stringToUnicode(self.stderr), win32file.GENERIC_WRITE | win32file.GENERIC_READ, win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_NORMAL, None) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdInput = hStdin_r StartupInfo.hStdOutput = hStdout StartupInfo.hStdError = hStderr StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles for the thread ends of the pipes. The duplicated handles will # have their inheritence properties set to false so that any children inheriting these # handles will not have non-closeable handles to the pipes pid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(pid, hStdin, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(hStdin) hStdin = tmp # start the process, and close down the copies of the process handles # we have open after the process creation (no longer needed here) old_command = command = self.__quotePath(self.command) for arg in self.arguments: command = '%s %s' % (command, self.__quotePath(arg)) try: self.__hProcess, self.__hThread, self.pid, self.__tid = win32process.CreateProcess( None, command, None, None, 1, 0, self.environs, os.path.normpath(self.workingDir), StartupInfo) except pywintypes.error as e: raise ProcessError("Error creating process %s: %s" % (old_command, e)) win32file.CloseHandle(hStdin_r) win32file.CloseHandle(hStdout) win32file.CloseHandle(hStderr) # set the handle to the stdin of the process self.__stdin = hStdin
def CreatePipe(readInheritable, writeInheritable): """Create a new pipe specifying whether the read and write ends are inheritable and whether they should be created for blocking or nonblocking I/O.""" r, w = win32pipe.CreatePipe(None, SPOOL_BYTES) if readInheritable: r = MakeInheritedHandle(r) if writeInheritable: w = MakeInheritedHandle(w) return r, w
def __init__(self, inherit_handle=True): """Create a pipe for Windows Create a new pipe Args: inherit_handle (bool): Whether the child can inherit this handle Returns: WinPipe: ``WinPipe`` instance. """ attr = win32security.SECURITY_ATTRIBUTES() attr.bInheritHandle = inherit_handle self.rp, self.wp = win32pipe.CreatePipe(attr, 0)
def run (self, cmdline): secAttrs = win32security.SECURITY_ATTRIBUTES() secAttrs.bInheritHandle = 1 """ windows file handle redirection: http://wiki.wxpython.org/Capturing%20DOS%20Output%20in%20a%20wxWindow """ hStdin_r, self.hStdin_w = win32pipe.CreatePipe(secAttrs,0) self.hStdout_r, hStdout_w = win32pipe.CreatePipe(secAttrs,0) self.hStderr_r, hStderr_w = win32pipe.CreatePipe(secAttrs,0) pid = win32api.GetCurrentProcess() # replace the handles self.hStdin_w = self.ReplaceHandle(self.hStdin_w, pid) self.hStdout_r = self.ReplaceHandle(self.hStdout_r, pid) self.hStderr_r = self.ReplaceHandle(self.hStderr_r, pid) # create the startupinformation for the process StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdInput = hStdin_r StartupInfo.hStdOutput = hStdout_w StartupInfo.hStdError = hStderr_w StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES hProcess, hThread, dwPid, dwTid = self.createProcess(cmdline,StartupInfo) self.stdin = os.fdopen(msvcrt.open_osfhandle(self.hStdin_w, 0), "wb") self.stdout = os.fdopen(msvcrt.open_osfhandle(self.hStdout_r, 0), "rb") self.stderr = os.fdopen(msvcrt.open_osfhandle(self.hStderr_r, 0), "rb") baggage = [self.stdin, self.stdout, self.stderr] return baggage
def windows_create_pipe(sAttrs=-1, nSize=None): # Default values if parameters are not passed if sAttrs == -1: sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 if nSize is None: # If this parameter is zero, the system uses the default buffer size. nSize = 0 try: (read_pipe, write_pipe) = win32pipe.CreatePipe(sAttrs, nSize) except pywintypes.error: raise return (read_pipe, write_pipe)
def run_command_win32(cmd): sa = win32security.SECURITY_ATTRIBUTES() sa.bInheritHandle = True stdout_r, stdout_w = win32pipe.CreatePipe(sa, 0) si = win32process.STARTUPINFO() si.dwFlags = (win32process.STARTF_USESTDHANDLES | win32process.STARTF_USESHOWWINDOW) si.wShowWindow = win32con.SW_HIDE si.hStdOutput = stdout_w process, thread, pid, tid = \ win32process.CreateProcess(None, cmd, None, None, True, 0, None, None, si) if process == None: return -1, "" # Must close the write handle in this process, or ReadFile will hang. stdout_w.Close() # Read the pipe until we get an error (including ERROR_BROKEN_PIPE, # which is okay because it happens when child process ends). data = "" error = 0 while 1: try: hr, buffer = win32file.ReadFile(stdout_r, 4096) if hr != winerror.ERROR_IO_PENDING: data = data + buffer except pywintypes.error as e: if e.args[0] != winerror.ERROR_BROKEN_PIPE: error = 1 break if error: return -2, "" # Everything is okay --- the called process has closed the pipe. # For safety, check that the process ended, then pick up its exit code. win32event.WaitForSingleObject(process, win32event.INFINITE) if win32process.GetExitCodeProcess(process): return -3, "" global debug if debug: sys.stdout.write(data) return 0, data
def _create_pipes(self): sa = win32security.SECURITY_ATTRIBUTES() sa.bInheritHandle = 1 self._stdin_read, self._stdin_write = win32pipe.CreatePipe(sa, 0) win32api.SetHandleInformation(self._stdin_write, win32con.HANDLE_FLAG_INHERIT, 0) if self._stdout: if os.path.isfile(self._stdout): shell.remove(self._stdout) shell.touch(self._stdout) self.stdout_reader = io.open(self._stdout, 'rb+') else: self._stdout_reader = tempfile.TemporaryFile() self._stdout_handle = create_file(self._stdout_reader.name) if self._stderr: if os.path.isfile(self._stderr): shell.remove(self._stderr) shell.touch(self._stderr) self._stderr_reader = io.open(self._stderr, 'rb+') else: self._stderr_reader = tempfile.TemporaryFile() self._stderr_handle = create_file(self._stderr_reader.name)
def _CreatePipe(self): """Return a new pipe. returns -- A tuple (under UNIX) or list (under Windows) consisting of the file descriptors (UNIX) or handles (Windows) for the read end and write end of a new pipe. The pipe is inheritable by child processes. On UNIX the fds will not be inherited across 'exec'.""" if sys.platform == "win32": # Create a security descriptor so that we can mark the handles # as inheritable. (A call to os.pipe under Windows # returns handles that are not inheritable.) sa = pywintypes.SECURITY_ATTRIBUTES() sa.bInheritHandle = 1 # Transform the tuple returned into a list so that the # individual elements can be altered. r, w = win32pipe.CreatePipe(sa, 0) return [r, w] else: pipe = os.pipe() for fd in pipe: qm.common.close_file_on_exec(fd) return pipe
def startBackgroundProcess(self): """Method to start a process running in the background. """ with process_lock: # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create pipes for the process to write to hStdin_r, hStdin = win32pipe.CreatePipe(sAttrs, 0) hStdout = win32file.CreateFile( self.stdout, win32file.GENERIC_WRITE | win32file.GENERIC_READ, win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_NORMAL, None) hStderr = win32file.CreateFile( self.stderr, win32file.GENERIC_WRITE | win32file.GENERIC_READ, win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_NORMAL, None) try: # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdInput = hStdin_r StartupInfo.hStdOutput = hStdout StartupInfo.hStdError = hStderr StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles for the thread ends of the pipes. The duplicated handles will # have their inheritence properties set to false so that any children inheriting these # handles will not have non-closeable handles to the pipes pid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(pid, hStdin, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(hStdin) hStdin = tmp # start the process, and close down the copies of the process handles # we have open after the process creation (no longer needed here) old_command = command = self.__quotePath(self.command) for arg in self.arguments: command = '%s %s' % (command, self.__quotePath(arg)) # Windows CreateProcess maximum lpCommandLine length is 32,768 # http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx if len(command) >= 32768: # pragma: no cover raise ValueError( "Command line length exceeded 32768 characters: %s..." % command[:1000]) dwCreationFlags = 0 if IS_PRE_WINDOWS_8: # pragma: no cover # In case PySys is itself running in a job, might need to explicitly breakaway from it so we can give # it its own, but only for old pre-windows 8/2012, which support nested jobs dwCreationFlags = dwCreationFlags | win32process.CREATE_BREAKAWAY_FROM_JOB if self.command.lower().endswith(('.bat', '.cmd')): # If we don't start suspended there's a slight race condition but due to some issues with # initially-suspended processes hanging (seen many years ago), to be safe, only bother to close the # race condition for shell scripts (which is the main use case for this anyway) dwCreationFlags = dwCreationFlags | win32con.CREATE_SUSPENDED self.__job = self._createParentJob() try: self.__hProcess, self.__hThread, self.pid, self.__tid = win32process.CreateProcess( None, command, None, None, 1, dwCreationFlags, self.environs, os.path.normpath(self.workingDir), StartupInfo) except pywintypes.error as e: raise ProcessError("Error creating process %s: %s" % (old_command, e)) try: if not self.disableKillingChildProcesses: win32job.AssignProcessToJobObject( self.__job, self.__hProcess) else: self.__job = None # pragma: no cover except Exception as e: # pragma: no cover # Shouldn't fail unless process already terminated (which can happen since # if we didn't use SUSPENDED there's an inherent race here) if win32process.GetExitCodeProcess( self.__hProcess) == win32con.STILL_ACTIVE: log.warning( 'Failed to associate process %s with new job: %s (this may prevent automatic cleanup of child processes)' % (self, e)) # force use of TerminateProcess not TerminateJobObject if this failed self.__job = None if (dwCreationFlags & win32con.CREATE_SUSPENDED) != 0: win32process.ResumeThread(self.__hThread) finally: win32file.CloseHandle(hStdin_r) win32file.CloseHandle(hStdout) win32file.CloseHandle(hStderr) # set the handle to the stdin of the process self.__stdin = hStdin
def __init__(self, reactor, protocol, command, args, environment, path): _pollingfile._PollingTimer.__init__(self, reactor) self.protocol = protocol # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create the pipes which will connect to the secondary process self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0) self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0) hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0) win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT, None, None) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdOutput = hStdoutW StartupInfo.hStdError = hStderrW StartupInfo.hStdInput = hStdinR StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles whose inheritance property is false pid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(pid, self.hStdoutR, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdoutR) self.hStdoutR = tmp tmp = win32api.DuplicateHandle(pid, self.hStderrR, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStderrR) self.hStderrR = tmp tmp = win32api.DuplicateHandle(pid, self.hStdinW, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdinW) self.hStdinW = tmp # Add the specified environment to the current environment - this is # necessary because certain operations are only supported on Windows # if certain environment variables are present. env = os.environ.copy() env.update(environment or {}) # create the process cmdline = ' '.join([cmdLineQuote(a) for a in args]) # TODO: error detection here. self.hProcess, hThread, dwPid, dwTid = win32process.CreateProcess( command, cmdline, None, None, 1, 0, env, path, StartupInfo) win32file.CloseHandle(hThread) # close handles which only the child will use win32file.CloseHandle(hStderrW) win32file.CloseHandle(hStdoutW) win32file.CloseHandle(hStdinR) self.closed = 0 self.closedNotifies = 0 # set up everything self.stdout = _pollingfile._PollableReadPipe( self.hStdoutR, lambda data: self.protocol.childDataReceived(1, data), self.outConnectionLost) self.stderr = _pollingfile._PollableReadPipe( self.hStderrR, lambda data: self.protocol.childDataReceived(2, data), self.errConnectionLost) self.stdin = _pollingfile._PollableWritePipe(self.hStdinW, self.inConnectionLost) for pipewatcher in self.stdout, self.stderr, self.stdin: self._addPollableResource(pipewatcher) # notify protocol self.protocol.makeConnection(self)
def main(self, token): connection = Connection('localhost', port=5672) connection.open() session = connection.session(str(uuid4())) receiver = session.receiver('amq.topic') local_ip = socket.gethostbyname(socket.gethostname()) localhost_name = platform.uname()[1] def make_inheritable(token): """Return a duplicate of handle, which is inheritable""" return win32api.DuplicateHandle(win32api.GetCurrentProcess(), token, win32api.GetCurrentProcess(), 0, 1, win32con.DUPLICATE_SAME_ACCESS) while True: message = receiver.fetch() session.acknowledge() sender = session.sender(message.reply_to) command = base64.b64decode(message.content) if command.startswith('winrs' or 'winrm') != True or command.find( '-r:' ) == -1 or command.find('localhost') != -1 or command.find( localhost_name) != -1 or command.find(local_ip) != -1: sender.send( Message( base64.b64encode( 'Commands against the proxy are not accepted'))) else: #Start the process: # First let's create the communication pipes used by the process # we need to have the pipes inherit the rights from token stdin_read, stdin_write = win32pipe.CreatePipe(None, 0) stdin_read = make_inheritable(stdin_read) stdout_read, stdout_write = win32pipe.CreatePipe(None, 0) stdout_write = make_inheritable(stdout_write) stderr_read, stderr_write = win32pipe.CreatePipe(None, 0) stderr_write = make_inheritable(stderr_write) # Set start-up parameters the process will use. #Here we specify the pipes for input, output and error. si = win32process.STARTUPINFO() si.dwFlags = win32con.STARTF_USESTDHANDLES si.hStdInput = stdin_read si.hStdOutput = stdout_write si.hStdError = stderr_write procArgs = ( None, # appName command, # commandLine None, # processAttributes None, # threadAttributes 1, # bInheritHandles 0, # dwCreationFlags None, # newEnvironment None, # currentDirectory si) # startupinfo # CreateProcessAsUser takes the first parameter the token, # this way the process will impersonate a user try: hProcess, hThread, PId, TId = win32process.CreateProcessAsUser( token, *procArgs) hThread.Close() if stdin_read is not None: stdin_read.Close() if stdout_write is not None: stdout_write.Close() if stderr_write is not None: stderr_write.Close() stdin_write = msvcrt.open_osfhandle( stdin_write.Detach(), 0) stdout_read = msvcrt.open_osfhandle( stdout_read.Detach(), 0) stderr_read = msvcrt.open_osfhandle( stderr_read.Detach(), 0) stdin_file = os.fdopen(stdin_write, 'wb', 0) stdout_file = os.fdopen(stdout_read, 'rU', 0) stderr_file = os.fdopen(stderr_read, 'rU', 0) def readerthread(fh, buffer): buffer.append(fh.read()) def translate_newlines(data): data = data.replace("\r\n", "\n") data = data.replace("\r", "\n") return data def wait(): """Wait for child process to terminate. Returns returncode attribute.""" win32event.WaitForSingleObject(hProcess, win32event.INFINITE) returncode = win32process.GetExitCodeProcess(hProcess) return returncode def communicate(): if stdout_file: stdout = [] stdout_thread = threading.Thread( target=readerthread, args=(stdout_file, stdout)) stdout_thread.setDaemon(True) stdout_thread.start() if stderr_file: stderr = [] stderr_thread = threading.Thread( target=readerthread, args=(stderr_file, stderr)) stderr_thread.setDaemon(True) stderr_thread.start() stdin_file.close() if stdout_file: stdout_thread.join() if stderr_file: stderr_thread.join() if stdout is not None: stdout = stdout[0] if stderr is not None: stderr = stderr[0] if stdout: stdout = translate_newlines(stdout) if stderr: stderr = translate_newlines(stderr) return_code = wait() return (stdout, stderr, return_code) ret_stdout, ret_stderr, retcode = communicate() result = Message(base64.b64encode(str(ret_stdout))) result.properties["retcode"] = base64.b64encode( str(retcode)) if ret_stderr: result.properties["stderr"] = base64.b64encode( str(ret_stderr)) else: result.properties["stderr"] = base64.b64encode('') sender.send(result) except Exception as exception_message: result = Message(base64.b64encode('')) result.properties["retcode"] = base64.b64encode( str(exception_message[0])) result.properties["stderr"] = base64.b64encode( str(exception_message[2])) sender.send(result)
def __init__(self, reactor, protocol, command, args, environment, path): """ Create a new child process. """ _pollingfile._PollingTimer.__init__(self, reactor) BaseProcess.__init__(self, protocol) # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create the pipes which will connect to the secondary process self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0) self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0) hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0) win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT, None, None) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdOutput = hStdoutW StartupInfo.hStdError = hStderrW StartupInfo.hStdInput = hStdinR StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles whose inheritance property is false currentPid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdoutR) self.hStdoutR = tmp tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStderrR) self.hStderrR = tmp tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdinW) self.hStdinW = tmp # Add the specified environment to the current environment - this is # necessary because certain operations are only supported on Windows # if certain environment variables are present. env = os.environ.copy() env.update(environment or {}) env = { os.fsdecode(key): os.fsdecode(value) for key, value in env.items() } # Make sure all the arguments are Unicode. args = [os.fsdecode(x) for x in args] cmdline = quoteArguments(args) # The command, too, needs to be Unicode, if it is a value. command = os.fsdecode(command) if command else command path = os.fsdecode(path) if path else path # TODO: error detection here. See #2787 and #4184. def doCreate(): flags = win32con.CREATE_NO_WINDOW self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess( command, cmdline, None, None, 1, flags, env, path, StartupInfo) try: doCreate() except pywintypes.error as pwte: if not _invalidWin32App(pwte): # This behavior isn't _really_ documented, but let's make it # consistent with the behavior that is documented. raise OSError(pwte) else: # look for a shebang line. Insert the original 'command' # (actually a script) into the new arguments list. sheb = _findShebang(command) if sheb is None: raise OSError("%r is neither a Windows executable, " "nor a script with a shebang line" % command) else: args = list(args) args.insert(0, command) cmdline = quoteArguments(args) origcmd = command command = sheb try: # Let's try again. doCreate() except pywintypes.error as pwte2: # d'oh, failed again! if _invalidWin32App(pwte2): raise OSError("%r has an invalid shebang line: " "%r is not a valid executable" % (origcmd, sheb)) raise OSError(pwte2) # close handles which only the child will use win32file.CloseHandle(hStderrW) win32file.CloseHandle(hStdoutW) win32file.CloseHandle(hStdinR) # set up everything self.stdout = _pollingfile._PollableReadPipe( self.hStdoutR, lambda data: self.proto.childDataReceived(1, data), self.outConnectionLost, ) self.stderr = _pollingfile._PollableReadPipe( self.hStderrR, lambda data: self.proto.childDataReceived(2, data), self.errConnectionLost, ) self.stdin = _pollingfile._PollableWritePipe(self.hStdinW, self.inConnectionLost) for pipewatcher in self.stdout, self.stderr, self.stdin: self._addPollableResource(pipewatcher) # notify protocol self.proto.makeConnection(self) self._addPollableResource(_Reaper(self))
def __init__(self, reactor, protocol, command, args, environment, path): _pollingfile._PollingTimer.__init__(self, reactor) BaseProcess.__init__(self, protocol) # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create the pipes which will connect to the secondary process self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0) self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0) hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0) win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT, None, None) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdOutput = hStdoutW StartupInfo.hStdError = hStderrW StartupInfo.hStdInput = hStdinR StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles whose inheritance property is false currentPid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdoutR) self.hStdoutR = tmp tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStderrR) self.hStderrR = tmp tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdinW) self.hStdinW = tmp # Add the specified environment to the current environment - this is # necessary because certain operations are only supported on Windows # if certain environment variables are present. env = os.environ.copy() env.update(environment or {}) cmdline = quoteArguments(args) # TODO: error detection here. def doCreate(): self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess( command, cmdline, None, None, 1, 0, env, path, StartupInfo) try: doCreate() except pywintypes.error, pwte: if not _invalidWin32App(pwte): # This behavior isn't _really_ documented, but let's make it # consistent with the behavior that is documented. raise OSError(pwte) else: # look for a shebang line. Insert the original 'command' # (actually a script) into the new arguments list. sheb = _findShebang(command) if sheb is None: raise OSError( "%r is neither a Windows executable, " "nor a script with a shebang line" % command) else: args = list(args) args.insert(0, command) cmdline = quoteArguments(args) origcmd = command command = sheb try: # Let's try again. doCreate() except pywintypes.error, pwte2: # d'oh, failed again! if _invalidWin32App(pwte2): raise OSError( "%r has an invalid shebang line: " "%r is not a valid executable" % ( origcmd, sheb)) raise OSError(pwte2)
def CreatePipe(): pp= win32pipe.CreatePipe(_sa,0) win32file.WriteFile(pp[1],"@") return pp
def newPipe(self): sa = win32security.SECURITY_ATTRIBUTES() sa.bInheritHandle = True return win32pipe.CreatePipe(sa, 0)
def runas(cmdLine, username, password=None, cwd=None): """ Run a command as another user. If the process is running as an admin or system account this method does not require a password. Other non privileged accounts need to provide a password for the user to runas. Commands are run in with the highest level privileges possible for the account provided. """ # Validate the domain and sid exist for the username username, domain = split_username(username) try: _, domain, _ = win32security.LookupAccountName(domain, username) except pywintypes.error as exc: message = win32api.FormatMessage(exc.winerror).rstrip("\n") raise CommandExecutionError(message) # Elevate the token from the current process access = win32security.TOKEN_QUERY | win32security.TOKEN_ADJUST_PRIVILEGES th = win32security.OpenProcessToken(win32api.GetCurrentProcess(), access) salt.platform.win.elevate_token(th) # Try to impersonate the SYSTEM user. This process needs to be running as a # user who as been granted the SeImpersonatePrivilege, Administrator # accounts have this permission by default. try: impersonation_token = salt.platform.win.impersonate_sid( salt.platform.win.SYSTEM_SID, session_id=0, privs=["SeTcbPrivilege"], ) except OSError: # pylint: disable=undefined-variable log.debug("Unable to impersonate SYSTEM user") impersonation_token = None win32api.CloseHandle(th) # Impersonation of the SYSTEM user failed. Fallback to an un-privileged # runas. if not impersonation_token: log.debug("No impersonation token, using unprivileged runas") return runas_unpriv(cmdLine, username, password, cwd) if domain == "NT AUTHORITY": # Logon as a system level account, SYSTEM, LOCAL SERVICE, or NETWORK # SERVICE. user_token = win32security.LogonUser( username, domain, "", win32con.LOGON32_LOGON_SERVICE, win32con.LOGON32_PROVIDER_DEFAULT, ) elif password: # Login with a password. user_token = win32security.LogonUser( username, domain, password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT, ) else: # Login without a password. This always returns an elevated token. user_token = salt.platform.win.logon_msv1_s4u(username).Token # Get a linked user token to elevate if needed elevation_type = win32security.GetTokenInformation( user_token, win32security.TokenElevationType) if elevation_type > 1: user_token = win32security.GetTokenInformation( user_token, win32security.TokenLinkedToken) # Elevate the user token salt.platform.win.elevate_token(user_token) # Make sure the user's token has access to a windows station and desktop salt.platform.win.grant_winsta_and_desktop(user_token) # Create pipes for standard in, out and error streams security_attributes = win32security.SECURITY_ATTRIBUTES() security_attributes.bInheritHandle = 1 stdin_read, stdin_write = win32pipe.CreatePipe(security_attributes, 0) stdin_read = salt.platform.win.make_inheritable(stdin_read) stdout_read, stdout_write = win32pipe.CreatePipe(security_attributes, 0) stdout_write = salt.platform.win.make_inheritable(stdout_write) stderr_read, stderr_write = win32pipe.CreatePipe(security_attributes, 0) stderr_write = salt.platform.win.make_inheritable(stderr_write) # Run the process without showing a window. creationflags = (win32process.CREATE_NO_WINDOW | win32process.CREATE_NEW_CONSOLE | win32process.CREATE_SUSPENDED) startup_info = salt.platform.win.STARTUPINFO( dwFlags=win32con.STARTF_USESTDHANDLES, hStdInput=stdin_read.handle, hStdOutput=stdout_write.handle, hStdError=stderr_write.handle, ) # Create the environment for the user env = create_env(user_token, False) hProcess = None try: # Start the process in a suspended state. process_info = salt.platform.win.CreateProcessWithTokenW( int(user_token), logonflags=1, applicationname=None, commandline=cmdLine, currentdirectory=cwd, creationflags=creationflags, startupinfo=startup_info, environment=env, ) hProcess = process_info.hProcess hThread = process_info.hThread dwProcessId = process_info.dwProcessId dwThreadId = process_info.dwThreadId # We don't use these so let's close the handle salt.platform.win.kernel32.CloseHandle(stdin_write.handle) salt.platform.win.kernel32.CloseHandle(stdout_write.handle) salt.platform.win.kernel32.CloseHandle(stderr_write.handle) ret = {"pid": dwProcessId} # Resume the process psutil.Process(dwProcessId).resume() # Wait for the process to exit and get its return code. if (win32event.WaitForSingleObject( hProcess, win32event.INFINITE) == win32con.WAIT_OBJECT_0): exitcode = win32process.GetExitCodeProcess(hProcess) ret["retcode"] = exitcode # Read standard out fd_out = msvcrt.open_osfhandle(stdout_read.handle, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_out, "r") as f_out: stdout = f_out.read() ret["stdout"] = stdout # Read standard error fd_err = msvcrt.open_osfhandle(stderr_read.handle, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_err, "r") as f_err: stderr = f_err.read() ret["stderr"] = stderr finally: if hProcess is not None: salt.platform.win.kernel32.CloseHandle(hProcess) win32api.CloseHandle(th) win32api.CloseHandle(user_token) if impersonation_token: win32security.RevertToSelf() win32api.CloseHandle(impersonation_token) return ret
def __init__(self, cmd, mode='t', cwd=None, env=None, avatar=None): log.info("Process.__init__(cmd=%r, mode=%r, cwd=%r, env=%r)", cmd, mode, cwd, env) # Keep a reference to ensure it is around for this object's destruction. self.__log = log self.mCmd = cmd self.mCwd = cwd self.mEnv = env self.mAvatar = avatar self.mMode = mode if self.mMode not in ('t', 'b'): raise ProcessError("'mode' must be 't' or 'b'.") self.mClosed = False si = win32process.STARTUPINFO() si.dwFlags = (win32con.STARTF_USESTDHANDLES ^ win32con.STARTF_USESHOWWINDOW) # Create pipes for std handles. # (Set the bInheritHandle flag so pipe handles are inherited.) saAttr = pywintypes.SECURITY_ATTRIBUTES() saAttr.bInheritHandle = 1 #XXX Should maybe try with os.pipe. Dunno what that does for # inheritability though. hChildStdinRd, hChildStdinWr = win32pipe.CreatePipe(saAttr, 0) hChildStdoutRd, hChildStdoutWr = win32pipe.CreatePipe(saAttr, 0) hChildStderrRd, hChildStderrWr = win32pipe.CreatePipe(saAttr, 0) try: # Duplicate the parent ends of the pipes so they are not # inherited. hChildStdinWrDup = win32api.DuplicateHandle( win32api.GetCurrentProcess(), hChildStdinWr, win32api.GetCurrentProcess(), 0, 0, # not inherited DUPLICATE_SAME_ACCESS) win32api.CloseHandle(hChildStdinWr) self._hChildStdinWr = hChildStdinWrDup hChildStdoutRdDup = win32api.DuplicateHandle( win32api.GetCurrentProcess(), hChildStdoutRd, win32api.GetCurrentProcess(), 0, 0, # not inherited DUPLICATE_SAME_ACCESS) win32api.CloseHandle(hChildStdoutRd) self._hChildStdoutRd = hChildStdoutRdDup hChildStderrRdDup = win32api.DuplicateHandle( win32api.GetCurrentProcess(), hChildStderrRd, win32api.GetCurrentProcess(), 0, 0, # not inherited DUPLICATE_SAME_ACCESS) win32api.CloseHandle(hChildStderrRd) self._hChildStderrRd = hChildStderrRdDup # Set the translation mode and buffering. self._mode = 't' if self._mode == 't': flags = os.O_TEXT else: flags = 0 fdChildStdinWr = msvcrt.open_osfhandle(self._hChildStdinWr, flags) fdChildStdoutRd = msvcrt.open_osfhandle(self._hChildStdoutRd, flags) fdChildStderrRd = msvcrt.open_osfhandle(self._hChildStderrRd, flags) self.stdin = _FileWrapper(descriptor=fdChildStdinWr, handle=self._hChildStdinWr) logres.info("[%s] Process._start(): create child stdin: %r", id(self), self.stdin) self.stdout = _FileWrapper(descriptor=fdChildStdoutRd, handle=self._hChildStdoutRd) logres.info("[%s] Process._start(): create child stdout: %r", id(self), self.stdout) self.stderr = _FileWrapper(descriptor=fdChildStderrRd, handle=self._hChildStderrRd) logres.info("[%s] Process._start(): create child stderr: %r", id(self), self.stderr) si.hStdInput = hChildStdinRd si.hStdOutput = hChildStdoutWr si.hStdError = hChildStderrWr #si.wShowWindow = show si.wShowWindow = 1 si.dwFlags |= win32process.STARTF_USESTDHANDLES creation_flags = win32process.CREATE_NEW_CONSOLE (self.mProcess, self.mThread, self.mProcessId, self.mThreadId)\ = _safeCreateProcess( self.mAvatar, # Avatar None, # App name cmd, # Command None, # Process security attribs None, # Primary thread security attribs 1, # Handles are inherited creation_flags, # Creation Flags self.mEnv, # Environment self.mCwd, # Current Working Directory si) # STARTUPINFO finally: # Close child ends of pipes on the parent's side (the # parent's ends of the pipe are closed in the _FileWrappers.) win32file.CloseHandle(hChildStdinRd) win32file.CloseHandle(hChildStdoutWr) win32file.CloseHandle(hChildStderrWr)
def run(self, cmdline): # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create pipes hStdin_r, self.hStdin_w = win32pipe.CreatePipe(sAttrs, 0) self.hStdout_r, hStdout_w = win32pipe.CreatePipe(sAttrs, 0) self.hStderr_r, hStderr_w = win32pipe.CreatePipe(sAttrs, 0) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdInput = hStdin_r StartupInfo.hStdOutput = hStdout_w StartupInfo.hStdError = hStderr_w StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Mark doesn't support wShowWindow yet. # StartupInfo.dwFlags = StartupInfo.dwFlags | win32process.STARTF_USESHOWWINDOW # StartupInfo.wShowWindow = win32con.SW_HIDE # Create new output read handles and the input write handle. Set # the inheritance properties to FALSE. Otherwise, the child inherits # the these handles; resulting in non-closeable handles to the pipes # being created. pid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle( pid, self.hStdin_w, pid, 0, 0, # non-inheritable!! win32con.DUPLICATE_SAME_ACCESS) # Close the inhertible version of the handle win32file.CloseHandle(self.hStdin_w) self.hStdin_w = tmp tmp = win32api.DuplicateHandle( pid, self.hStdout_r, pid, 0, 0, # non-inheritable! win32con.DUPLICATE_SAME_ACCESS) # Close the inhertible version of the handle win32file.CloseHandle(self.hStdout_r) self.hStdout_r = tmp # start the process. hProcess, hThread, dwPid, dwTid = win32process.CreateProcess( None, # program cmdline, # command line None, # process security attributes None, # thread attributes 1, # inherit handles, or USESTDHANDLES won't work. # creation flags. Don't access the console. 0, # Don't need anything here. # If you're in a GUI app, you should use # CREATE_NEW_CONSOLE here, or any subprocesses # might fall victim to the problem described in: # KB article: Q156755, cmd.exe requires # an NT console in order to perform redirection.. None, # no new environment None, # current directory (stay where we are) StartupInfo) # normally, we would save the pid etc. here... # Child is launched. Close the parents copy of those pipe handles # that only the child should have open. # You need to make sure that no handles to the write end of the # output pipe are maintained in this process or else the pipe will # not close when the child process exits and the ReadFile will hang. win32file.CloseHandle(hStderr_w) win32file.CloseHandle(hStdout_w) win32file.CloseHandle(hStdin_r) self.stdin = os.fdopen(msvcrt.open_osfhandle(self.hStdin_w, 0), "wb") self.stdin.write('hmmmmm\r\n') self.stdin.flush() self.stdin.close() self.stdout = os.fdopen(msvcrt.open_osfhandle(self.hStdout_r, 0), "rb") print("Read on stdout: ", repr(self.stdout.read())) self.stderr = os.fdopen(msvcrt.open_osfhandle(self.hStderr_r, 0), "rb") print("Read on stderr: ", repr(self.stderr.read()))
def runas_system(cmd, username, password): # This only works as system, when salt is running as a service for example # Check for a domain domain = '.' if '@' in username: username, domain = username.split('@') if '\\' in username: domain, username = username.split('\\') # Load User and Get Token token = win32security.LogonUser(username, domain, password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) # Load the User Profile handle_reg = win32profile.LoadUserProfile(token, {'UserName': username}) try: # Get Unrestricted Token (UAC) if this is an Admin Account elevated_token = win32security.GetTokenInformation( token, win32security.TokenLinkedToken) # Get list of privileges this token contains privileges = win32security.GetTokenInformation( elevated_token, win32security.TokenPrivileges) # Create a set of all privileges to be enabled enable_privs = set() for luid, flags in privileges: enable_privs.add((luid, win32con.SE_PRIVILEGE_ENABLED)) # Enable the privileges win32security.AdjustTokenPrivileges(elevated_token, 0, enable_privs) except win32security.error as exc: # User doesn't have admin, use existing token if exc[0] == winerror.ERROR_NO_SUCH_LOGON_SESSION \ or exc[0] == winerror.ERROR_PRIVILEGE_NOT_HELD: elevated_token = token else: raise # Get Security Attributes security_attributes = win32security.SECURITY_ATTRIBUTES() security_attributes.bInheritHandle = 1 # Create a pipe to set as stdout in the child. The write handle needs to be # inheritable. stdin_read, stdin_write = win32pipe.CreatePipe(security_attributes, 0) stdin_read = make_inheritable(stdin_read) stdout_read, stdout_write = win32pipe.CreatePipe(security_attributes, 0) stdout_write = make_inheritable(stdout_write) stderr_read, stderr_write = win32pipe.CreatePipe(security_attributes, 0) stderr_write = make_inheritable(stderr_write) # Get startup info structure startup_info = win32process.STARTUPINFO() startup_info.dwFlags = win32con.STARTF_USESTDHANDLES startup_info.hStdInput = stdin_read startup_info.hStdOutput = stdout_write startup_info.hStdError = stderr_write # Get User Environment user_environment = win32profile.CreateEnvironmentBlock(token, False) # Build command cmd = 'cmd /c {0}'.format(cmd) # Run command and return process info structure procArgs = (None, cmd, security_attributes, security_attributes, 1, 0, user_environment, None, startup_info) hProcess, hThread, PId, TId = \ win32process.CreateProcessAsUser(elevated_token, *procArgs) if stdin_read is not None: stdin_read.Close() if stdout_write is not None: stdout_write.Close() if stderr_write is not None: stderr_write.Close() hThread.Close() # Initialize ret and set first element ret = {'pid': PId} # Get Standard Out fd_out = msvcrt.open_osfhandle(stdout_read, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_out, 'r') as f_out: ret['stdout'] = f_out.read() # Get Standard Error fd_err = msvcrt.open_osfhandle(stderr_read, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_err, 'r') as f_err: ret['stderr'] = f_err.read() # Get Return Code if win32event.WaitForSingleObject( hProcess, win32event.INFINITE) == win32con.WAIT_OBJECT_0: exitcode = win32process.GetExitCodeProcess(hProcess) ret['retcode'] = exitcode # Close handle to process win32api.CloseHandle(hProcess) # Unload the User Profile win32profile.UnloadUserProfile(token, handle_reg) return ret
def runas_system(cmd, username, password): # This only works as system, when salt is running as a service for example # Check for a domain domain = '.' if '@' in username: username, domain = username.split('@') if '\\' in username: domain, username = username.split('\\') # Get User Token token = win32security.LogonUser(username, domain, password, win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) # Get Security Attributes security_attributes = win32security.SECURITY_ATTRIBUTES() security_attributes.bInheritHandle = 1 # Create a pipe to set as stdout in the child. The write handle needs to be # inheritable. stdin_read, stdin_write = win32pipe.CreatePipe(security_attributes, 0) stdin_read = make_inheritable(stdin_read) stdout_read, stdout_write = win32pipe.CreatePipe(security_attributes, 0) stdout_write = make_inheritable(stdout_write) stderr_read, stderr_write = win32pipe.CreatePipe(security_attributes, 0) stderr_write = make_inheritable(stderr_write) # Get startup info structure startup_info = win32process.STARTUPINFO() startup_info.dwFlags = win32con.STARTF_USESTDHANDLES startup_info.hStdInput = stdin_read startup_info.hStdOutput = stdout_write startup_info.hStdError = stderr_write # Get User Environment user_environment = win32profile.CreateEnvironmentBlock(token, False) # Build command cmd = 'cmd /c {0}'.format(cmd) # Run command and return process info structure procArgs = (None, cmd, security_attributes, security_attributes, 1, 0, user_environment, None, startup_info) hProcess, hThread, PId, TId = win32process.CreateProcessAsUser( token, *procArgs) if stdin_read is not None: stdin_read.Close() if stdout_write is not None: stdout_write.Close() if stderr_write is not None: stderr_write.Close() hThread.Close() # Initialize ret and set first element ret = {'pid': PId} # Get Standard Out fd_out = msvcrt.open_osfhandle(stdout_read, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_out, 'r') as f_out: ret['stdout'] = f_out.read() # Get Standard Error fd_err = msvcrt.open_osfhandle(stderr_read, os.O_RDONLY | os.O_TEXT) with os.fdopen(fd_err, 'r') as f_err: ret['stderr'] = f_err.read() # Get Return Code if win32event.WaitForSingleObject( hProcess, win32event.INFINITE) == win32con.WAIT_OBJECT_0: exitcode = win32process.GetExitCodeProcess(hProcess) ret['retcode'] = exitcode # Close handle to process win32api.CloseHandle(hProcess) return ret