def purgeGroup(self): users = System.groupMember(Config.group) if users is None: return False ret = True for user in users: if user == Config.dav_user: continue Logger.debug("FileServer:: deleting user '%s'"%(user)) u = User(user) u.clean() if u.existSomeWhere(): Logger.error("FS: unable to del user %s"%(user)) ret = False htgroup = HTGroup(Config.dav_group_file) htgroup.purge() try: groups = [g.gr_name for g in grp.getgrall() if g.gr_name.startswith("ovd_share_")] for g in groups: System.groupDelete(g) except Exception: Logger.exception("Failed to purge groups") ret = False return ret
def main(self): self.synchronizer.restore() Logger._instance.setQueue(self.logging_queue, False) System.prepareForSessionActions() # Prevent the process to be stop by a keyboard interruption signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGTERM, signal.SIG_IGN) Logger.debug("Starting SessionManager process") while True: self.current_session_id.value = "" try: (request, obj) = self.queue2.get_nowait() except Queue.Empty: try: (request, obj) = self.queue.get(True, 4) except Queue.Empty, e: continue except IOError, e: if e.errno == 4: break else: raise e
def destroy(self): lock = FileLock("/tmp/user.lock") arg_remove = "" if self.check_remaining_mount_points(): arg_remove = "--remove" cmd = "userdel --force %s %s"%(arg_remove, System.local_encode(self.name)) retry = 5 while retry !=0: lock.acquire() p = System.execute(cmd) lock.release() if p.returncode == 0: return True if p.returncode == 12: Logger.debug("mail dir error: '%s' return %d => %s"%(str(cmd), p.returncode, p.stdout.read())) return True Logger.debug("User delete of %s: retry %i"%(self.name, 6-retry)) if p.returncode == 1 or p.returncode == 10: # an other process is creating a user Logger.debug("An other process is creating a user") retry -=1 time.sleep(0.2) continue if p.returncode != 0: Logger.error("userdel return %d (%s)"%(p.returncode, p.stdout.read())) return False return True
def enable(self, mode): for i in ['ro', 'rw']: cmd = "groupadd %s_%s" % (self.group, i) p = System.execute(cmd) if p.returncode is not 0: Logger.error("FS: unable to create group") Logger.debug( "FS: command '%s' return %d: %s" % (cmd, p.returncode, p.stdout.read().decode("UTF-8"))) return False cmd = 'net usershare add %s "%s" %s %s_ro:r,%s_rw:f guest_ok=n' % ( self.name, self.frontDirectory, self.name, self.group, self.group) p = System.execute(cmd) if p.returncode is not 0: Logger.error("FS: unable to add share") Logger.debug("FS: command '%s' return %d: %s" % (cmd, p.returncode, p.stdout.read().decode("UTF-8"))) return False self.do_right_normalization() self.htaccess.addGroup(self.group) self.htaccess.save() self.active = True return True
def check_remaining_mount_points(self): try: user = pwd.getpwnam(System.local_encode(self.name)) except KeyError: return False mount_points = MountPoint.get_list(user.pw_dir) if mount_points is None: return False success = True for d in mount_points: path = System.local_encode(d) Logger.warn("Remaining mount point '%s'"%(path)) cmd = 'umount "%s"'%(path) p = System.execute(cmd) if p.returncode == 0: continue Logger.warn("Unable to unmount remaining mount point %s: force the unmount"%(path)) Logger.debug('umount command "%s" return: %s'%(cmd, p.stdout.read())) cmd = 'umount -l "%s"'%(path) p = System.execute(cmd) if p.returncode != 0: Logger.error("Unable to force the unmount remaining mount point %s"%(path)) Logger.debug('umount command "%s" return: %s'%(cmd, p.stdout.read())) success = False if success == False: Logger.error("Unable to unmount remaining mount point, home dir %s won't be purged"%(user.pw_dir)) return success
def copySessionStart(self): profile_tmp_dir = os.path.join(Profile.TEMPORARY_PROFILE_PATH, self.session.user.name) if os.path.exists(profile_tmp_dir): System.rchown(profile_tmp_dir, self.session.user.name) if self.homeDir is None or not os.path.isdir(self.homeDir): return d = os.path.join(self.profile_mount_point, "conf.Linux") if not System.mount_point_exist(d): return if self.profile['profile_mode'] == 'advanced': return # Copy conf files d = self.transformToLocaleEncoding(d) cmd = self.getRsyncMethod(d, self.homeDir, Config.profile_filters_filename, True) Logger.debug("rsync cmd '%s'" % (cmd)) p = System.execute(cmd) if p.returncode is not 0: Logger.error("Unable to copy conf from profile") Logger.debug( "Unable to copy conf from profile, cmd '%s' return %d: %s" % (cmd, p.returncode, p.stdout.read()))
def purgeGroup(self): users = System.groupMember(Config.group) if users is None: return False ret = True for user in users: if user == Config.dav_user: continue Logger.debug("FileServer:: deleting user '%s'" % (user)) u = User(user) u.clean() if u.existSomeWhere(): Logger.error("FS: unable to del user %s" % (user)) ret = False htgroup = HTGroup(Config.dav_group_file) htgroup.purge() try: groups = [ g.gr_name for g in grp.getgrall() if g.gr_name.startswith("ovd_share_") ] for g in groups: System.groupDelete(g) except Exception: Logger.exception("Failed to purge groups") ret = False return ret
def destroy(self): lock = FileLock("/tmp/user.lock") arg_remove = "" if self.check_remaining_mount_points(): arg_remove = "--remove" cmd = "userdel --force %s %s" % (arg_remove, System.local_encode(self.name)) retry = 5 while retry != 0: lock.acquire() p = System.execute(cmd) lock.release() if p.returncode == 0: return True if p.returncode == 12: Logger.debug("mail dir error: '%s' return %d => %s" % (str(cmd), p.returncode, p.stdout.read())) return True Logger.debug("User delete of %s: retry %i" % (self.name, 6 - retry)) if p.returncode == 1 or p.returncode == 10: # an other process is creating a user Logger.debug("An other process is creating a user") retry -= 1 time.sleep(0.2) continue if p.returncode != 0: Logger.error("userdel return %d (%s)" % (p.returncode, p.stdout.read())) return False return True
def copySessionStart(self): profile_tmp_dir = os.path.join(Profile.TEMPORARY_PROFILE_PATH, self.session.user.name) if os.path.exists(profile_tmp_dir): System.rchown(profile_tmp_dir, self.session.user.name) if self.homeDir is None or not os.path.isdir(self.homeDir): return d = os.path.join(self.profile_mount_point, "conf.Linux") if not System.mount_point_exist(d): return if self.profile["profile_mode"] == "advanced": return # Copy conf files d = self.transformToLocaleEncoding(d) cmd = self.getRsyncMethod(d, self.homeDir, Config.profile_filters_filename, True) Logger.debug("rsync cmd '%s'" % (cmd)) p = System.execute(cmd) if p.returncode is not 0: Logger.error("Unable to copy conf from profile") Logger.debug( "Unable to copy conf from profile, cmd '%s' return %d: %s" % (cmd, p.returncode, p.stdout.read()) )
def copyDirOverride(src, dst, exception=None): src = System.local_encode(src) dst = System.local_encode(dst) if not os.path.isdir(src): return if exception is None: exception = [] try: attr = win32file.GetFileAttributes(src) if attr & FILE_ATTRIBUTE_SYSTEM and attr & FILE_ATTRIBUTE_REPARSE_POINT: return win32file.SetFileAttributes(dst, attr) except: #print "Unable to setAttribute of",dst pass if not os.path.isdir(dst): os.makedirs(dst) dirs = None try: dirs = os.listdir(src) except Exception, err: return
def perform(self): os.mkdir(self.directory) f_stdout = open(os.path.join(self.directory, "stdout"), "w") f_stderr = open(os.path.join(self.directory, "stderr"), "w") process_out = {"stdout": f_stdout, "stderr": f_stderr} p = System.execute(["apt-get", "update"], True, {}, process_out) if p.returncode != 0: f_stdout.close() f_stderr.close() return False apt_env = {"DEBIAN_FRONTEND": "noninteractive", "DEBIAN_PRIORITY": "critical", "DEBCONF_NONINTERACTIVE_SEEN": "true"} command = ["apt-get", "--yes", "--force-yes", "--option", "DPkg::Options::=--force-confold"] if self.order == "upgrade": command.append("dist-upgrade") elif self.order == "install": command.append("install") elif self.order == "remove": command.append("autoremove") command.append("--purge") if self.order in ["install", "remove"]: command.extend(self.packages) p = System.execute(command, True, apt_env, process_out) if p.returncode != 0: f_stdout.close() f_stderr.close() return False f_stdout.close() f_stderr.close() return True
def destroy(self): ret = True cmd = 'htpasswd -D %s "%s"'%(Config.dav_passwd_file, self.login) p = System.execute(cmd) if p.returncode != 0: Logger.error("FS: unable to update apache auth file") Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) return False cmd = 'smbpasswd -x %s'%(self.login) p = System.execute(cmd) if p.returncode != 0: Logger.error("FS: unable to del smb password") Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) ret = False cmd = "userdel -f %s"%(self.login) p = System.execute(cmd) if p.returncode != 0: Logger.error("FS: unable to del user") Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) ret = False return ret
def create(self, password): cmd = "useradd -d /dev/null -s /bin/false -G %s,%s %s"%(Config.group, "sambashare", self.login) p = System.execute(cmd) if p.returncode == 9: Logger.warn("FS: unable to create user: already exists") return False elif p.returncode != 0: Logger.error("FS: unable to create user") Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) return False cmd = 'smbpasswd -s -a %s'%(self.login) p = System.execute(cmd, wait = False) p.stdin.write("%s\n%s\n"%(password, password)) p.wait() if p.returncode != 0: Logger.error("FS: unable to set samba password") Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) return False cmd = 'htpasswd -b %s "%s" "%s"'%(Config.dav_passwd_file, self.login, password) p = System.execute(cmd) if p.returncode != 0: Logger.error("FS: unable to update apache auth file") Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) return False return True
def req_server_conf(self, request): cpuInfos = System.getCPUInfos() ram_total = System.getRAMTotal() doc = Document() rootNode = doc.createElement('configuration') rootNode.setAttribute("type", System.getName()) rootNode.setAttribute("version", System.getVersion()) rootNode.setAttribute("ram", str(ram_total)) rootNode.setAttribute("ulteo_system", str(self.server.ulteo_system).lower()) cpuNode = doc.createElement('cpu') cpuNode.setAttribute('nb_cores', str(cpuInfos[0])) textNode = doc.createTextNode(cpuInfos[1]) cpuNode.appendChild(textNode) rootNode.appendChild(cpuNode) for role,dialog in self.server.role_dialogs: roleNode = doc.createElement('role') roleNode.setAttribute('name', dialog.getName()) rootNode.appendChild(roleNode) doc.appendChild(rootNode) return self.req_answer(doc)
def req_server_conf(self, request): cpuInfos = System.getCPUInfos() ram_total = System.getRAMTotal() doc = Document() rootNode = doc.createElement('configuration') rootNode.setAttribute("type", System.getName()) rootNode.setAttribute("version", System.getVersion()) rootNode.setAttribute("ram", str(ram_total)) rootNode.setAttribute("ulteo_system", str(self.server.ulteo_system).lower()) cpuNode = doc.createElement('cpu') cpuNode.setAttribute('nb_cores', str(cpuInfos[0])) textNode = doc.createTextNode(cpuInfos[1]) cpuNode.appendChild(textNode) rootNode.appendChild(cpuNode) for role, dialog in self.server.role_dialogs: roleNode = doc.createElement('role') roleNode.setAttribute('name', dialog.getName()) rootNode.appendChild(roleNode) doc.appendChild(rootNode) return self.req_answer(doc)
def install_client(self): name = System.local_encode(self.user.name) d = os.path.join(self.SPOOL_USER, self.user.name) self.init_user_session_dir(d) self.install_desktop_shortcuts() os.chown(self.instanceDirectory, pwd.getpwnam(name)[2], -1) os.chown(self.user_session_dir, pwd.getpwnam(name)[2], -1) xdg_dir = os.path.join(d, "xdg") xdg_app_d = os.path.join(xdg_dir, "applications") if not os.path.isdir(xdg_app_d): os.makedirs(xdg_app_d) for p in ["icons", "pixmaps", "mime", "themes"]: src_dir = os.path.join("/usr/share/", p) dst_dir = os.path.join(xdg_dir, p) os.symlink(src_dir, dst_dir) os.system('update-desktop-database "%s"'%(System.local_encode(xdg_app_d))) if self.parameters.has_key("desktop_icons") and self.parameters["desktop_icons"] == "1": path = os.path.join(xdg_app_d, ".show_on_desktop") f = file(path, "w") f.close() env_file_lines = [] # Set the language if self.parameters.has_key("locale"): env_file_lines.append("LANG=%s.UTF-8\n"%(self.parameters["locale"])) env_file_lines.append("LC_ALL=%s.UTF-8\n"%(self.parameters["locale"])) env_file_lines.append("LANGUAGE=%s.UTF-8\n"%(self.parameters["locale"])) if self.parameters.has_key("timezone"): tz_file = "/usr/share/zoneinfo/" + self.parameters["timezone"] if not os.path.exists(tz_file): Logger.warn("Unsupported timezone '%s'"%(self.parameters["timezone"])) Logger.debug("Unsupported timezone '%s'. File '%s' does not exists"%(self.parameters["timezone"], tz_file)) else: env_file_lines.append("TZ=%s\n"%(tz_file)) f = file(os.path.join(d, "env"), "w") f.writelines(env_file_lines) f.close() if self.profile is not None: self.profile.mount() shares_dir = os.path.join(d, "shares") if not os.path.isdir(shares_dir): os.makedirs(shares_dir) self.profile.register_shares(shares_dir) return True
def create(self): lock = FileLock("/tmp/user.lock") # TODO get the default home in /etc/default/useradd default_home_dir = os.path.join(u"/home", self.name) home_dir = default_home_dir i = 0 while os.path.exists(home_dir) and i < 100: home_dir = default_home_dir+"_%d"%(i) i+= 1 if i > 0: Logger.warn("Unable to create home directory %s, the home is now %s"%(default_home_dir, home_dir)) if os.path.exists(home_dir): Logger.error("Unable to find a valid home directory") return False cmd = u"useradd -m -d '%s' -k '%s'"%(home_dir, Config.linux_skel_directory) if self.infos.has_key("displayName"): cmd+= u""" --comment "%s,,," """%(self.infos["displayName"].replace('"', "")) groups = ["video", "audio", "pulse", "pulse-access", Config.linux_fuse_group] if self.infos.has_key("groups"): groups+= self.infos["groups"] cmd+= u" --groups %s"%(",".join(groups)) cmd+= u" "+self.name retry = 5 while retry !=0: if retry < 0: Logger.error("ERROR: unable to add a new user") lock.acquire() p = System.execute(System.local_encode(cmd)) lock.release() if p.returncode == 0: break Logger.debug("Add user :retry %i"%(6-retry)) if p.returncode == 9: # user already exist Logger.error("User %s already exist"%(self.name)) break; if p.returncode == 1: # an other process is creating a user Logger.error("An other process is creating a user") retry -=1 time.sleep(0.2) continue if p.returncode != 0: Logger.error("UserAdd return %d (%s)"%(p.returncode, p.stdout.read())) return False if self.infos.has_key("password"): if not self.set_password(): return False return self.post_create()
def do_right_normalization(self): cmd = 'chown -R %s:%s "%s"'%(Config.uid, Config.gid, self.directory) p = System.execute(cmd) if p.returncode is not 0: Logger.debug("FS: following command '%s' returned %d => %s"%(cmd, p.returncode, p.stdout.read())) cmd = 'chmod -R u=rwX,g=rwX,o-rwx "%s"'%(self.directory) p = System.execute(cmd) if p.returncode is not 0: Logger.debug("FS: following command '%s' returned %d => %s"%(cmd, p.returncode, p.stdout.read()))
def copySessionStop(self): # etre sur que le type est logoff ! d = shell.SHGetFolderPath(0, shellcon.CSIDL_COMMON_APPDATA, 0, 0) profile_tmp_dir = os.path.join(d, "ulteo", "profile", self.session.user.name) profile_tmp_dir = System.local_encode(profile_tmp_dir) profile_filter = System.local_encode(Config.profile_filters_filename) d = os.path.join(self.mountPoint, "conf.Windows.%s" % System.getWindowsVersionName()) trial = 5 while not os.path.exists(d): try: os.makedirs(d) except OSError: trial -= 1 if trial == 0: Logger.exception("Failed to create directory %s" % d) return False time.sleep(random.randint(1, 10) / 100.0) Logger.debug2( "conf.Windows mkdir failed (concurrent access because of more than one ApS)" ) continue # Copy user registry src = os.path.join(self.session.windowsProfileDir, "NTUSER.DAT") dst = os.path.join(d, "NTUSER.DAT") if os.path.exists(src): try: win32file.CopyFile(src, dst, False) except: Logger.error("Unable to copy registry to profile") else: Logger.warn("Weird: no NTUSER.DAT in user home dir ...") # Copy configuration File if self.profile['profile_mode'] == 'standard': cmd = self.getRsyncMethod(Profile.toCygPath(profile_tmp_dir), Profile.toCygPath(d), Profile.toCygPath(profile_filter)) Logger.debug("rsync cmd '%s'" % (cmd)) p = System.execute(cmd) if p.returncode is not 0: Logger.error("Unable to copy conf to profile") Logger.debug( "Unable to copy conf to profile, cmd '%s' return %d: %s" % (cmd, p.returncode, p.stdout.read())) if os.path.exists(profile_tmp_dir): System.DeleteDirectory(profile_tmp_dir)
def do_right_normalization(self): cmd = 'chown -R %s:%s "%s"' % (Config.uid, Config.gid, self.directory) p = System.execute(cmd) if p.returncode is not 0: Logger.debug("FS: following command '%s' returned %d => %s" % (cmd, p.returncode, p.stdout.read())) cmd = 'chmod -R u=rwX,g=rwX,o-rwx "%s"' % (self.directory) p = System.execute(cmd) if p.returncode is not 0: Logger.debug("FS: following command '%s' returned %d => %s" % (cmd, p.returncode, p.stdout.read()))
def init(self): Logger.debug("ApplicationServer init") try: TS.getList() except Exception: Logger.exception("RDP server dialog failed ... exiting") return if not System.groupExist(self.manager.ts_group_name): Logger.error("The group '%s' doesn't exist" % (self.manager.ts_group_name)) return False if not System.groupExist(self.manager.ovd_group_name): if not System.groupCreate(self.manager.ovd_group_name): return False if not self.manager.purgeGroup(): Logger.error("Unable to purge group") return False if Config.clean_dump_archive: self.purgeArchives() if Config.thread_count is None: cpuInfos = System.getCPUInfos() vcpu = cpuInfos[0] ram_total = System.getRAMTotal() ram = int(round(ram_total / 1024.0 / 1024.0)) nb_thread = int(round(1 + (ram + vcpu * 2) / 3)) else: nb_thread = Config.thread_count Logger._instance.setQueue(self.logging_queue, True) for _ in xrange(nb_thread): self.threads.append( SessionManagement(self.manager, self.sessions_spooler, self.sessions_spooler2, self.sessions_sync, self.logging_queue)) if self.canManageApplications(): self.apt = Apt() self.apt.init() self.threads.append(self.apt) Logger.info( "ApplicationServer:: retrieve all applications installed (can take some time)" ) self.updateApplications() return True
def tuneGroups(self, username, groups): if groups is None or len(groups) == 0: return False groupString = ','.join(groups) cmd = u"usermod -G %s %s"%(groupString, username) p = System.execute(System.local_encode(cmd)) if p.returncode != 0: Logger.error("UserAdd return %d (%s)"%(p.returncode, p.stdout.read())) return False return True
def tuneGroups(self, username, groups): if groups is None or len(groups) == 0: return False groupString = ','.join(groups) cmd = u"usermod -G %s %s" % (groupString, username) p = System.execute(System.local_encode(cmd)) if p.returncode != 0: Logger.error("UserAdd return %d (%s)" % (p.returncode, p.stdout.read())) return False return True
def cleanup_repository(self): cmd = 'chown -R %s:%s "%s"'%(Config.uid, Config.gid, Config.backendSpool) p = System.execute(cmd) if p.returncode is not 0: Logger.debug("FS: following command '%s' returned %d => %s"%(cmd, p.returncode, p.stdout.read())) return False cmd = 'chmod -R u=rwX,g=rwX,o-rwx "%s"'%(Config.backendSpool) p = System.execute(cmd) if p.returncode is not 0: Logger.debug("FS: following command '%s' returned %d => %s"%(cmd, p.returncode, p.stdout.read())) return False return True
def copySessionStop(self): # etre sur que le type est logoff ! d = shell.SHGetFolderPath(0, shellcon.CSIDL_COMMON_APPDATA, 0, 0) profile_tmp_dir = os.path.join(d, "ulteo", "profile", self.session.user.name) profile_tmp_dir = System.local_encode(profile_tmp_dir) profile_filter = System.local_encode(Config.profile_filters_filename) d = os.path.join(self.mountPoint, "conf.Windows.%s"%System.getWindowsVersionName()) trial = 5 while not os.path.exists(d): try: os.makedirs(d) except OSError: trial -= 1 if trial == 0: Logger.exception("Failed to create directory %s"%d) return False time.sleep(random.randint(1,10)/100.0) Logger.debug2("conf.Windows mkdir failed (concurrent access because of more than one ApS)") continue # Copy user registry src = os.path.join(self.session.windowsProfileDir, "NTUSER.DAT") dst = os.path.join(d, "NTUSER.DAT") if os.path.exists(src): try: win32file.CopyFile(src, dst, False) except: Logger.error("Unable to copy registry to profile") else: Logger.warn("Weird: no NTUSER.DAT in user home dir ...") # Copy configuration File if self.profile['profile_mode'] == 'standard': cmd = self.getRsyncMethod(Profile.toCygPath(profile_tmp_dir), Profile.toCygPath(d), Profile.toCygPath(profile_filter)) Logger.debug("rsync cmd '%s'"%(cmd)) p = System.execute(cmd) if p.returncode is not 0: Logger.error("Unable to copy conf to profile") Logger.debug("Unable to copy conf to profile, cmd '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read())) if os.path.exists(profile_tmp_dir): System.DeleteDirectory(profile_tmp_dir)
def getIcon(self, filename): Logger.debug("ApplicationsDetection::getIcon %s"%(filename)) try: entry = xdg.DesktopEntry.DesktopEntry(filename) except xdg.Exceptions.Error as detail: Logger.warn("ApplicationsDetection::getIcon %s" % detail) return None iconName = entry.getIcon() if entry.getIcon() == u'': # icon field is not required for type=Application return None iconPath = xdg.IconTheme.getIconPath(iconName, size = 32, theme=Config.linux_icon_theme, extensions = ["png", "xpm"]) if iconPath == None: return None bufFile = tempfile.mktemp(".png") cmd = 'convert -resize 32x32 "%s" "%s"'%(iconPath, bufFile) p = System.execute(cmd) if p.returncode != 0: Logger.debug("getIcon cmd '%s' returned (%d): %s"%(cmd, p.returncode, p.stdout.read())) Logger.error("getIcon: imagemagick error") if os.path.exists(bufFile): os.remove(bufFile) return None try: f = file(bufFile, "r") except IOError, err: Logger.error("ApplicationsDetection::getIcon finale icon file '%s' does not exists"%(bufFile)) return None
def purgeGroup(self): while True: users = System.groupMember(self.ovd_group_name) if users is None: return False if users == []: return True for user in users: # todo : check if the users is connected, if yes logoff his session if not System.userRemove(user): return False return False
def exists(self): try: pwd.getpwnam(System.local_encode(self.name)) except KeyError: return False return True
def existSomeWhere(self): try: pwd.getpwnam(self.login) return True except: pass cmd = "smbpasswd -e %s"%(self.login) p = System.execute(cmd) if p.returncode == 0: return True accessOK = False try: f = file(Config.dav_passwd_file, "r") accessOK = True except: pass if accessOK: lines = f.readlines() f.close for line in lines: if line.startswith(self.login+":"): return True return False
def del_user(self, user): if user not in self.ro_users and user not in self.rw_users: return True ret = True if user in self.ro_users: cmd = "deluser %s %s_ro"%(user, self.group) else: cmd = "deluser %s %s_rw"%(user, self.group) p = System.execute(cmd) if p.returncode is not 0: ret = False Logger.error("FS: unable to del user in group") Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) htgroup = HTGroup(Config.dav_group_file) if user in self.ro_users: self.ro_users.remove(user) htgroup.delete(user, self.group+"_ro") if user in self.rw_users: self.rw_users.remove(user) htgroup.delete(user, self.group+"_rw") if (len(self.ro_users) + len(self.rw_users)) == 0: return self.disable() return True
def create_session(self, session): Logger.info("SessionManagement::create %s for user %s"%(session.id, session.user.name)) if System.userExist(session.user.name): Logger.error("unable to create session: user %s already exists"%(session.user.name)) session.end_status = Session.SESSION_END_STATUS_ERROR self.aps_instance.session_switch_status(session, Session.SESSION_STATUS_ERROR) return self.destroy_session(session) rr = session.user.create() if rr is False: Logger.error("unable to create session for user %s"%(session.user.name)) session.end_status = Session.SESSION_END_STATUS_ERROR self.aps_instance.session_switch_status(session, Session.SESSION_STATUS_ERROR) return self.destroy_session(session) session.user.created = True try: rr = session.install_client() except Exception,err: Logger.debug("Unable to initialize session %s: %s"%(session.id, str(err))) rr = False
def mount_cifs(self, share, uri, dest): mount_env = {} if share.has_key("login") and share.has_key("password"): cmd = "mount -t cifs -o 'uid=%s,gid=0,%s,iocharset=utf8' //%s%s %s" % ( self.session.user.name, self.DEFAULT_PERMISSION, uri.netloc, uri.path, dest, ) mount_env["USER"] = share["login"] mount_env["PASSWD"] = share["password"] else: cmd = "mount -t cifs -o 'guest,uid=%s,gid=0,%s,iocharset=utf8' //%s%s %s" % ( self.session.user.name, self.DEFAULT_PERMISSION, uri.netloc, uri.path, dest, ) cmd = self.transformToLocaleEncoding(cmd) Logger.debug("Profile, share mount command: '%s'" % (cmd)) p = System.execute(cmd, env=mount_env) if p.returncode != 0: Logger.debug("CIFS mount failed (status: %d) => %s" % (p.returncode, p.stdout.read())) return False return True
def del_user(self, user): if user not in self.ro_users and user not in self.rw_users: return True ret = True if user in self.ro_users: cmd = "deluser %s %s_ro" % (user, self.group) else: cmd = "deluser %s %s_rw" % (user, self.group) p = System.execute(cmd) if p.returncode is not 0: ret = False Logger.error("FS: unable to del user in group") Logger.debug("FS: command '%s' return %d: %s" % (cmd, p.returncode, p.stdout.read().decode("UTF-8"))) htgroup = HTGroup(Config.dav_group_file) if user in self.ro_users: self.ro_users.remove(user) htgroup.delete(user, self.group + "_ro") if user in self.rw_users: self.rw_users.remove(user) htgroup.delete(user, self.group + "_rw") if (len(self.ro_users) + len(self.rw_users)) == 0: return self.disable() return True
def destroy(self): lock = FileLock("/tmp/user.lock") arg_remove = "" if self.check_remaining_mount_points(): arg_remove = "--remove" cmd = "userdel --force %s %s"%(arg_remove, System.local_encode(self.name)) retry = 5 while retry !=0: lock.acquire() s,o = commands.getstatusoutput(cmd) lock.release() if s == 0: return True if s == 3072: Logger.debug("mail dir error: '%s' return %d => %s"%(str(cmd), s, o)) return True Logger.debug("User delete of %s: retry %i"%(self.name, 6-retry)) if s == 256 or s == 2560: # an other process is creating a user Logger.debug("An other process is creating a user") retry -=1 time.sleep(0.2) continue if s != 0: Logger.error("userdel return %d (%s)"%(s, o)) return False return True
def init(self): Logger.debug("ApplicationServer init") try: TS.getList() except Exception: Logger.exception("RDP server dialog failed ... exiting") return if not System.groupExist(self.manager.ts_group_name): Logger.error("The group '%s' doesn't exist"%(self.manager.ts_group_name)) return False if not System.groupExist(self.manager.ovd_group_name): if not System.groupCreate(self.manager.ovd_group_name): return False if not self.manager.purgeGroup(): Logger.error("Unable to purge group") return False if Config.clean_dump_archive: self.purgeArchives() if Config.thread_count is None: cpuInfos = System.getCPUInfos() vcpu = cpuInfos[0] ram_total = System.getRAMTotal() ram = int(round(ram_total / 1024.0 / 1024.0)) nb_thread = int(round(1 + (ram + vcpu * 2)/3)) else: nb_thread = Config.thread_count Logger._instance.setQueue(self.logging_queue, True) for _ in xrange(nb_thread): self.threads.append(SessionManagement(self.manager, self.sessions_spooler, self.sessions_spooler2, self.sessions_sync, self.logging_queue)) if self.canManageApplications(): self.apt = Apt() self.apt.init() self.threads.append(self.apt) Logger.info("ApplicationServer:: retrieve all applications installed (can take some time)") self.updateApplications() return True
def updateMonitoring(self): cpu_load = System.getCPULoad() ram_used = System.getRAMUsed() doc = Document() monitoring = doc.createElement("server") cpu = doc.createElement("cpu") cpu.setAttribute("load", str(cpu_load)) monitoring.appendChild(cpu) ram = doc.createElement("ram") ram.setAttribute("used", str(ram_used)) monitoring.appendChild(ram) self.monitoring = monitoring
def updateMonitoring(self): cpu_load = System.getCPULoad() ram_used = System.getRAMUsed() doc = Document() monitoring = doc.createElement('server') cpu = doc.createElement('cpu') cpu.setAttribute('load', str(cpu_load)) monitoring.appendChild(cpu) ram = doc.createElement('ram') ram.setAttribute('used', str(ram_used)) monitoring.appendChild(ram) self.monitoring = monitoring
def finalize(self): Logger._instance.setThreadedMode(False) self.update_locked_sessions() for session in self.sessions.values(): self.manager.session_switch_status(session, Session.SESSION_STATUS_WAIT_DESTROY) System.prepareForSessionActions() cleaner = SessionManagement(self.manager, None, None, None, None) for session in self.sessions.values(): session.end_status = Session.SESSION_END_STATUS_SHUTDOWN cleaner.destroy_session(session) self.manager.purgeGroup() Profile.cleanup()
def cleanup_repository(self): cmd = 'chown -R %s:%s "%s"' % (Config.uid, Config.gid, Config.backendSpool) p = System.execute(cmd) if p.returncode is not 0: Logger.debug("FS: following command '%s' returned %d => %s" % (cmd, p.returncode, p.stdout.read())) return False cmd = 'chmod -R u=rwX,g=rwX,o-rwx "%s"' % (Config.backendSpool) p = System.execute(cmd) if p.returncode is not 0: Logger.debug("FS: following command '%s' returned %d => %s" % (cmd, p.returncode, p.stdout.read())) return False return True
def delete(self): cmd = "rm -rf %s"%(self.directory) p = System.execute(cmd) if p.returncode is not 0: Logger.error("FS: unable to del share") Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) return False return True
def clean(self): cmd = 'htpasswd -D %s "%s"'%(Config.dav_passwd_file, self.login) p = System.execute(cmd) if p.returncode != 0: Logger.warn("FS: unable to remove user %s in 'clean' process"%(self.login)) Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) cmd = 'smbpasswd -x %s'%(self.login) p = System.execute(cmd) if p.returncode != 0: Logger.warn("FS: unable to remove user %s in 'clean' process"%(self.login)) Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8"))) cmd = "userdel -f %s"%(self.login) p = System.execute(cmd) if p.returncode != 0: Logger.warn("FS: unable to remove user %s in 'clean' process"%(self.login)) Logger.debug("FS: command '%s' return %d: %s"%(cmd, p.returncode, p.stdout.read().decode("UTF-8")))
def createShortcut(self, application_): png_file = os.path.join(self.spool, application_["id"] + ".png") ico_file = os.path.join(self.spool, application_["id"] + ".ico") cmd = """"%s" "%s" "%s" """ % ("png2ico.exe", ico_file, png_file) p = System.execute(cmd, True) if p.returncode != 0: Logger.warn("createShortcut following command returned %d: %s" % (p.returncode, cmd)) if os.path.exists(ico_file): os.remove(ico_file) return False if not os.path.exists(ico_file): Logger.warn("createShortcut: No ico file returned") return False (executable, arguments) = self.extract_command(application_["command"]) pythoncom.CoInitialize() shortcut = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink) try: shortcut.SetPath(executable) except: Logger.warn( "Unable to shortcut SetPath. Check if the following command is available on the system: '%s'" % (executable)) return False if arguments is not None: try: shortcut.SetArguments(arguments) except: Logger.warn("Unable to shortcut SetArguments ('%s')" % (arguments)) return False if application_.has_key("directory"): try: shortcut.SetWorkingDirectory(application_["directory"]) except: Logger.warn("Unable to shortcut SetWorkingDirectory ('%s')" % (application_["directory"])) return False shortcut.SetIconLocation(ico_file, 0) #shortcut.SetWorkingDirectory(workingDirectory) shortcut.SetDescription(application_["description"]) shortcut.QueryInterface(pythoncom.IID_IPersistFile).Save( os.path.join(self.spool, application_["id"] + ".lnk"), 0) return True
def finalize(self): Logger._instance.setThreadedMode(False) self.update_locked_sessions() for session in self.sessions.values(): self.manager.session_switch_status( session, Session.SESSION_STATUS_WAIT_DESTROY) System.prepareForSessionActions() cleaner = SessionManagement(self.manager, None, None, None, None) for session in self.sessions.values(): session.end_status = Session.SESSION_END_STATUS_SHUTDOWN cleaner.destroy_session(session) self.manager.purgeGroup() Profile.cleanup()
def create_session(self, session): Logger.info("SessionManagement::create %s for user %s" % (session.id, session.user.name)) if session.domain.manage_user(): if System.userExist(session.user.name): Logger.error( "unable to create session: user %s already exists" % (session.user.name)) session.end_status = Session.SESSION_END_STATUS_ERROR session.switch_status(Session.SESSION_STATUS_ERROR) return self.destroy_session(session) session.user.infos["groups"] = [ self.aps_instance.ts_group_name, self.aps_instance.ovd_group_name ] if session.mode == "desktop": session.user.infos["shell"] = "OvdDesktop" else: session.user.infos["shell"] = "OvdRemoteApps" rr = session.user.create() if rr is False: Logger.error("unable to create session for user %s" % (session.user.name)) session.end_status = Session.SESSION_END_STATUS_ERROR session.switch_status(Session.SESSION_STATUS_ERROR) return self.destroy_session(session) session.user.created = True try: rr = session.install_client() except Exception: Logger.exception("Unable to initialize session %s" % session.id) rr = False if rr is False: Logger.error("unable to initialize session %s" % (session.id)) session.end_status = Session.SESSION_END_STATUS_ERROR session.switch_status(Session.SESSION_STATUS_ERROR) return self.destroy_session(session) else: # will be customize by a lock system when the users will connect in RDP if not session.domain.onSessionCreate(): session.end_status = Session.SESSION_END_STATUS_ERROR session.switch_status(Session.SESSION_STATUS_ERROR) return False session.post_install() session.switch_status(Session.SESSION_STATUS_INITED)
def get_enabled_usershares(self): p = System.execute("net usershare list") if p.returncode is not 0: Logger.error("FS: unable to 'net usershare list': %d => %s"%(p.returncode, p.stdout.read())) res = [] try: res = os.listdir("/var/lib/samba/usershares/") except Exception, e: Logger.exception("FS: unable to list content of /var/lib/samba/usershares") return res
def delete(self): cmd = "rm -rf %s" % (self.directory) p = System.execute(cmd) if p.returncode is not 0: Logger.error("FS: unable to del share") Logger.debug("FS: command '%s' return %d: %s" % (cmd, p.returncode, p.stdout.read().decode("UTF-8"))) return False return True
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 check_remaining_mount_points(self): try: user = pwd.getpwnam(System.local_encode(self.name)) except KeyError: return False mount_points = MountPoint.get_list(user.pw_dir) if mount_points is None: return False success = True for d in mount_points: path = System.local_encode(d) Logger.warn("Remaining mount point '%s'" % (path)) cmd = 'umount "%s"' % (path) p = System.execute(cmd) if p.returncode == 0: continue Logger.warn( "Unable to unmount remaining mount point %s: force the unmount" % (path)) Logger.debug('umount command "%s" return: %s' % (cmd, p.stdout.read())) cmd = 'umount -l "%s"' % (path) p = System.execute(cmd) if p.returncode != 0: Logger.error( "Unable to force the unmount remaining mount point %s" % (path)) Logger.debug('umount command "%s" return: %s' % (cmd, p.stdout.read())) success = False if success == False: Logger.error( "Unable to unmount remaining mount point, home dir %s won't be purged" % (user.pw_dir)) return success
def mount_webdav(self, share, uri, dest): davfs_conf = os.path.join(self.cifs_dst, "davfs.conf") davfs_secret = os.path.join(self.cifs_dst, "davfs.secret") if uri.scheme == "webdav": mount_uri = urlparse.urlunparse( ("http", uri.netloc, uri.path, uri.params, uri.query, uri.fragment)) else: mount_uri = urlparse.urlunparse( ("https", uri.netloc, uri.path, uri.params, uri.query, uri.fragment)) if not System.mount_point_exist(davfs_conf): f = open(davfs_conf, "w") f.write("ask_auth 0\n") f.write("use_locks 0\n") f.write("secrets %s\n" % (davfs_secret)) f.close() if not System.mount_point_exist(davfs_secret): f = open(davfs_secret, "w") f.close() os.chmod(davfs_secret, stat.S_IRUSR | stat.S_IWUSR) if share.has_key("login") and share.has_key("password"): f = open(davfs_secret, "a") f.write("%s %s %s\n" % (mount_uri, share["login"], share["password"])) f.close() cmd = "mount -t davfs -o 'conf=%s,uid=%s,gid=0,%s' '%s' %s" % ( davfs_conf, self.session.user.name, self.DEFAULT_PERMISSION, mount_uri, dest) cmd = self.transformToLocaleEncoding(cmd) Logger.debug("Profile, sharedFolder mount command: '%s'" % (cmd)) p = System.execute(cmd) if p.returncode != 0: Logger.debug("WebDAV mount failed (status: %d) => %s" % (p.returncode, p.stdout.read())) return False return True
def get_lsof(self, path): cmd = "lsof -t \"%s\"" % (path) p = System.execute(cmd) if p.returncode != 0: Logger.warn( "Failed to get the list of processus blocked on a share") return None res = p.stdout.read().decode("UTF-8") return res.split()
def init_user_session_dir(self, user_session_dir): self.user_session_dir = user_session_dir if os.path.isdir(self.user_session_dir): System.DeleteDirectory(self.user_session_dir) try: os.makedirs(self.user_session_dir) except WindowsError, e: if e[0] == 183: # The directory already exist Logger.debug("The directory %s already exist" % (self.user_session_dir))