def install_client(self): logon = win32security.LogonUser( self.user.name, None, self.user.infos["password"], win32security.LOGON32_LOGON_INTERACTIVE, win32security.LOGON32_PROVIDER_DEFAULT) data = {} data["UserName"] = self.user.name hkey = win32profile.LoadUserProfile(logon, data) self.windowsProfileDir = win32profile.GetUserProfileDirectory(logon) self.windowsProgramsDir = shell.SHGetFolderPath( 0, shellcon.CSIDL_PROGRAMS, logon, 0) Logger.debug("startmenu: %s" % (self.windowsProgramsDir)) # remove default startmenu if os.path.exists(self.windowsProgramsDir): Platform.System.DeleteDirectory(self.windowsProgramsDir) os.makedirs(self.windowsProgramsDir) self.windowsDesktopDir = shell.SHGetFolderPath( 0, shellcon.CSIDL_DESKTOPDIRECTORY, logon, 0) self.appDataDir = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, logon, 0) self.localAppDataDir = shell.SHGetFolderPath( 0, shellcon.CSIDL_LOCAL_APPDATA, logon, 0) Logger.debug("localAppdata: '%s'" % (self.localAppDataDir)) Logger.debug("appdata: '%s'" % (self.appDataDir)) win32profile.UnloadUserProfile(logon, hkey) win32api.CloseHandle(logon) self.set_user_profile_directories(self.windowsProfileDir, self.appDataDir) self.init_user_session_dir( os.path.join(self.appDataDir, "ulteo", "ovd")) if self.profile is not None and self.profile.hasProfile(): if not self.profile.mount(): return False self.profile.copySessionStart() if self.profile is not None and self.profile.mountPoint is not None: d = os.path.join(self.profile.mountPoint, self.profile.DesktopDir) self.cleanupShortcut(d) self.install_desktop_shortcuts() self.overwriteDefaultRegistry(self.windowsProfileDir) if self.profile is not None and self.profile.hasProfile(): self.profile.umount() self.succefully_initialized = True return True
def post_spawn_stop(self, user, spawner): """Unload profile for user if we were configured to opened one""" token = None if not self.open_sessions: return try: loop = asyncio.new_event_loop() auth_state = loop.run_until_complete(user.get_auth_state()) token = pywintypes.HANDLE(auth_state['auth_token']) win32profile.UnloadUserProfile(token, self._hreg) except Exception as exc: self.log.warning("Failed to unload user profile for %s: %s", user.name, exc) finally: if token: # Detach so token stays valid token.Detach()
def logout(self): # Update the handles to which self.mUserSID was granted access in the # creation/login process. for h in self.mAddedHandles: windesktop.removeUserSID(h, self.mUserSID) # We are done with this now. self.mAddedHandles = [] self.mWinsta.CloseWindowStation() self.mDesktop.CloseDesktop() # Unload the user's profile. try: # Leave Flags in since 2.3 still chokes on some types of optional # keyword args. win32profile.UnloadUserProfile(self.mUserHandle, self.mUserProfile) self.mLogger.info("Unloaded profile.") except pywintypes.error, error: self.mLogger.error("Error unloading profile: %s" % error)
## Marshal saved credential and use it to log on mc = win32cred.CredMarshalCredential(win32cred.UsernameTargetCredential, target) th = win32security.LogonUser(mc, None, '', win32con.LOGON32_LOGON_INTERACTIVE, win32con.LOGON32_PROVIDER_DEFAULT) win32security.ImpersonateLoggedOnUser(th) print 'GetUserName:'******'s profile. (first check if user has a roaming profile) username, domain = win32cred.CredUIParseUserName(target) user_info_4 = win32net.NetUserGetInfo(None, username, 4) profilepath = user_info_4['profile'] ## LoadUserProfile apparently doesn't like an empty string if not profilepath: profilepath = None ## leave Flags in since 2.3 still chokes on some types of optional keyword args hk = win32profile.LoadUserProfile(th, { 'UserName': username, 'Flags': 0, 'ProfilePath': profilepath }) ## Get user's environment variables in a form that can be passed to win32process.CreateProcessAsUser env = win32profile.CreateEnvironmentBlock(th, False) ## Cleanup should probably be in a finally block win32profile.UnloadUserProfile(th, hk) th.Close()
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(cmdLine, username, password=None, cwd=None): ''' Run a command as another user. It the proccess is running as an admin or system account this method does not require a password. Other non priviledged accounts need to provide a password for the user to runas. Commands are run in with the highest level priviledges possible for the account provided. ''' # 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 runnung 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 WindowsError: # pylint: disable=undefined-variable log.debug("Unable to impersonate SYSTEM user") impersonation_token = None # Impersonation of the SYSTEM user failed. Fallback to an un-priviledged # runas. if not impersonation_token: log.debug("No impersonation token, using unprivileged runas") return runas_unpriv(cmdLine, username, password, cwd) username, domain = split_username(username) # Validate the domain and sid exist for the username sid, domain, sidType = win32security.LookupAccountName(domain, username) if domain == 'NT AUTHORITY': # Logon as a system level account, SYSTEM, LOCAL SERVICE, or NETWORK # SERVICE. logonType = win32con.LOGON32_LOGON_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 profile is loaded. handle_reg = win32profile.LoadUserProfile(user_token, {'UserName': username}) # 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 = win32profile.CreateEnvironmentBlock(user_token, False) # 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 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 it's 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 win32profile.UnloadUserProfile(user_token, handle_reg) salt.platform.win.kernel32.CloseHandle(hProcess) win32api.CloseHandle(user_token) if impersonation_token: win32security.RevertToSelf() win32api.CloseHandle(impersonation_token) return ret