def SvcDoRun(self): config_file = os.path.join(System.get_default_config_dir(), "slaveserver.conf") if not Config.read(ConfigReader.process(None)): return if not Config.is_valid(): return Win32Logger.initialize("OVD", Config.log_level, Config.log_file) try: ServerCheckup.check() except: Logger.exception("Server checkup") return slave = SlaveServer(Communication) if not slave.load_roles(): return if not slave.init(): Logger.error("Unable to initialize SlaveServer") slave.stop() return inited = False rc = win32event.WAIT_TIMEOUT while rc == win32event.WAIT_TIMEOUT: if not inited: ret = slave.push_production() if ret: inited = True Logger.info("SlaveServer started") else: Logger.warn( "Session Manager not connected. Sleeping for a while ..." ) if inited: slave.loop_procedure() rc = win32event.WaitForSingleObject(self.hWaitStop, 30 * 1000) if not slave.stopped: slave.stop() Logger.info("SlaveServer stopped")
def SvcDoRun(self): config_file = os.path.join(System.get_default_config_dir(), "slaveserver.conf") if not Config.read(ConfigReader.process(None)): return if not Config.is_valid(): return Win32Logger.initialize("OVD", Config.log_level, Config.log_file) try: ServerCheckup.check() except: Logger.exception("Server checkup") return slave = SlaveServer(Communication) if not slave.load_roles(): return if not slave.init(): Logger.error("Unable to initialize SlaveServer") slave.stop() return inited = False rc = win32event.WAIT_TIMEOUT while rc == win32event.WAIT_TIMEOUT: if not inited: ret = slave.push_production() if ret: inited = True Logger.info("SlaveServer started") else: Logger.warn("Session Manager not connected. Sleeping for a while ...") if inited: slave.loop_procedure() rc = win32event.WaitForSingleObject(self.hWaitStop, 30 * 1000) if not slave.stopped: slave.stop() Logger.info("SlaveServer stopped")
class Session(AbstractSession): SPOOL_USER = System.get_default_config_dir() def init(self): self.succefully_initialized = False 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) sessionDir = os.path.join(self.SPOOL_USER, self.user.name) 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): System.DeleteDirectory(self.windowsProgramsDir) os.makedirs(self.windowsProgramsDir) 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.init_user_session_dir(sessionDir) if self.profile is not None and self.profile.hasProfile(): if not self.profile.mount(): if self.parameters.has_key( "need_valid_profile" ) and self.parameters["need_valid_profile"] == "1": return False else: self.profile.copySessionStart() self.profile.installLogoffGPO() 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 get_target_file(self, application): return application["name"] + ".lnk" def clone_shortcut(self, src, dst, command, args): return LnkFile.clone(src, dst, command, " ".join(args)) def uninstall_client(self): if not self.succefully_initialized: return self.archive_shell_dump() if self.profile is not None and self.profile.hasProfile(): if not self.profile.mount(): Logger.warn( "Unable to mount profile at uninstall_client of session " + self.id) else: self.profile.copySessionStop() if not self.profile.umount(): Logger.error( "Unable to umount profile at uninstall_client of session " + self.id) try: shutil.rmtree(self.user_session_dir) except Exception: Logger.exception("Failed to remove spool directory '%s'" % self.user_session_dir) self.domain.onSessionEnd() return True def overwriteDefaultRegistry(self, directory): registryFile = os.path.join(directory, "NTUSER.DAT") hiveName = "OVD_%s_%d" % (str(self.id), random.randrange(10000, 50000)) # Load the hive win32api.RegLoadKey(win32con.HKEY_USERS, hiveName, registryFile) # Set the OVD Environnment path = r"%s\Environment" % (hiveName) try: Reg.CreateKeyR(win32con.HKEY_USERS, path) hkey = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: hkey = None if hkey is None: Logger.error("Unable to open key '%s'" % (path)) else: win32api.RegSetValueEx(hkey, "OVD_SESSION_DIR", 0, win32con.REG_SZ, self.user_session_dir) win32api.RegCloseKey(hkey) # Set the language if self.parameters.has_key("locale"): cl = Langs.getLCID(self.parameters["locale"]) wl = Langs.unixLocale2WindowsLocale(self.parameters["locale"]) path = r"%s\Control Panel\Desktop" % (hiveName) try: Reg.CreateKeyR(win32con.HKEY_USERS, path) hkey = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: hkey = None if hkey is None: Logger.error("Unable to open key '%s'" % (path)) else: win32api.RegSetValueEx(hkey, "MUILanguagePending", 0, win32con.REG_SZ, "%08X" % (cl)) win32api.RegSetValueEx(hkey, "PreferredUILanguagesPending", 0, win32con.REG_MULTI_SZ, [wl]) win32api.RegCloseKey(hkey) # Policies update path = r"%s\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" % ( hiveName) restrictions = [ "DisableFavoritesDirChange", "DisableLocalMachineRun", "DisableLocalMachineRunOnce", "DisableMachineRunOnce", "DisableMyMusicDirChange", "DisableMyPicturesDirChange", "DisablePersonalDirChange", "EnforceShellExtensionSecurity", #"ForceStartMenuLogOff", "Intellimenus", "NoChangeStartMenu", "NoClose", "NoCommonGroups", "NoControlPanel", "NoDFSTab", "NoFind", "NoFolderOptions", "NoHardwareTab", "NoInstrumentation", "NoIntellimenus", "NoInternetIcon", # remove the IE icon "NoManageMyComputerVerb", "NonEnum", "NoNetworkConnections", "NoResolveSearch", "NoSetFolders", "NoSetTaskbar", #"NoStartMenuSubFolders", # should remove the folders from startmenu but doesn't work + On 2008, start menu is empty if this key is set "NoSMBalloonTip", "NoStartMenuEjectPC", "NoStartMenuNetworkPlaces", "NoTrayContextMenu", "NoWindowsUpdate", #"NoViewContextMenu", # Mouse right clic #"StartMenuLogOff", ] try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: for item in restrictions: win32api.RegSetValueEx(key, item, 0, win32con.REG_DWORD, 1) win32api.RegCloseKey(key) # Hide local drives value = 0 drives = win32api.GetLogicalDriveStrings() drives = drives.split('\000')[:-1] for drive in drives: t = win32file.GetDriveType(drive) if t not in [ win32con.DRIVE_CDROM, win32con.DRIVE_REMOVABLE, win32con.DRIVE_FIXED ]: continue # Transform the drive letter into a bit value according to # http://technet.microsoft.com/en-us/library/cc959437.aspx value += 1 << (ord(drive.lower()[0]) - 97) path = r"%s\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" % ( hiveName) try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: win32api.RegSetValueEx(key, "NoDrives", 0, win32con.REG_DWORD, value) # win32api.RegSetValueEx(key, "NoViewOnDrive", 0, win32con.REG_DWORD, value) win32api.RegCloseKey(key) # Enable to use of lnk file from share without popup path = r"%s\Software\Microsoft\Windows\CurrentVersion\Policies\Associations" % ( hiveName) try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: win32api.RegSetValueEx(key, "ModRiskFileTypes", 0, win32con.REG_SZ, ".exe;.msi;.vbs") win32api.RegCloseKey(key) # start menu customization path = r"%s\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" % ( hiveName) restrictions = [ "Start_ShowRun", "StartMenuAdminTools", "Start_AdminToolsRoot" ] try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: for item in restrictions: win32api.RegSetValueEx(key, item, 0, win32con.REG_DWORD, 0) win32api.RegCloseKey(key) if self.profile is not None: # http://support.microsoft.com/kb/810869 # Do not show recycle bin path = r"%s\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel" % ( hiveName) restrictions = ["{645FF040-5081-101B-9F08-00AA002F954E}"] try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: for item in restrictions: win32api.RegSetValueEx(key, item, 0, win32con.REG_DWORD, 1) win32api.RegCloseKey(key) path = r"%s\Software\Microsoft\Windows\CurrentVersion\Policies\System" % ( hiveName) restrictions = [ "DisableRegistryTools", "DisableTaskMgr", "DisableLockWorkstation", "NoDispCPL", ] try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: for item in restrictions: win32api.RegSetValueEx(key, item, 0, win32con.REG_DWORD, 1) win32api.RegCloseKey(key) # Remove Windows startup sound keys = [ "WindowsLogon", "WindowsLogoff", "SystemStart", # old Windows 2003, not used anymore in 2008 ] for k in keys: path = r"%s\AppEvents\Schemes\Apps\.Default\%s\.Current" % ( hiveName, k) try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: win32api.RegSetValueEx(key, None, 0, win32con.REG_EXPAND_SZ, "") win32api.RegCloseKey(key) # Desktop customization path = r"%s\Control Panel\Desktop" % (hiveName) items = ["ScreenSaveActive", "ScreenSaverIsSecure"] try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: for item in items: win32api.RegSetValueEx(key, item, 0, win32con.REG_DWORD, 0) win32api.RegCloseKey(key) # Overwrite Active Setup: works partially try: Reg.UpdateActiveSetup(self.user.name, hiveName, r"Software\Microsoft\Active Setup") # On 64 bits architecture, Active Setup is already present in path "Software\Wow6432Node\Microsoft\Active Setup" if "PROGRAMW6432" in os.environ.keys(): Reg.UpdateActiveSetup( self.user.name, hiveName, r"Software\Wow6432Node\Microsoft\Active Setup") except Exception: Logger.exception("Unable to reset ActiveSetup") if self.profile is not None: self.profile.overrideRegistry(hiveName, self.user.name) self.domain.doCustomizeRegistry(hiveName) # Timezone override if self.parameters.has_key("timezone"): tz_name = Langs.getWinTimezone(self.parameters["timezone"]) ret = Reg.setTimezone(hiveName, tz_name) if ret is False: Logger.warn("Unable to set TimeZone (%s, %s)" % (self.parameters["timezone"], tz_name)) # Hack for Windows 2012R2 relative to StartScreen integration. path = r"%s\Software\Microsoft\Windows\CurrentVersion\Explorer\StartPage" % ( hiveName) try: Reg.CreateKeyR(win32con.HKEY_USERS, path) key = win32api.RegOpenKey(win32con.HKEY_USERS, path, 0, win32con.KEY_SET_VALUE) except: key = None if key is None: Logger.error("Unable to open key '%s'" % (path)) else: win32api.RegSetValueEx(key, "MakeAllAppsDefault", 0, win32con.REG_DWORD, 1) win32api.RegCloseKey(key) # Unload the hive win32api.RegUnLoadKey(win32con.HKEY_USERS, hiveName)
class Config: # generic infos = {} roles = [] stop_timeout = 600 # in second (10m) ROLES_ALIASES = {"aps": "ApplicationServer", "fs": "FileServer"} LOGS_FLAGS_ALIASES = { "error": Logger.ERROR, "warn": Logger.WARN, "info": Logger.INFO, "debug": Logger.DEBUG, "normal": Logger.INFO | Logger.WARN | Logger.ERROR, "*": Logger.INFO | Logger.WARN | Logger.ERROR | Logger.DEBUG, } log_level = Logger.INFO | Logger.WARN | Logger.ERROR | Logger.DEBUG log_file = os.path.join(System.get_default_log_dir(), "slaveserver.log") log_threaded = False conf_dir = System.get_default_config_dir() spool_dir = System.get_default_spool_dir() # OVD servers communication session_manager = None SM_SERVER_PORT = 1111 SLAVE_SERVER_PORT = 1112 server_allow_reuse_address = System.tcp_server_allow_reuse_address() @classmethod def read(cls, raw_data): cls.raw_data = raw_data if not cls.raw_data.has_key("main") or type( cls.raw_data["main"]) is not dict: report_error("Missing 'main' part") return False if cls.raw_data["main"].has_key("roles"): cls.roles = cls.parse_list(cls.raw_data["main"]["roles"]) cls.manage_role_aliases(cls.roles) if cls.raw_data["main"].has_key("session_manager"): a = cls.raw_data["main"]["session_manager"] if len(a) > 0: cls.session_manager = a.strip() if cls.raw_data["main"].has_key("stop_timeout"): a = cls.raw_data["main"]["stop_timeout"] try: a = int(a) if a > 0: cls.stop_timeout = a except ValueError: report_error( "Invalid value for configuration key 'stop_timeout', need a time in seconde" ) if cls.raw_data["main"].has_key("server_allow_reuse_address"): a = cls.raw_data["main"]["server_allow_reuse_address"].lower( ).strip() if a not in ["true", "false"]: report_error( "Invalid value for configuration key 'server_allow_reuse_address', allowed values are true/false" ) cls.server_allow_reuse_address = (a == "true") if not cls.raw_data.has_key("log") or type( cls.raw_data["log"]) is not dict: return True if cls.raw_data["log"].has_key("file"): cls.log_file = cls.raw_data["log"]["file"] if cls.raw_data["log"].has_key("level"): cls.log_level = 0 debug_count = 0 for item in cls.raw_data["log"]["level"].split(' '): item = item.lower() if item == "debug": debug_count += 1 if cls.LOGS_FLAGS_ALIASES.has_key(item): cls.log_level |= cls.LOGS_FLAGS_ALIASES[item] if debug_count > 1: cls.log_level |= Logger.DEBUG_2 if debug_count >= 3: cls.log_level |= Logger.DEBUG_3 if cls.raw_data["log"].has_key("thread"): cls.log_threaded = ( cls.raw_data["log"]["thread"].lower() == "true") return True @classmethod def is_valid(cls): if len(cls.roles) == 0: report_error("No role given") return False if cls.session_manager is None: report_error("No session manager given") return False if " " in cls.session_manager: report_error("Invalid session manager given") return False # if not is_host(cls.session_manager): # return False if cls.log_file is not None: try: f = file(cls.log_file, "a") f.close() except IOError: report_error("Unable to write into log file '%s'" % (cls.log_file)) return False return True @classmethod def manage_role_aliases(cls, l): for item in list(l): if not cls.ROLES_ALIASES.has_key(item): continue l.remove(item) v = cls.ROLES_ALIASES[item] if v not in l: l.append(v) @classmethod def parse_list(cls, data): return dict.fromkeys(data.split()).keys() @classmethod def get_role_dict(cls, role): if not cls.raw_data.has_key(role): return {} return cls.raw_data[role]