#-*- coding: utf-8 -*- #Copyright 2008 Calculate Pack, http://www.calculate-linux.ru # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import sys import re #import popen2 import ldap import cStringIO, StringIO from ldif import LDIFParser, LDIFWriter import cl_base import cl_profile import cl_utils2 import cl_utils # Для подсчета символов import termios, fcntl, struct # Ввод pwd import getpass # Статистика файла import stat import types import time # Для ввода символа import tty import termios Version = "calculate-server 0.0.1" tr = cl_base.lang() tr.setLanguage(sys.modules[__name__]) pcs = cl_utils.prettyColumnStr def adminConnectLdap(fun): """Cоединение с LDAP администратором сервиса (декоратор) соединение с LDAP и проверка установки необходимых переменных """ def ret (self, *arg, **argv): flagError = False if not self.clVars: self.createClVars() if not self.ldapObj: if not self.getLdapObjInFile(): flagError = True if not self.baseDN: if self.clVars.defined("ld_base_dn"): self.baseDN = self.clVars.Get("ld_base_dn") if not self.baseDN: self.printERROR (_('Not found LDAP base DN')) if flagError: return False else: return fun(self, *arg , **argv) return ret class iniLdapParser(cl_base.iniParser): """Класс для работы c ini-файлом ldap""" def __init__(self): # название ini файла self.nameIniFile = "/etc/calculate/calculate.ldap" cl_base.iniParser.__init__(self, self.nameIniFile) # права создаваемого ini-файла self.setMode(0600) pathIniFile = os.path.split(self.nameIniFile)[0] if not os.path.exists(pathIniFile): os.makedirs(pathIniFile) class addLdif(LDIFParser): """Класс необходимый для добавления записей в LDAP""" def __init__(self, strInput,ldapCon): FD = cStringIO.StringIO(strInput) LDIFParser.__init__(self, FD) self.ldapCon = ldapCon def handle(self, dn, entry): self.ldapCon.add_s(dn, entry.items()) class ldapFunction(cl_utils2.ldapFun): '''Объект для работы с LDAP сервером''' def __init__(self, dnUser, password): cl_utils2.ldapFun.__init__(self, dnUser, password) def ldapAdd(self, strLdif): """Добавляем строку содержащую ldif в LDAP Если данные существуют - ошибка """ if self.conLdap: try: # Записываем параметры из ldif файла в LDAP сервер parser = addLdif(strLdif,self.conLdap) parser.parse() except ldap.LDAPError, e: self.setError(e[0]['desc']) return False except: self.setError("Error in ldif file") return False return True else: self.setError(_("No connect to LDAP server")) return False # Импортированные классы в cl_ldap # Запись ошибок imp_cl_err = cl_profile._error # Работа с XML imp_cl_xml = cl_profile.xmlShare # Обработка параметров командной строки imp_cl_help = cl_utils2.cl_help # Форматированный вывод imp_cl_smcon = cl_utils2.cl_smartcon class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon): """Класс где храняться общие методы для всех сервисов""" def __init__(self): # Переменная объект Vars self.clVars = False # Переменная объект ldapFunction self.ldapObj = False # Переменная соединение с LDAP сервером self.conLdap = False # Базовый DN LDAP сервера self.baseDN = False # DN сервисов относительно базового self.ServicesDN = "ou=Services" def restorePathDelUser(self,userName,destDir,relDir,message,unixObj=False): """Восстанавливает директорию удаленного пользователя""" removeDir = False flagError = False resRestore = self.restoreDelUser(userName, relDir, destDir, message,unixObj) # Если ошибка то выходим if not resRestore: flagError = True # Флаг создания директории профиля пользователя createDir = destDir term = "" if resRestore == True: term = message if not flagError and type(resRestore) == types.TupleType: # Если cansel if resRestore[0] == "Cancel": # Удаляем пользователя flagError = True term = None # Если No elif resRestore[0] == "No": if not self.removeDir(resRestore[1]): flagError = True if not flagError: removeDir = resRestore[1] term = False elif resRestore[0] == "Yes": createDir = False removeDir = resRestore[1] term = True if flagError or term == "": return False else: return (term, createDir, removeDir) @adminConnectLdap def restoreDelUser(self,userName,service,srcDir,message,unixObj=False): """Возвращаем данные удаленного пользователя""" # Ищем Unix пользователя if unixObj: servUnixObj = unixObj else: servUnixObj = self.servUnixObj searchUnixUser = servUnixObj.searchUnixUser(userName) # id пользователя strUid = "" if searchUnixUser: strUid = searchUnixUser[0][0][1]['uidNumber'][0] else: resPasswd = servUnixObj.searchPasswdUser(userName) if resPasswd: strUid = resPasswd.split(":")[2] if strUid: delBackDir =\ os.path.join(self.clVars.Get("sr_deleted_path"), "%s-%s"%(userName,strUid), service) if strUid and os.path.exists(delBackDir) and os.listdir(delBackDir): if message == None or type(message) == types.BooleanType: dialogRes = message else: dialogRes = self.dialogYesNo(message) if dialogRes and dialogRes == True: try: self.copyDir(srcDir, delBackDir) except: self.printERROR(_("Not restore user data in dir %s")\ %srcDir) return False self.printSUCCESS(_("Restore user data in dir %s")\ %srcDir) return "Yes", delBackDir elif dialogRes == False: return "No", delBackDir elif dialogRes == None: return "Cancel", delBackDir return True @adminConnectLdap def backupDelUser(self, userName, service, srcDir, unixObj=False): """Сохраняем данные удаляемого пользователя""" # Ищем Unix пользователя if unixObj: servUnixObj = unixObj else: servUnixObj = self.servUnixObj searchUnixUser = servUnixObj.searchUnixUser(userName) # id пользователя strUid = "" if searchUnixUser: strUid = searchUnixUser[0][0][1]['uidNumber'][0] if strUid: delBackDir =\ os.path.join(self.clVars.Get("sr_deleted_path"), "%s-%s"%(userName,strUid), service) if os.path.exists(delBackDir) and os.listdir(delBackDir): self.printERROR(_("Found deleted user data dir %s")\ %delBackDir) self.printERROR(_("Not created deleted user data dir %s")\ %delBackDir) return False else: delBackDir =\ os.path.join(self.clVars.Get("sr_deleted_path"), "%s"%(userName), service) i = 0 while os.path.exists(delBackDir): i += 1 delBackDir =\ os.path.join(self.clVars.Get("sr_deleted_path"), "%s_%s"%(userName,i), service) # Cоздаем директорию хранения удаленных пользователей if not os.path.exists(self.clVars.Get("sr_deleted_path")): os.makedirs(self.clVars.Get("sr_deleted_path")) #Делаем сохранение директории try: self.copyDir(delBackDir,srcDir) except: self.printERROR(_("Not created deleted user data dir %s")\ %delBackDir) return False self.printSUCCESS(_("Created deleted user data dir %s")\ %delBackDir) return True def stringIsJpeg(self, string): """Определяет является ли строка jpeg изображением""" if len(string)<8: return False FD = cStringIO.StringIO(string) isJpeg = False FD.seek(0, 0) (firstByte, secondByte) = FD.read(2) if (ord(firstByte) == 0xff and ord(secondByte) == 0xd8): (firstByte, secondByte) = FD.read(2) if (ord(firstByte) == 0xff and ord(secondByte) == 0xe0): isJpeg = True return isJpeg def setDaemonAutostart(self, daemon): """Прописывает демона в автозагрузку""" execStr = "rc-update add %s default" %daemon textLine = self.execProg(execStr) if "added to runlevel" in textLine or\ "already installed in runlevel" in textLine: return True else: self.printError(_("ERROR") + ": " + execStr) self.printError(_("Not added at default runlevel")+ " ...") return False def delDaemonAutostart(self, daemon): """Удаляет демона из автозагрузки""" execStr = "rc-update del %s default" %daemon textLine = self.execProg(execStr) if "removed from the following runlevels" in textLine or\ "not found in any of the specified runlevels" in textLine: return True else: self.printError(_("ERROR") + ": " + execStr) self.printError(_("Not deleted from default runlevel")+ " ...") return False def runLdapServer(self): """Запускает LDAP сервер""" textLine = self.execProg("/etc/init.d/slapd start") if "ok" in textLine: return True else: self.printNotOK(_("Starting LDAP")+ " ...") return False def restartLdapServer(self): """Запускает LDAP сервер""" textLine = self.execProg("/etc/init.d/slapd restart") if "ok" in textLine: return True else: self.printNotOK(_("Restarting LDAP")+ " ...") return False def stopLdapServer(self): """Останавливает LDAP сервер""" textLine = self.execProg("/etc/init.d/slapd stop") if "ok" in textLine: #self.printOK(_("LDAP stop")+ " ...") return True else: self.printNotOK(_("Stopping LDAP")+ " ...") return False def getALLServices(self): """Получаем все сервисы которые описаны в профилях""" # путь к директории профилей profilePath = self.clVars.Get("cl_profile_path")[0] data = os.listdir(profilePath) service = [] for fileData in data: if os.path.isdir(os.path.join(profilePath, fileData)): service.append(fileData) if service: # После добавления сервисов в класс необходимо удалить # apache и jabber service.remove('backup') service.remove('apache') return service def applyProfilesFromService(self, service): """Применяем профили для данного сервиса""" # Cоздаем объект профиль устанавливая директорию # service для файлов профилей clProf = cl_profile.profile(self.clVars,service) # Объединяем профили clProf.applyProfiles() if clProf.getError(): self.printERROR(clProf.getError()) return False else: return True def searchService(self): """Поиск DN сервиса""" name, value = self.relServDN.split('=') resSearch = self.searchLdapDN(value, self.ServicesDN, name) return resSearch def delServicesAutostart(self, servInstalled): """Удаляет из автозагрузки сервисы Входные данные - список названий сервисов """ flagError = False flagLdap = False for service in servInstalled: if service == "unix" or service == "ldap": if not self.delDaemonAutostart("slapd"): flagError = True break continue elif service == "mail": if not self.delDaemonAutostart("postfix"): flagError = True break if not self.delDaemonAutostart("dovecot"): flagError = True break continue elif service == "jabber": if not self.delDaemonAutostart("ejabberd"): flagError = True break continue else: if not self.delDaemonAutostart("service"): flagError = True break continue if flagError: return False else: return True def stopServices(self, servInstalled): """Останавливает все сервисы поданные на вход этому методу Входные даннные - список названий сервисов """ flagError = False flagLdap = False for service in servInstalled: if service == "unix" or service == "ldap": flagLdap = True continue elif service == "mail": if self.getRunDaemons(["postfix"]): textLine = self.execProg("/etc/init.d/postfix stop") if not ("ok" in textLine): self.printERROR( "Postfix" + " " + _("service is not stopped")) flagError = True break if self.getRunDaemons(["dovecot"]): textLine = self.execProg("/etc/init.d/dovecot stop") if not ("ok" in textLine): self.printERROR(str("Dovecot") + " " + _("service is not stopped")) flagError = True break continue elif service == "jabber": if self.getRunService("jabber"): textLine = self.execProg("/etc/init.d/ejabberd stop") if not ("ok" in textLine): self.printERROR( "Ejabberd" + " " + _("service is not stopped")) flagError = True break listProcess = self.execProg("ps ax",False,False) killPid = [] for process in listProcess: if "erlang" in process: killPid.append(process.split(" ")[0]) if killPid and " ".join(killPid).strip(): textLine = self.execProg("kill %s" %" ".join(killPid)) if not (textLine == None): self.printERROR(_("Can not 'kill %s'")\ %" ".join(killPid)) flagError = True break elif self.getRunService(service): stopService = service textLine = self.execProg("/etc/init.d/%s stop" %(stopService)) if not ("ok" in textLine): self.printERROR( str(service) + " " + _("service is not stopped")) flagError = True break if flagLdap: if self.getRunService('ldap'): textLine = self.execProg("/etc/init.d/slapd stop") if not ("ok" in textLine): self.printERROR( "LDAP" + " " + _("service is not stopped")) flagError = True if flagError: return False else: return True def getUserPassword(self, options, optDialog, optStdIn, pwDialog=False): """Получить пароль у пользователя options - полученные опции командной строки optDialog - опция командной строки для вывода диалога для получения пароля optStdIn - опция командной строки для получения пароля из стандартного ввода (stdin) pwDialog - структура для вывода приглашения в режиме диалога """ userPwd = "" if optStdIn and options.has_key(optStdIn): pwdA = sys.stdin.readline().rstrip() pwdB = sys.stdin.readline().rstrip() elif optDialog and options.has_key(optDialog): if not pwDialog: pwDialog = [_("New password"), _("Retype new password")] pwdA = getpass.getpass(pwDialog[0]+":") pwdB = getpass.getpass(pwDialog[1]+":") if (optStdIn and options.has_key(optStdIn)) or\ (optDialog and options.has_key(optDialog)): if not pwdA or not (pwdA == pwdB): self.printERROR (_("ERROR") + ": " +\ _("password incorrect")+ ": " + _("try again")) return False userPwd = pwdA userPwd = re.sub("(\W)", r"\\\1",userPwd) return userPwd def getRunDaemons(self, daemons, printError=False): """Проверка, запущены ли демоны""" baseDir = "/var/run" runDaemons = {} for daemon in daemons: # Проверка на запуск демона postfix if daemon == 'postfix': flagRun = False listProcess = self.execProg("ps ax",False,False) for process in listProcess: if "postfix/master" in process: flagRun = True break if flagRun: runDaemons['postfix'] = True else: runDaemons['postfix'] = False continue addDirDict = {"slapd":("openldap","slapd.pid"), "samba":("samba","smbd.pid"), "dovecot":("dovecot","master.pid"), "ejabberd":("/var/lib/init.d/daemons","ejabberd")} if addDirDict[daemon][0][:1] == "/": pidDir = addDirDict[daemon][0] else: pidDir = baseDir + "/" + addDirDict[daemon][0] if os.access(pidDir, os.F_OK) and os.listdir(pidDir) and\ os.path.exists(os.path.join(pidDir,addDirDict[daemon][1])): runDaemons[daemon] = True else: runDaemons[daemon] = False if printError: for daemon in daemons: if not runDaemons[daemon]: self.printERROR(_("Daemon %s is not started") %daemon) if False in runDaemons.values(): return False else: return True def getRunService(self, nameService, printError=False): """Проверка, запущен ли сервис с данным именем""" flagError = False if nameService == "mail": daemons = ['postfix','dovecot'] if not self.getRunDaemons(daemons,printError): flagError = True elif nameService == "ldap": if not self.getRunDaemons(['slapd'],printError): flagError = True elif nameService == "jabber": if not self.getRunDaemons(['ejabberd'],printError): flagError = True else: if not self.getRunDaemons([nameService],printError): flagError = True if flagError: if printError: self.printERROR( nameService.capitalize + " " + _("service is not started") + " ...") return False return True def unicList(self, lst): """Список уникальных элементов из списка не уникальных""" return list(set(lst)) def setJpegPhotoUser(self, userName, photoPath, attr="uid"): """Добавляем jpeg фотографию пользователя в LDAP""" try: FD = open(photoPath) photoData = FD.read() FD.close() except: self.printERROR(_("Not open file") + ": " + str(photoPath)) return False searchUser = self.searchLdapDN(userName, self.relUsersDN, attr) if not searchUser: self.printERROR(_("User") + " " + str(userName) + " "+\ _("not found")) return False modAttrs = [] if not self.stringIsJpeg(photoData): self.printERROR(_("File") + " " + str(photoPath) + " " +\ _("is not jpeg")) return False if searchUser[0][0][1].has_key('jpegPhoto'): modAttrs.append((ldap.MOD_REPLACE, 'jpegPhoto', photoData)) else: modAttrs.append((ldap.MOD_ADD, 'jpegPhoto', photoData)) userDN = self.addDN("%s=%s"%(attr,userName),self.relUsersDN) if not self.modAttrsDN(userDN, modAttrs): return False return True def removeDir(self, rmDir): """Рекурсивное удаление директории""" if not os.path.exists(rmDir): self.printERROR(_("Not found remove dir %s") %rmDir) return False fileObj = cl_profile._file() # Сканируем директорию scanObjs = fileObj.scanDirs([rmDir]) for fileRm in scanObjs[0].files: # Удаляем файлы os.remove(fileRm) for linkRm in scanObjs[0].links: # Удаляем ссылки os.unlink(linkRm[1]) scanObjs[0].dirs.sort(lambda x, y: cmp(len(y), len(x))) for dirRm in scanObjs[0].dirs: # Удаляем директории os.rmdir(dirRm) os.rmdir(rmDir) return True def removeEmptyDir(self, rmDir): """Удаление пустых директорий""" if not os.path.exists(rmDir): self.printERROR(_("Not found remove dir %s") %rmDir) return False rDir = rmDir while os.listdir(rDir) == []: os.rmdir(rDir) rDir = os.path.split(rDir)[0] if rDir == "/": break return True def createUserDir(self, uid, gid, userDir, mode=0700): """Создание пользовательской директории""" if not os.path.exists(userDir): os.makedirs(userDir) if mode: os.chmod(userDir,mode) os.chown(userDir,uid,gid) return True else: self.printERROR(_("Path %s exists") %userDir) return False def createUserFile(self, fileName, fileTxt, uid, gid, mode=0644): """Создает пользовательский файл с содержимым Если директория файла не существует то ошибка """ userDir = os.path.split(fileName)[0] if not os.path.exists(userDir): self.printERROR(_("Path %s not exists") %userDir) return False fd = os.open(fileName, os.O_CREAT) os.close(fd) os.chmod(fileName, mode) os.chown(fileName,uid,gid) FD = open(fileName, "r+") FD.write(fileTxt) FD.close() return True def saveVarsClient(self, listVarName): """Записывает переменные для клиента calcualte-client""" #считаем переменные для клиента dictVar = {} flagError = False for varName in listVarName: value = self.clVars.Get(varName) if not value and value != "": self.printERROR(_("Variables %s is empty")%varName) flagError = True break dictVar[varName] = value if flagError: return False #Запишем переменные в клиентскую секцию for name,value in dictVar.items(): value = str(value) if not self.clVars.Write(name,value,True,"remote","client"): self.printERROR(_("Error writing variable %s")%name) flagError = True break if flagError: return False return True @adminConnectLdap def isServiceSetup(self, service): """Проверяет установлен ли сервис""" if self.clVars: if self.clVars.Get("sr_%s_set"%service) == "on": return True self.printERROR(_("Service %s is not installed")%service + " ...") return False def copyDir(self, destDir, srcDir): """Копируем директорию в другое место При копировании сохраняются владелец, группа, права """ if not os.path.exists(destDir): # Создаем домашнюю директорию os.makedirs(destDir) # Файловый объект fileObj = cl_profile._file() # Сканируем директорию scanObjs = fileObj.scanDirs([srcDir]) if not scanObjs: return True for dirSrc in scanObjs[0].dirs: #создаем в домашней директории директории из srcDir dirName = destDir + dirSrc.split(srcDir)[1] os.mkdir(dirName) mode,uid,gid = fileObj.getModeFile(dirSrc) os.chown(dirName, uid,gid) os.chmod(destDir, mode) for fileCopy in scanObjs[0].files: oldFile = destDir + fileCopy.split(srcDir)[1] #копируем файлы fileObj.openFiles(fileCopy, oldFile) fileObj.saveOldFile() fileObj.oldProfile = False fileObj.closeFiles() os.chown(oldFile, fileObj._uid, fileObj._gid) os.chmod(oldFile, fileObj._mode) for linkCreate in scanObjs[0].links: #копируем ссылки dst = destDir + linkCreate[1].split(srcDir)[1] srcDestList = linkCreate[0].split(srcDir) if len(srcDestList)>1: src = destDir + srcDestList[1] else: src = linkCreate[0] os.symlink(src,dst) mode,uid,gid = fileObj.getModeFile(linkCreate) #Изменение прав на ссылки os.lchown(dst, uid, gid) mode,uid,gid = fileObj.getModeFile(srcDir) os.chmod(destDir, mode) os.chown(destDir, uid,gid) return True def addDN(self, *arg): """Складывает текстовые элементы DN""" DNs = [] for dn in arg: if dn: DNs.append(dn) return ','.join(DNs) def chownR(self, directory, uid, gid): """изменяет владельца и группу для всех файлов и директорий внутри directory """ fileObj = cl_profile._file() scanObjs = fileObj.scanDirs([directory]) # меняем владельца домашней директории os.chown(directory, uid,gid) # Меняем владельца директорий for dirCh in scanObjs[0].dirs: os.chown(dirCh, uid,gid) # Меняем владельца файлов for fileCh in scanObjs[0].files: os.chown(fileCh, uid,gid) # Меняем владельца ссылок for linkCh in scanObjs[0].links: os.lchown(linkCh[1], uid, gid) return True @adminConnectLdap def modAttrsDN(self, relDN, modAttrs): """Модифицирует аттрибуты DN""" DN = self.addDN(relDN,self.baseDN) if modAttrs: try: self.conLdap.modify_s(DN, modAttrs) except ldap.LDAPError, e: self.printERROR(e[0]['desc']) return False return True @adminConnectLdap def modifyElemDN(self, relDN, newFirstDn): """Изменяет основной элемент DN (uid, cn и др.)""" DN = self.addDN(relDN,self.baseDN) try: self.conLdap.modrdn_s(DN, newFirstDn) except ldap.LDAPError, e: self.printERROR(e[0]['desc']) return False return True @adminConnectLdap def delDN(self, relDN): DN = self.addDN(relDN,self.baseDN) try: self.conLdap.delete_s(DN) except ldap.LDAPError, e: self.printERROR(e[0]['desc']) return False return True def getMaxAttrDN(self, relDN, name, attr, numMin, numMax, attrSearch): """Находит максимальный добавленный аттрибут в LDAP DN""" resSearch = self.searchLdapDN(name, relDN, attr, [attrSearch]) lst = [] lst.append(0) if resSearch: for scope in resSearch: if scope[0][1].has_key(attrSearch): uid = int(scope[0][1][attrSearch][0]) if uid<=numMax and uid>=numMin: lst.append(uid) return max(lst) return False @adminConnectLdap def fullElementDNtoText(self, relDN): """Выводит все внутренние элементы DN виде текста""" DN = self.addDN(relDN, self.baseDN) listDN=[] try: dnList = self.conLdap.search_s(DN, ldap.SCOPE_SUBTREE, '(objectclass=*)',None) except ldap.LDAPError, e: self.printERROR("fullElementDN: "+e[0]['desc']) return False FDOUT = StringIO.StringIO("") writer = LDIFWriter(FDOUT) for dn, f in dnList: writer.unparse(dn, f) FDOUT.seek(0) return FDOUT.read() @adminConnectLdap def deleteDN(self, relDelDN): """Удаляет DN и все внутренние элементы""" delDN = self.addDN(relDelDN, self.baseDN) delListDN=[] try: dnList = self.conLdap.search_s(delDN, ldap.SCOPE_SUBTREE, '(objectclass=*)', ['']) except ldap.LDAPError, e: self.printERROR("deleteDN: "+e[0]['desc']) return False for dn, f in dnList: delListDN.append(dn) delListDN.sort(lambda x, y: cmp(len(y), len(x))) for dn in delListDN: try: self.conLdap.delete_s(dn) except ldap.LDAPError, e: self.printERROR("deleteDN: "+e[0]['desc']) return False return True def execProg(self, cmdStrProg, inStr=False, retFull=True): """Выполняет внешнюю программу Параметры: cmdStrProg внешняя программа inStr данные передаваемые программе на страндартный вход. Возвращаемые параметры: строка которую выведет внешняя программа """ return cl_utils.runOsCommand(cmdStrProg, inStr, retFull) def createLdif(self, ldifFile): """Cоздает ldif из ldif - профиля""" if not os.access(ldifFile, os.F_OK): self.setError(_("File not found") + ":\n " + ldifFile) return False FD = open (ldifFile) ldifProfile = FD.read() FD.close() clProf = cl_profile.profile(self.clVars) # Применяем условия к профилю ldifProfile = clProf.applyTermsProfile(ldifProfile,ldifFile) # Заменяем переменные ldifProfile = clProf.applyVarsProfile(ldifProfile,ldifFile) return ldifProfile def searchLineInFile(self, name, fileName, numEl=0): """Ищет строку в которой есть название разделенное ':' в файле похожем на /etc/passwd""" if os.path.exists(fileName): FD = open(fileName) lines = FD.readlines() FD.close() lineFound = "" for line in lines: if name == line.split(":")[numEl]: lineFound = line break if lineFound: return lineFound else: return False def getMaxInFile(self, fileName, numMin, numMax, numEl=2): """Получаем максимальный номер из файла похожего на /etc/group""" lst = [] lst.append(0) if os.path.exists(fileName): FD = open(fileName) lines = FD.readlines() FD.close() for line in lines: num = int(line.split(":")[numEl]) if num<=numMax and num>=numMin: lst.append(num) return max(lst) return False def getLdapObjInFile(self, part="admin"): """Получаем объект ldapFunction из ini файла В выходном объекте есть соединение с LDAP сервером: self.conLdap """ ldapParser = iniLdapParser() adminDn = ldapParser.getVar(part,"DN") adminPw = ldapParser.getVar(part,"PASS") if not (adminDn or adminPw): if part == "admin": service = "LDAP" else: service = part self.printERROR(\ _("Admin password for the service %s could not be found")%service+\ " ...") return False ldapObj = ldapFunction(adminDn, adminPw) if ldapObj.getError(): self.printERROR (_("LDAP connect error") + ": " +\ ldapObj.getError().strip()) return False # Устанавливаем у объекта соединение и объект LDAP функций self.ldapObj = ldapObj self.conLdap = ldapObj.conLdap return True def dialogYn(self, message): def getChar(): fd = sys.stdin.fileno() oldSet = termios.tcgetattr(fd) tty.setraw(fd) char = sys.stdin.read(1) termios.tcsetattr(fd, termios.TCSADRAIN, oldSet) return char def term(char): if ord(char) == 3: return None if char == "Y": return True elif char == "n": return False else: char = getChar() return term(char) sys.stdout.write(message + ":") char = getChar() res = term(char) sys.stdout.write("\n") return res def dialogYesNo(self, message): sys.stdout.write(message + ": ") strIn=sys.stdin.readline().lower().strip() sys.stdout.write("\n") if "yes" == strIn: return True elif "no" == strIn: return False else: return self.dialogYesNo(message) def createClVars(self, clVars=False): """Создает объект Vars""" if not clVars: clVars = cl_base.DataVars() clVars.flServer() clVars.flIniFile() # Устанавливаем у объекта объект Vars self.clVars = clVars return True @adminConnectLdap def searchLdapDN(self, name, relDN, attr, retAttr=None): """Находит DN в LDAP""" DN = self.addDN(relDN,self.baseDN) #searchScope = ldap.SCOPE_SUBTREE searchScope = ldap.SCOPE_ONELEVEL searchFilter = "%s=%s" %(attr,name) retrieveAttributes = retAttr resSearch = self.ldapObj.ldapSearch(DN, searchScope, searchFilter, retrieveAttributes) return resSearch class servUnix(shareLdap): """Методы севисa Unix""" def __init__(self, smbObj=False): shareLdap.__init__(self) # минимальное и максимальное значение gid-ов системных групп #(Computers, и.т. д) self.maxSysGid = 999 self.minSysGid = 900 # максимальный и минимальный uid self.maxUid = self.getUidMax() self.minUid = self.getUidMin() # максимальный и минимальный gid self.maxGid = self.maxUid self.minGid = self.minUid self.relGrDN = 'ou=Groups' self.relUsDN = 'ou=Users' self.relServDN = 'ou=Unix' self.relDN = self.addDN(self.relServDN,self.ServicesDN) # DN пользователей, относительно базового DN self.relUsersDN = self.addDN(self.relUsDN, self.relDN) # DN групп пользователей, относительно базового DN self.relGroupsDN = self.addDN(self.relGrDN, self.relDN) # Коментарий к группе по умолчанию self.groupGecos = "Calculate group" # Коментарий к группе компьютеров self.groupCompGecos = "Computer group" # Базовая директория пользователей self.baseDir = "/home" # Название пользователя по умолчанию self.fullNameUser = "Calculate user" # Оболочка пользователя по умолчанию self.userShell = "/bin/bash" # Скелетная директория для создания пользователя self.skelDir = "/etc/skel" # Алгоритм шифрования пароля для LDAP пользователя self.userCrypt = "{SSHA}" # Используемые ldif файлы self.ldifFileMachine =\ "/usr/lib/calculate/calculate-server/ldif/samba_machine.ldif" self.ldifFileUser =\ "/usr/lib/calculate/calculate-server/ldif/unix_user.ldif" self.ldifFileGroup =\ "/usr/lib/calculate/calculate-server/ldif/unix_group.ldif" self.ldifFileBase =\ "/usr/lib/calculate/calculate-server/ldif/unix_base.ldif" if smbObj: # получаем объект сервиса Samba self.servSambaObj = smbObj else: # создаем объект сервиса Samba self.servSambaObj = servSamba(self) # создаем объект сервиса Mail self.servMailObj = servMail(self) # DN, компьютеров относительно базового DN self.relComputersDN = self.servSambaObj.relComputersDN def getLdapObjInFile(self): """Cоединение с LDAP администратором Samba сервиса""" return shareLdap.getLdapObjInFile(self, "unix") def createHomeDir(self, userName, homeDir, skelDir): """Создаем домашнюю директорию пользователя создание происходит после создания пользователя """ resLdap = self.searchUnixUser(userName) if resLdap: uid = int(resLdap[0][0][1]['uidNumber'][0]) gid = int(resLdap[0][0][1]['gidNumber'][0]) else: return False if not os.path.exists(homeDir): # Создаем домашнюю директорию os.makedirs(homeDir) # Файловый объект fileObj = cl_profile._file() # Сканируем скелетную директорию scanObjs = fileObj.scanDirs([skelDir]) if not scanObjs: return True for dirCreate in scanObjs[0].dirs: #создаем в домашней директории директории из /etc/skel fileObj.createDir(skelDir, dirCreate, homeDir) dirName = homeDir + dirCreate.split(skelDir)[1] os.chown(dirName, uid,gid) for fileCopy in scanObjs[0].files: oldFile = homeDir + fileCopy.split(skelDir)[1] #копируем файлы fileObj.openFiles(fileCopy, oldFile) fileObj.saveOldFile() fileObj.oldProfile = False fileObj.closeFiles() os.chown(oldFile, uid,gid) for linkCreate in scanObjs[0].links: #копируем ссылки dst = homeDir + linkCreate[1].split(skelDir)[1] srcHomeList = linkCreate[0].split(skelDir) if len(srcHomeList)>1: src = homeDir + srcHomeList[1] else: src = linkCreate[0] os.symlink(src,dst) #Изменение прав на ссылки os.lchown(dst, uid, gid) os.chmod(homeDir, 0700) os.chown(homeDir, uid,gid) return True def searchPasswdUser(self, userName): """Ищет пользователей в /etc/passwd""" filePasswd = "/etc/passwd" return self.searchLineInFile(userName, filePasswd) def searchGroupGid(self, groupId): """Ищет gid в /etc/group""" gid = str(groupId) fileGroup = "/etc/group" return self.searchLineInFile(gid, fileGroup, 2) def searchGroupGroupName(self, groupName): """Ищет имя группы в /etc/group""" fileGroup = "/etc/group" return self.searchLineInFile(groupName, fileGroup) def searchUnixGroupName(self, groupName): """Находит группу сервиса Unix по её имени""" resSearch = self.searchLdapDN(groupName, self.relGroupsDN, "cn") return resSearch def searchUnixUser(self, userName): """Находит пользователя сервиса Unix""" resSearch = self.searchLdapDN(userName, self.relUsersDN, "uid") return resSearch def searchUnixUserPrimGroup(self, groupId): """Находит пользователей с первичной группой groupId""" resSearch = self.searchLdapDN(str(groupId), self.relUsersDN, "gidNumber") return resSearch def searchUnixGid(self, groupId): """Находит группу сервиса Unix по ёе id""" resSearch = self.searchLdapDN(str(groupId), self.relGroupsDN, "gidNumber") return resSearch def searchUnixMemberGid(self, userName): """Ищет группы сервиса Unix в котрых есть данный пользователь""" resSearch = self.searchLdapDN(userName, self.relGroupsDN, "memberUid") return resSearch def searchUidPasswd(self, userId): """Находит пользователя по его идентефикатору из /etc/passwd""" filePasswd = "/etc/passwd" return self.searchLineInFile(str(userId), filePasswd, 2) def searchUidUnix(self, userId): """Находит пользователя по его идентефикатору из LDAP""" resSearch = self.searchLdapDN(str(userId), self.relUsersDN, "uidNumber") return resSearch def searchGroupsUnix(self, userGroups, printError=True): """Ищет список групп из списка userGroups в LDAP Список групп может состоять из чисел или названий групп Возвращает список имен групп """ userGroupNames = [] flagInt = True for gid in userGroups: try: int(gid) except: flagInt = False break flagError = False if flagInt: for gidNumber in userGroups: res = self.searchUnixGid(gidNumber) if not res: flagError = True break userGroupNames.append(res[0][0][1]['cn'][0]) if flagError: if printError: self.printERROR(\ _("Group number %s is not found in Unix service") %\ str(gidNumber) + "...") return False else: for groupName in userGroups: res = self.searchUnixGroupName(groupName) if not res: flagError = True break if flagError: if printError: self.printERROR(\ _("Group name %s is not found in Unix service") %\ str(groupName) + "...") return False userGroupNames = userGroups return userGroupNames def searchGroupsGroups(self, userGroups, printError=True): """Ищет список групп из списка userGroups в /etc/group Список групп может состоять из чисел или названий групп Возвращает список имен групп """ userGroupNames = [] flagInt = True for gid in userGroups: try: int(gid) except: flagInt = False break flagError = False if flagInt: for gidNumber in userGroups: res = self.searchGroupGid(gidNumber) if not res: flagError = True break userGroupNames.append(res.split(':')[0]) if flagError: if printError: self.printERROR( _("Group number %s is not found in") %\ str(gidNumber) + " /etc/group ...") return False else: for groupName in userGroups: res = self.searchGroupGroupName(groupName) if not res: flagError = True break if flagError: if printError: self.printERROR( _("Group name %s is not found in") %\ str(groupName) + " /etc/group ...") return False userGroupNames = userGroups return userGroupNames def searchUsersInGroupUnix(self, usersNames, groupName): """Ищет спиcок пользователей в группе, ищет в Unix В случае успеха выводит список найденных пользователей если нет группы False если ничего не найдено пустой список """ res = self.searchUnixGroupName(groupName) if not res: return False else: findUsers = [] if res[0][0][1].has_key('memberUid'): usersInGroup = res[0][0][1]['memberUid'] for userName in usersNames: if userName in usersInGroup: findUsers.append(userName) return findUsers def searchUsersInGroupGroup(self, usersNames, groupName): """Ищет спиcок пользователей в группе, ищет в /etc/groups В случае успеха выводит список найденных пользователей если нет группы False если ничего не найдено пустой список """ res = self.searchGroupGroupName(groupName) if not res: return False else: findUsers = [] res = res.rstrip() usersInGroup = res.split(':')[3] if not usersInGroup: return findUsers usersInGroup = usersInGroup.split(',') for userName in usersNames: if userName in usersInGroup: findUsers.append(userName) return findUsers @adminConnectLdap def addGroupUnixServer(self, groupName, options, printSuccess=True): """Добавляет группу пользователей Unix""" # Проверим установлен ли сервис unix if not self.isServiceSetup("unix"): return False # Если группа существует выходим без ошибки flagSearchGroups = True if options.has_key('f'): flagSearchGroups = False if flagSearchGroups and self.searchGroupGroupName(groupName): self.printERROR(\ _("group name %s is found in") % str(groupName) +\ " /etc/group ...") return False if self.searchUnixGroupName(groupName): self.printERROR(\ _("group name %s is found in Unix service") %\ str(groupName) + " ...") return False self.clVars.Set("ur_group",groupName) # номер группы gid = str(self.getMaxGid()) if options.has_key('g'): gid = options['g'] try: int(gid) except: self.printERROR(_("GID must be is number") + " ...") return False if flagSearchGroups and self.searchGroupGid(gid): self.printERROR(_("GID is found in") + " /etc/group ...") return False if self.searchUnixGid(gid): self.printERROR(_("GID is found in Unix service") + " ...") return False self.clVars.Set("ur_group_id", gid) # Коментарий к группе gecos = self.groupGecos if options.has_key('c'): gecos = options['c'] self.clVars.Set("ur_group_comment",gecos) ldifFile = self.ldifFileGroup groupLdif = self.createLdif(ldifFile) if not groupLdif: print self.getError() return False if not self.ldapObj.getError(): self.ldapObj.ldapAdd(groupLdif) if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False if options.has_key('p'): sys.stdout.write(gid) else: if printSuccess: self.printSUCCESS(_("Added group in Unix service") + " ...") return True @adminConnectLdap def addMachineLdapServer(self, machineName, options): # Проверим установлен ли сервис unix if not self.isServiceSetup("unix"): return False """Добавляет Unix машину в LDAP-сервер""" machineLogin = machineName.replace('$','') + "$" groupName = self.clVars.Get('sr_samba_machine_group') resSearch = self.searchUnixGroupName(groupName) if resSearch: groupId = resSearch[0][0][1]['gidNumber'][0] else: # Находим следующий номер в диапазоне системных групп groupId = str(self.getMaxGidSystem()) res = self.searchUnixGid(groupId) maxGid = self.getUidMax() if res: numberGid = int(groupId) flagMaxGidError = False while res: numberGid += 1 res = self.searchUnixGid(str(numberGid)) if numberGid>=maxGid: flagMaxGidError = True break if flagMaxGidError: self.printERROR (_("ERROR") + ": " +\ _("free GID %s is not found in Unix service") %\ str(userGid)) return False groupId = str(numberGid) options = {'g':groupId,'c':self.groupCompGecos} if not self.addGroupUnixServer(groupName, options): return False self.clVars.Set('sr_samba_machine_login',machineLogin) # Находим последний добавленный id userIdNumber = str(self.getMaxUid()) self.clVars.Set('sr_samba_machine_id',userIdNumber) self.clVars.Set('sr_samba_machine_gid',groupId) ldifFile = self.ldifFileMachine userLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): #Добавляем пользователя в LDAP self.ldapObj.ldapAdd(userLdif) if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False self.printSUCCESS(_("Added machine") + "...") return True @adminConnectLdap def addUserUnixServer(self,userName,options,printSuccess=True,pwd=False): # Проверим установлен ли сервис unix if not self.isServiceSetup("unix"): return False """Добавляет Unix пользователя в LDAP-сервер""" if self.searchUnixUser(userName): self.printERROR(_("User exists in Unix service")) return False elif self.searchPasswdUser(userName): self.printERROR(_("User exists in") + " /etc/passwd") return False # id нового пользователя userId = str(self.getMaxUid()) self.clVars.Set("ur_name", userName) baseDir = self.baseDir # Базовая домашняя директория if options.has_key('b'): baseDir = options['b'] # Устанавливаем скелетную директорию if options.has_key('k'): skelDir = options['k'] else: skelDir = self.skelDir # Устанавливаем домашнюю директорию if options.has_key('d'): homeDir = options['d'] else: homeDir = os.path.join(baseDir, userName) self.clVars.Set("ur_home_path",homeDir) fullNameUser = self.fullNameUser # Полное имя пользователя if options.has_key('c'): fullNameUser = options['c'] self.clVars.Set("ur_fio",fullNameUser) # По умолчанию пользователя не видно visible = '0' if options.has_key('v'): visible = '1' self.clVars.Set("ur_visible",visible) # Оболочка пользователя userShell = self.userShell if options.has_key('s'): userShell = options['s'] self.clVars.Set("ur_shell", userShell) # id пользователя if options.has_key('u'): userId = options['u'] try: int(userId) except: self.printERROR(_("UID is not number") + " ...") return False if self.searchUidUnix(userId): self.printERROR("UID %s "%userId + \ _("exists in Unix service") + " ...") return False if self.searchUidPasswd(userId): self.printERROR("UID %s "%userId+_("exists in") + \ " /etc/passwd"+ " ...") return False self.clVars.Set("ur_id",userId) # Добавляем пользователя в группы (находим имена групп) if options.has_key('G'): userGroups = options['G'].split(',') #список имен добавляемых групп userGroupNames = self.searchGroupsUnix(userGroups) if not userGroupNames: return False userGid = str(self.getMaxGid()) # Группа пользователя if options.has_key('g'): userGid = options['g'] userGidNamesLdap = self.searchGroupsUnix([userGid], False) userGidNamesPasswd = self.searchGroupsGroups([userGid], False) if userGidNamesPasswd: #Имя группы пользователя groupName = userGidNamesPasswd[0] elif userGidNamesLdap: #Имя группы пользователя groupName = userGidNamesLdap[0] else: self.printERROR( _("Group %s is not found") % str(userGid) + " ...") return False else: if self.searchGroupGroupName(userName): self.printERROR( _("Group name %s is found in")%str(userName) +\ " /etc/group ...") return False if self.searchUnixGroupName(userName): self.printERROR( _("Group name %s is found in Unix serivce")%str(userName)+\ " ...") return False if pwd: userPwd = pwd else: userPwd = self.getUserPassword(options, "p", "P") if userPwd == False: return False if not userPwd: userPwdHash = "crypt{xxx}" else: userPwdHash =\ self.execProg("slappasswd -s %s -h %s" %(userPwd,self.userCrypt)) if not userPwdHash: self.printERROR(_("ERROR") + ": " +\ _("create crypto password")) return False self.clVars.Set("ur_hash",userPwdHash) # флаги добавления flagAdd = {} # Добавление основной группы пользователя if options.has_key('g'): resLdap = self.searchUnixGroupName(groupName) resGroup = self.searchGroupGroupName(groupName) if not (resLdap or resGroup): self.printERROR (_("ERROR") + ": " +\ "gid=" + userGid + " " + _("is not found")) return False if resGroup: userGid = resGroup.split(":")[2] if resLdap: userGid = resLdap[0][0][1]['gidNumber'][0] else: flagAddGroup = self.addGroupUnixServer(userName,{},False) flagAdd['group'] = flagAddGroup if not flagAddGroup: return False self.clVars.Set("ur_gid", userGid) ldifFile = self.ldifFileUser userLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): #Добавляем пользователя в LDAP self.ldapObj.ldapAdd(userLdif) #ldapObj.ldapAdd(userLdif1) #Добавляем его в другие группы (опция G) if options.has_key('G') and userGroupNames: for group in userGroupNames: self.addUsersGroupUnix([userName],group) # не переделывать на else flagError = False if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() flagError = True removeHomeBack = False if not flagError: # Востановим (home на сервере) удаленного пользователя message = _("Restored deleted user %s")% userName + "\n" +\ _("'yes', 'no'") resHomeDir = self.restorePathDelUser(userName, homeDir, "unix/home", message, self) if not resHomeDir: flagError = True createDirHome = False else: term, createDirHome, removeHomeBack = resHomeDir # Удаляем бекап домашней директории на сервере (удаленного польз..) if not flagError and removeHomeBack and\ os.path.exists(removeHomeBack): self.removeDir(removeHomeBack) self.removeEmptyDir(os.path.split(removeHomeBack)[0]) # Изменим время последнего измения пароля пользователя if not flagError and not self.setShadowLastChange(userName): flagError = True # Добавим домашнюю директорию if not flagError and createDirHome and options.has_key('m'): if not os.path.exists(homeDir): if not self.createHomeDir(userName, homeDir, skelDir): self.printERROR (_("ERROR") + ": " +\ _("cannot create HOME dir")) flagError = True #загружаем картинку if not flagError and options.has_key('i'): photoFile = options['i'] if not self.setJpegPhotoUser(userName, photoFile): self.printERROR(_("Not added jpeg photo for user") + " " +\ str(userName)) flagError = True if flagError: self.delUserUnixServer(userName, {}, False, False) self.printERROR (_("Can not added user")+ " " + str(userName)) return False if printSuccess: if flagAdd.has_key('group'): self.printSUCCESS(_("Added group in Unix service") + " ...") if createDirHome and options.has_key('m'): self.printSUCCESS(_("Created home dir %s")% homeDir+\ " ...") if options.has_key('i'): self.printSUCCESS(_("Added jpeg photo %s")% photoFile+\ " ...") self.printSUCCESS(_("Added user in Unix service") + " ...") return True def setUserMail(self, userName, mail): """Устанавливает для пользователя основной почтовый адрес""" searchUser = self.searchUnixUser(userName) if not searchUser: self.printERROR(_("User %s not found in Unix service")\ %str(userName)) return False modAttrs = [] if searchUser[0][0][1].has_key('mail'): modAttrs.append((ldap.MOD_REPLACE, 'mail', mail)) else: modAttrs.append((ldap.MOD_ADD, 'mail', mail)) userDN = self.addDN('uid='+userName,self.relUsersDN) if not self.modAttrsDN(userDN, modAttrs): self.printERROR(_("Can not modify mail attribute in Unix service")) return False return True def getUserMail(self, userName): """Выдаем основной почтовый адрес""" searchUser = self.searchUnixUser(userName) if not searchUser: self.printERROR(_("User %s not found in Unix service")\ %str(userName)) return False if searchUser[0][0][1].has_key('mail'): return searchUser[0][0][1]['mail'][0] else: return "" def deleteUserMail(self, userName): if self.getUserMail(userName): modAttrs =[(ldap.MOD_DELETE, 'mail', None)] userDN = self.addDN('uid='+userName,self.relUsersDN) if not self.modAttrsDN(userDN, modAttrs): self.printERROR(_("Can not delete mail attribute in Unix \ service")) return False return True def addUsersGroupUnix(self, users, groupName): """Добавляет пользователей из списка в Unix группу""" if not self.searchUnixGroupName(groupName): self.printERROR(_("group name is not found in Unix service") +\ " ...") return False flagFalse = False for userName in users: if not (self.searchUnixUser(userName) or\ self.searchPasswdUser(userName)): self.printERROR(\ _("User %s is not found")%str(userName) + " ..." ) flagFalse = True break if flagFalse: return False foundUsersLdap = self.searchUsersInGroupUnix(users, groupName) foundUsersGroup = self.searchUsersInGroupGroup(users, groupName) foundUsers = [] if foundUsersLdap and foundUsersGroup: foundUsers = self.unicList(foundUsersLdap + foundUsersGroup) elif foundUsersLdap: foundUsers = foundUsersLdap elif foundUsersGroup: foundUsers = foundUsersGroup addUsers = [] for user in users: if not(user in foundUsers): addUsers.append(user) modAttrs = [] for userName in addUsers: modAttrs.append((ldap.MOD_ADD, 'memberUid', userName)) if modAttrs: groupDN = self.addDN("cn="+groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) return True def getMaxGidUnix(self): """Находит максимальный добавленный gid в Unix""" return self.getMaxAttrDN(self.relGroupsDN, "*", "cn", self.minGid, self.maxGid, "gidNumber") def getMaxGidUnixSystem(self): """Находит максимальный добавленный gid в LDAP системной группы""" return self.getMaxAttrDN(self.relGroupsDN, "*", "cn", self.minSysGid, self.maxSysGid, "gidNumber") def getMaxGid(self): """Находит максимальный gid +1""" maxGidLdap = self.getMaxGidUnix() maxGidGroup = self.getMaxGidGroup() if maxGidLdap > maxGidGroup: maxGid = maxGidLdap else: maxGid = maxGidGroup if maxGid == 0: return self.minGid else: return maxGid+1 def getMaxGidGroupSystem(self): """Получаем максимальный добавленный gid из /etc/group системной группы """ fileGroup = "/etc/group" return self.getMaxInFile(fileGroup, self.minSysGid, self.maxSysGid) def getMaxGidGroup(self): """Получаем максимальный добавленный gid из /etc/group""" fileGroup = "/etc/group" return self.getMaxInFile(fileGroup, self.minGid, self.maxGid) def getMaxGidSystem(self): """Находит максимальный gid +1 системной группы""" maxGidLdap = self.getMaxGidUnixSystem() maxGidGroup = self.getMaxGidGroupSystem() if maxGidLdap > maxGidGroup: maxGid = maxGidLdap else: maxGid = maxGidGroup if maxGid == 0: return self.minSysGid else: return maxGid+1 def getUidMin(self): """Получаем начальный UID пользователя""" fileLogin = "/etc/login.defs" fileAdduser = "/etc/adduser.conf" minUid = 1000 if os.path.exists(fileLogin): FD = open(fileLogin) lines = FD.readlines() FD.close() for line in lines: if "UID_MIN" in line and not "#" in line: s = re.compile("\s+") minUid = int(s.split(line)[1]) break elif os.path.exists(fileAdduser): FD = open(fileLogin) lines = FD.readlines() FD.close() for line in lines: if "FIRST_UID" in line and not "#" in line: minUid = int(line.split('=')[1]) break return minUid def getUidMax(self): """Получаем конечный UID пользователя""" fileLogin = "/etc/login.defs" fileAdduser = "/etc/adduser.conf" maxUid = 29999 if os.path.exists(fileLogin): FD = open(fileLogin) lines = FD.readlines() FD.close() for line in lines: if "UID_MAX" in line and not "#" in line: s = re.compile("\s+") maxUid = int(s.split(line)[1]) break elif os.path.exists(fileAdduser): FD = open(fileLogin) lines = FD.readlines() FD.close() for line in lines: if "LAST_UID" in line and not "#" in line: maxUid = int(line.split('=')[1]) break return maxUid def getMaxUidPasswd(self): """Получаем максимальный добавленный id из /etc/passwd""" filePasswd = "/etc/passwd" return self.getMaxInFile(filePasswd, self.minUid, self.maxUid) def getMaxUidUnix(self, relDn=False): """Находит максимальный добавленный id в сервисе Unix""" if relDn: return self.getMaxAttrDN(relDn, "*", "uid", self.minUid, self.maxUid, "uidNumber") else: return self.getMaxAttrDN(self.relUsersDN, "*", "uid", self.minUid, self.maxUid, "uidNumber") def getMaxUid(self): """Находит максимальный id +1""" # Ветка компьютеры maxUidLdapComp = self.getMaxUidUnix(self.relComputersDN) maxUidLdap = self.getMaxUidUnix() maxUidPasswd = self.getMaxUidPasswd() listUid = [maxUidLdapComp, maxUidLdap, maxUidPasswd] maxUid = max(listUid) if maxUid == 0: return self.minUid else: return maxUid+1 def delUserUnixServer(self, userName, options, printSuccess=True, backup=True): """Удаляем Unix пользователя""" # Проверим установлен ли сервис unix if not self.isServiceSetup("unix"): return False # Ищем пользователя в Samba if self.servSambaObj.searchSambaUser(userName): self.printERROR (_("ERROR") + ": " +\ _("User %s is found in Samba service") %\ str(userName) + " ...") self.printWARNING(\ _("At first, need remove user from Samba service") ) return False # Ищем пользователя в Mail if self.servMailObj.searchMailUserToName(userName): self.printERROR (_("ERROR") + ": " +\ _("User %s is found in Mail service") %\ str(userName) + " ...") self.printWARNING(\ _("At first, need remove user from Mail service") ) return False # Ищем пользователя в Unix resLdap = self.searchUnixUser(userName) if not resLdap: self.printERROR (_("ERROR") + ": " +\ _("User %s is not found in Unix service") % str(userName) +\ " ...") return False if options.has_key('r'): backup = False homeDir = False if resLdap[0][0][1].has_key('homeDirectory'): #Домашняя директория пользователя homeDir = resLdap[0][0][1]['homeDirectory'][0] if backup and os.path.exists(homeDir) and os.listdir(homeDir): # Делаем сохранение домашней директории if not self.backupDelUser(userName, 'unix/home', homeDir, self): return False # Удаляем пользователя delDN = self.addDN("uid=" + userName, self.relUsersDN) if not self.delDN(delDN): return False # Удаляем пользователя из групп if not self.delUserInGroup(userName): return False if resLdap[0][0][1].has_key('gidNumber'): gid = resLdap[0][0][1]['gidNumber'][0] else: resPasswd = self.searchPasswdUser(userName) if resPasswd: gid = resPasswd.split(":")[3] #Находим основную группу пользователя resGroup = False if gid: resGroup = self.searchUnixGid(gid) if resGroup: # В случае отсутствия других пользователей удаляем основную группу if not resGroup[0][0][1].has_key('memberUid'): groupName = resGroup[0][0][1]['cn'][0] if not self.delGroupUnixServer(groupName, {}, False): return False # Удаляем домашнюю директорию if homeDir and os.path.exists(homeDir) and self.removeDir(homeDir): if printSuccess: self.printSUCCESS( _("Home directory %s is removed")% str(homeDir) + " ...") if printSuccess: self.printSUCCESS(_("User %s is deleted")%userName + " ...") return True def delGroupUnixServer(self, groupName, options, printSuccess=True): """Удаляет группу пользователей Unix""" # Проверим установлен ли сервис unix if not self.isServiceSetup("unix"): return False res = self.searchUnixGroupName(groupName) if not res: self.printERROR( _("Group %s is not found in Unix service")%groupName +\ " ...") return False groupId = res[0][0][1]['gidNumber'][0] if self.searchUnixUserPrimGroup(groupId): self.printWARNING(_("cannot remove user's primary group") + ".") return True delDN = self.addDN("cn="+groupName, self.relGroupsDN) res = self.delDN(delDN) if res: if printSuccess: self.printSUCCESS( _("Group %s is deleted")%groupName+" ...") return True else: self.printERROR(_("Can not delete group") + " " + groupName+\ " ...") return False def modUserUnixServer(self,userName, options, printSuccess=True): """Модифицирует настройки пользователя Unix в LDAP""" # Проверим установлен ли сервис unix if not self.isServiceSetup("unix"): return False res = self.searchUnixUser(userName) if not res: self.printERROR( _("User %s is not found in Unix service")%str(userName)+\ "...") return False # Новые группы в которые входит пользователь if options.has_key('G'): userGroups = options['G'].split(',') #список имен добавляемых групп userGroupNames = self.searchGroupsUnix(userGroups) if not userGroupNames: return False # Удаляем пользователя из групп в которые он входит if not self.delUserInGroup(userName): return False flagError = False for group in userGroupNames: if not self.addUsersGroupUnix([userName], group): flagError = True break if flagError: return False if printSuccess: self.printSUCCESS(_("Replaced list of supplementary group")+\ " ...") # Добавляем группы в которые входит пользователь elif options.has_key('a'): userGroups = options['a'].split(',') #список имен добавляемых групп userGroupNames = self.searchGroupsUnix(userGroups) if not userGroupNames: return False flagError = False for group in userGroupNames: if not self.addUsersGroupUnix([userName], group): flagError = True break if flagError: return False if printSuccess: self.printSUCCESS(\ _("Appended the user to the supplemental groups") + " ...") # Изменяемые аттрибуты пользователя modAttrs = [] # Изменяем первичную группу пользователя if options.has_key('g'): newFirstGroup = options['g'] userGroupNames = self.searchGroupsUnix([newFirstGroup]) if not userGroupNames: return False groupName = userGroupNames[0] resLdap = self.searchUnixGroupName(groupName) resGroup = self.searchGroupGroupName(groupName) if not (resLdap or resGroup): self.printERROR (_("ERROR") + ": " +\ _("not found gid=") + userGid) return False if resGroup: userGid = resGroup.split(":")[2] if resLdap: userGid = resLdap[0][0][1]['gidNumber'][0] modAttrs += [(ldap.MOD_REPLACE, 'gidNumber', userGid)] visible = False # пользователя видно if options.has_key('V'): visible = '1' # пользователя не видно if options.has_key('I'): visible = '0' if visible: modAttrs += [(ldap.MOD_REPLACE, 'shadowFlag', visible)] # Изменяем домашнюю директорию if options.has_key('d'): homeDir = options['d'] modAttrs += [(ldap.MOD_REPLACE, 'homeDirectory', homeDir)] # Включаем пользователя if options.has_key('U'): modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "-1")] # Выключаем пользователя if options.has_key('L'): modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "1")] # Изменяем коментарий к пользователю if options.has_key('c'): comment = options['c'] if res[0][0][1].has_key('displayName'): modAttrs += [(ldap.MOD_REPLACE, 'displayName', comment), (ldap.MOD_REPLACE, 'cn', comment)] else: modAttrs += [(ldap.MOD_REPLACE, 'cn', comment)] # Изменяем оболочку пользователя if options.has_key('s'): shell = options['s'] modAttrs.append((ldap.MOD_REPLACE, 'loginShell', shell)) # Изменяем пароль пользователя userPwd = self.getUserPassword(options, "p", "P") if userPwd == False: return False if userPwd: userPwdHash = self.execProg("slappasswd -s %s -h %s"\ %(userPwd, self.userCrypt)) if res[0][0][1].has_key('userPassword'): modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False # Переносим домашнюю директорию пользователя if options.has_key('d') and options.has_key('m'): homeDirOld = res[0][0][1]['homeDirectory'][0] homeDirNew = homeDir textLine = self.execProg("mv %s %s" %(homeDirOld, homeDirNew)) if not (textLine == None): self.printERROR(_("Can not move home directory") + " ...") modAttrs = [(ldap.MOD_REPLACE, 'homeDirectory', homeDirOld)] self.modAttrsDN(DN, modAttrs) return False else: if printSuccess: self.printSUCCESS(_("Moved home directory") + " ...") if options.has_key('c'): if printSuccess: self.printSUCCESS(_("Modified comment") + " ...") if options.has_key('s'): if printSuccess: self.printSUCCESS(_("Modified shell") + " ...") if options.has_key('d'): if printSuccess: self.printSUCCESS(_("Modified home directory") + " ...") if options.has_key('P') or options.has_key('p'): # Изменим время последнего измения пароля пользователя if not self.setShadowLastChange(userName): return False if printSuccess: self.printSUCCESS(\ _("Modified user password of Unix service")+\ " ...") if options.has_key('U'): if printSuccess: self.printSUCCESS(_("Unlocked user %s")% str(userName) +\ " ...") if options.has_key('I'): if printSuccess: self.printSUCCESS(\ _("User %s is invisible")% str(userName) + " ...") if options.has_key('V'): if printSuccess: self.printSUCCESS(_("User %s is visible")% str(userName)+\ " ...") if options.has_key('L'): if printSuccess: self.printSUCCESS(_("Locked user %s")% str(userName) +\ " ...") return True def modUserUnixPasswd(self, userName, options, pwd=False): # Проверим установлен ли сервис unix if not self.isServiceSetup("unix"): return False """Устанавливает пароль LDAP пользователя и меняет его опции""" res = self.searchUnixUser(userName) if not res: self.printERROR( _("User %s is not found in Unix service")%str(userName) +\ " ...") return False # Изменяемые аттрибуты пользователя modAttrs = [] # Удаляем пароль пользователя if options.has_key('d'): if res[0][0][1].has_key('userPassword'): modAttrs += [(ldap.MOD_DELETE, 'userPassword', None)] else: self.printERROR(\ _("User %s has not password for Unix service")%\ str(userName) + " ...") # Включаем пользователя if options.has_key('u'): modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "-1")] # Выключаем пользователя elif options.has_key('l'): modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "1")] if not options: optPasswd = {"p":""} if pwd: userPwd = pwd else: userPwd = self.getUserPassword(optPasswd, "p", False) if userPwd == False: return False userPwdHash =\ self.execProg("slappasswd -s %s -h %s"\ %(userPwd, self.userCrypt)) if res[0][0][1].has_key('userPassword'): modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if options.has_key('d'): self.printSUCCESS( _("Deleted password of Unix service for user") +\ str(userName) + " ...") if options.has_key('l'): self.printSUCCESS(_("Locked user") + " " + str(userName) +\ " " +_("of Unix service") + " ...") if options.has_key('u'): self.printSUCCESS(_("Unlocked user") + " " + str(userName) +\ " " +_("of Unix service") + " ...") if not options: self.printSUCCESS(_("User password of Unix service changed")+\ " ...") # Изменим время последнего измения пароля пользователя if not self.setShadowLastChange(userName): return False return True return False def modGroupUnixServer(self, groupName, options): # Проверим установлен ли сервис unix if not self.isServiceSetup("unix"): return False """Модифицирует настройки группы пользователей LDAP""" if not self.searchUnixGroupName(groupName): self.printERROR(_("group name not found in Unix service") + " ...") return False # Добавляем список пользователей в группу if options.has_key('a'): # добавляемые пользователи в группу users = options['a'].split(',') res = self.addUsersGroupUnix(users, groupName) if res: self.printSUCCESS(_("Appended list of users to group") + " " +\ str(groupName) + " ...") else: self.printERROR(_("Can not append list of users to group") +\ " " + str(groupName) + " ...") return False # Удаляем список пользователей из группы if options.has_key('d'): # удаляемые пользователи из группы users = options['d'].split(',') res = self.delUsersGroupUnix(users, groupName) if res: self.printSUCCESS(_("Deleted list users from group") + " " +\ str(groupName) + " ...") else: self.printERROR(_("Can not delete list users from group") +\ " " + str(groupName) + " ...") return False modGroupName = groupName # Изменяем имя группы if options.has_key('n'): newGroupName = options['n'] if self.searchUnixGroupName(newGroupName): self.printERROR( _("group name %s is found in Unix service")%\ str(newGroupName) + " ...") return False newFirstDn = "cn=" + newGroupName oldDN = self.addDN("cn=" + groupName, self.relGroupsDN) res = self.modifyElemDN(oldDN, newFirstDn) if res: modGroupName = newGroupName self.printSUCCESS(_("Group renamed") + " ...") else: self.printERROR(_("Can not rename group") + "...") return False modAttrs = [] # Изменяем коментарий к группе if options.has_key('c'): gecos = options['c'] modAttrs.append((ldap.MOD_REPLACE, 'description', gecos)) if modAttrs: groupDN = self.addDN("cn=" + modGroupName, self.relGroupsDN) res = self.modAttrsDN(groupDN, modAttrs) if res: if options.has_key('c'): self.printSUCCESS(_("Modified group comment") + " ...") return True else: if options.has_key('c'): self.printSUCCESS(_("Can not modify group comment") +\ " ...") return False return True def delUserInGroup(self, userName): """Удаление из групп в которые входит пользователь""" userInGroups = self.searchUnixMemberGid(userName) modAttrs = [(ldap.MOD_DELETE, 'memberUid', userName)] flagError = False for group in userInGroups: groupName = group[0][1]['cn'][0] groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) if not self.modAttrsDN(groupDN, modAttrs): flagError = True break if flagError: return False else: return True def delUsersGroupUnix(self, users, groupName): """Удаление пользователей из списка из группы Unix""" res = self.searchUnixGroupName(groupName) if not res : self.printERROR(_("group name is not found in Unix service") +\ " ...") return False if not res[0][0][1].has_key("memberUid"): self.printERROR( _("Member list of group %s is empty")%str(groupName) + " ...") return False memberUsers = res[0][0][1]["memberUid"] flagError =False for user in users: if not user in memberUsers: flagError = True break if flagError: self.printERROR( _("User %s is not found in group")%str(user)+" "+\ str(groupName) + " ...") return False modAttrs = [] for userName in users: modAttrs.append((ldap.MOD_DELETE, 'memberUid', userName)) groupDN = self.addDN("cn="+groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) def setupUnixServer(self, options): """Начальная настройка Unix сервиса""" # Принудительная установка forceOptions = False # Cоздаем объект переменные self.createClVars() if options.has_key("f"): forceOptions = True # В случае если сервер установлен if self.clVars.Get("sr_unix_set") == "on" and\ not forceOptions: self.printWARNING (_("WARNING") + ": " +\ _("Unix service already configured")+ ".") return True if not self.clVars.Get("sr_ldap_set") == "on": self.printERROR(_("LDAP service not setuped") +" ...") self.printWARNING(_("Setup LDAP service")) self.printWARNING(" cl-setup ldap") return False if not forceOptions: # предупреждение при выполнении этой программы будут изменены # конфигурационные файлы и база данных сервиса LDAP self.printWARNING (_("WARNING") + ": " + _("Executing of the program will change") + " " + _("the configuration files and database of LDAP service")+ ".") # если вы готовы продолжить работу программы нажмите Y если нет n messDialog = \ _("If you are ready to continue executing the program")+", "+\ _("input 'yes'") +", "+ _("if not 'no'") if not self.dialogYesNo(messDialog): return True else: # делаем backup # Проверим запущен ли ldap if not self.getRunService("ldap"): # Запускаем LDAP сервер if not self.runLdapServer(): return False bakupObj = servLdap() bakupObj.backupServer() # Имя устанавливаемого сервиса self.clVars.Set("cl_pass_service","unix") self.clVars.Write("sr_unix_set","off") # Cоздаем объект профиль устанавливая директорию ldap для # файлов профилей if not self.applyProfilesFromService('unix'): return False # Проверим запущен ли ldap if not self.getRunService("ldap"): # Запускаем LDAP сервер if not self.runLdapServer(): return False else: if not self.restartLdapServer(): return False #Cоединение с Ldap (администратор) shareLdap.getLdapObjInFile(self) # Удаляем предыдущую ветку сервиса Unix servicesDN = self.relDN resSearch = self.searchService() ret = True if resSearch: delDN = self.relDN ret = self.deleteDN(delDN) if ret: self.printOK(_("Removed Unix DN from LDAP database") + " ...") else: self.printERROR(\ _("Can not remove Unix DN from LDAP database") + " ...") if not ret: return False ldifFile = self.ldifFileBase baseLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False self.printOK(_("Added ldif file") +" ...") # Записываем данные администратора сервиса Unix ldapParser = iniLdapParser() ldapParser.setVar("unix", {"DN":self.clVars.Get("ld_unix_dn"), "PASS":self.clVars.Get("ld_unix_pw")}) self.printOK(_("Unix service configured") +" ...") self.clVars.Write("sr_unix_set","on") return True def setShadowLastChange(self, userName): """Изменим последнюю дату измениня пароля на текущую""" # число дней от 1970 года date = int(time.time()/86400) modAttrs = [(ldap.MOD_REPLACE, 'shadowLastChange', str(date))] userDN = self.addDN('uid='+userName,self.relUsersDN) if not self.modAttrsDN(userDN, modAttrs): self.printERROR(_("Can not modify shadowLastChange attribute")) return False return True class servMail(shareLdap): """Методы сервиса Mail""" def __init__(self, unixObj=False): shareLdap.__init__(self) self.relGrDN = 'ou=Groups' self.relUsDN = 'ou=Users' self.relServDN = 'ou=Mail' # DN сервиса self.relDN = self.addDN(self.relServDN,self.ServicesDN) # DN пользователей, относительно базового DN self.relUsersDN = self.addDN(self.relUsDN, self.relDN) # DN групп пользователей, относительно базового DN self.relGroupsDN = self.addDN(self.relGrDN, self.relDN) self.ldifFileBase =\ "/usr/lib/calculate/calculate-server/ldif/mail_base.ldif" self.ldifFileUser =\ "/usr/lib/calculate/calculate-server/ldif/mail_user.ldif" self.ldifFileGroup =\ "/usr/lib/calculate/calculate-server/ldif/mail_group.ldif" # Алгоритм шифрования пароля для Mail пользователя self.userCrypt = "{SSHA}" # Директория хранения писем if unixObj: # получаем объект сервиса Unix self.servUnixObj = unixObj else: # создаем объект сервиса Unix self.servUnixObj = servUnix() def searchGroupsMail(self, userGroups, printError=True): """Ищет список групп из списка userGroups в Mail сервисе Список групп может состоять из названий групп или их почтовых адресов Возвращает список названий групп """ userGroupNames = [] flagError = False searchEmailGroup = True searchNameGroup = True for userGroup in userGroups: if "@" in userGroup: searchEmailGroup = self.searchGroupToMail(userGroup) if not searchEmailGroup: flagError = True break userGroupNames.append(searchEmailGroup[0][0][1]['cn'][0]) else: searchNameGroup = self.searchMailGroupToName(userGroup) if not searchNameGroup: flagError = True break userGroupNames.append(userGroup) if flagError: if printError: if not searchEmailGroup: self.printERROR( _("Email address %s is not found in Mail service")%\ str(userGroup) + " ...") elif not searchNameGroup: self.printERROR( _("Group name %s is not found in Mail service")%\ str(userGroup) + " ...") return False return userGroupNames def delUserMailServer(self,userName,options,printSuccess=True,backup=True): """Удаляем Mail пользователя""" # Проверим установлен ли сервис mail if not self.isServiceSetup("mail"): return False # Ищем Mail пользователя resSearch = self.searchMailUserToName(userName) if not resSearch: self.printERROR (_("ERROR") + ": " +\ _("User %s is not found in Mail service") % str(userName) +\ " ...") return False #почтовая директория пользователя mailDir = os.path.join(self.clVars.Get("sr_mail_path"), userName) if options.has_key('r'): backup = False # Делаем сохранение данных удаляемого пользователя if backup and os.path.exists(mailDir) and os.listdir(mailDir): if not self.backupDelUser(userName, 'mail/imap', mailDir): return False #удаляем почту из Unix сервиса if not self.servUnixObj.deleteUserMail(userName): return False # Удаляем пользователя из групп if not self.delUserInGroup(userName): return False # Удаляем пользователя delDN = self.addDN("uid=" + userName, self.relUsersDN) if not self.delDN(delDN): return False # Удаляем почтовую папку if self.removeDir(mailDir): if printSuccess: self.printSUCCESS(\ _("Mail user directory %s is removed")% str(mailDir) +\ " ...") if printSuccess: self.printSUCCESS(_("Mail user %s is deleted")%userName +\ " ...") return True def searchMailGroupToName(self, groupName): """Находит группу сервиса Unix по её имени""" resSearch = self.searchLdapDN(groupName, self.relGroupsDN, "cn") return resSearch def searchMailGroup(self, nameOrMali): """Находит группу сервиса Mail по имени или email""" if "@" in nameOrMali: resSearch = self.searchGroupToMail(nameOrMali) else: resSearch = self.searchMailGroupToName(nameOrMali) return resSearch def searchMailMember(self, nameOrMail, printError=True): """Ищет группы сервиса Unix в котрых есть данный пользователь Поиск происходит по email или имени пользователя """ resSearchUser = self.searchMailUser(nameOrMail) if not resSearchUser: if printError: self.printERROR(\ _("Mail user or email %s are not found in Mail service")%\ str(nameOrMail) + " ...") return False userMail = resSearchUser[0][0][1]['mail'][0] resSearchGroup = self.searchLdapDN(userMail, self.relGroupsDN, "rfc822member") return (userMail, resSearchGroup) def delUserInGroup(self, userName): """Удаление из групп в которые входит пользователь""" resSearch = self.searchMailMember(userName) if not resSearch: return False userMail = resSearch[0] userInGroups = resSearch[1] modAttrs = [(ldap.MOD_DELETE, 'rfc822member', userMail)] flagError = False for group in userInGroups: groupName = group[0][1]['cn'][0] groupDN = self.addDN("cn=" + groupName, self.relGroupsDN) if not self.modAttrsDN(groupDN, modAttrs): flagError = True break if flagError: return False else: return True def delUsersGroupMail(self, users, groupName): """Удаление пользователей из списка из группы Mail""" res = self.searchMailGroupToName(groupName) if not res : self.printERROR(_("group name is not found in Mail service") +\ " ...") return False if not res[0][0][1].has_key("rfc822member"): self.printERROR(\ _("Member list of group %s is empty")%str(groupName)+" ...") return False memberMailUsers = res[0][0][1]["rfc822member"] flagError = False memberUsers = {} for mailUser in memberMailUsers: userName = mailUser.split("@")[0] memberUsers[userName] = mailUser for user in users: if not user in memberUsers.keys(): flagError = True break if flagError: self.printERROR(\ _("User %s is not found in group")%str(user)+" "+\ str(groupName) + " ...") return False modAttrs = [] for user in users: mailUser = memberUsers[user] modAttrs.append((ldap.MOD_DELETE, 'rfc822member', mailUser)) groupDN = self.addDN("cn="+groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) def delGroupMailServer(self, groupName, options): """Удаляет группу пользователей Mail""" # Проверим установлен ли сервис mail if not self.isServiceSetup("mail"): return False res = self.searchMailGroupToName(groupName) if not res: self.printERROR( _("Group %s is not found in Mail service")%groupName +\ " ...") return False delDN = self.addDN("cn="+groupName, self.relGroupsDN) res = self.delDN(delDN) if res: self.printSUCCESS( _("Mail group %s is deleted")%groupName + \ " ...") return True else: self.printERROR(_("Can not delete Mail group") +\ " " + groupName + " ...") return False def delAlternateAddress(self, userName): """Удаление альтернативных адресов пользователя""" res = self.searchMailUserToName(userName) if not res: return False if not res[0][0][1].has_key('mailAlternateAddress'): return True modAttrs = [(ldap.MOD_DELETE, 'mailAlternateAddress', None)] userDN = self.addDN("uid=" + userName, self.relUsersDN) if not self.modAttrsDN(userDN, modAttrs): return False return True def modGroupMailServer(self, groupName, options): """Модифицирует настройки группы пользователей Mail""" # Проверим установлен ли сервис mail if not self.isServiceSetup("mail"): return False searchGroup = self.searchMailGroupToName(groupName) if not searchGroup: self.printERROR(_("group name not found in Mail service") +" ...") return False # Добавляем список пользователей в группу if options.has_key('a'): # добавляемые пользователи в группу users = options['a'].split(',') res = self.addUsersGroupMail(users, groupName) if res: self.printSUCCESS(_("Appended list users to group") + " " +\ str(groupName) + " ...") else: self.printERROR(_("Can not append list users to group") +\ " " + str(groupName) + " ...") return False # Удаляем список пользователей из группы if options.has_key('d'): # удаляемые пользователи из группы users = options['d'].split(',') res = self.delUsersGroupMail(users, groupName) if res: self.printSUCCESS(_("Deleted list users from group") + " " +\ str(groupName) + " ...") else: self.printERROR(_("Can not delete list users from group") +\ " " + str(groupName) + " ...") return False # Изменяем имя группы attrDelete = [] attrAppend = [] modGroupName = groupName if options.has_key('n'): newGroupName = options['n'] if self.searchMailGroupToName(newGroupName): self.printERROR( _("group name %s is found in Mail service")%\ str(newGroupName) + " ...") return False # изменяем адрес и альтернативный адрес altEmails = searchGroup[0][0][1]["mailAlternateAddress"] for altEmail in altEmails: splAltEmail = altEmail.split("@") grName = splAltEmail[0] if groupName == grName: altEmailDomen = "" if len(splAltEmail)==2: altEmailDomen = splAltEmail[1] newAltEmail = "%s@%s" %(newGroupName,altEmailDomen) attrDelete.append( (ldap.MOD_DELETE, 'mailAlternateAddress', altEmail)) attrAppend.append( (ldap.MOD_ADD, 'mailAlternateAddress', newAltEmail)) break email = searchGroup[0][0][1]["mail"][0] splEmail = email.split("@") emailDomen = "" if len(splEmail)==2: emailDomen = splEmail[1] newEmail = "%s@%s" %(newGroupName,emailDomen) attrAppend.append((ldap.MOD_REPLACE, 'mail', newEmail)) attrAppend.append((ldap.MOD_REPLACE, 'mailMessageStore', newGroupName + "/")) newFirstDn = "cn=" + newGroupName oldDN = self.addDN("cn=" + groupName, self.relGroupsDN) res = self.modifyElemDN(oldDN, newFirstDn) if res: self.printSUCCESS(_("Group renamed") + " ...") modGroupName = newGroupName else: self.printERROR(_("Can not rename group") + "...") return False modAttrs = attrAppend + attrDelete # Изменяем коментарий к группе if options.has_key('c'): gecos = options['c'] modAttrs.append((ldap.MOD_REPLACE, 'description', gecos)) if modAttrs: groupDN = self.addDN("cn=" + modGroupName, self.relGroupsDN) res = self.modAttrsDN(groupDN, modAttrs) if res: if options.has_key('c'): self.printSUCCESS(_("Modified group comment") + " ...") return True else: if options.has_key('c'): self.printSUCCESS(_("Can not modify group comment") +\ " ...") return False return True def modUserMailServer(self, userName, options): """Модифицирует настройки пользователя Mail в LDAP""" # Проверим установлен ли сервис mail if not self.isServiceSetup("mail"): return False res = self.searchMailUserToName(userName) if not res: self.printERROR( _("User %s is not found in Mail service")%\ str(userName) + " ...") return False # Новые группы в которые входит пользователь if options.has_key('G'): userGroups = options['G'].split(',') #список имен добавляемых групп userGroupNames = self.searchGroupsMail(userGroups) if not userGroupNames: return False # Удаляем пользователя из групп в которые он входит if not self.delUserInGroup(userName): return False flagError = False for group in userGroupNames: if not self.addUsersGroupMail([userName], group): flagError = True break if flagError: return False self.printSUCCESS(_("Replaced list of supplementary group") +\ " ...") # Добавляем группы в которые входит пользователь elif options.has_key('a'): userGroups = options['a'].split(',') #список имен добавляемых групп userGroupNames = self.searchGroupsMail(userGroups) if not userGroupNames: return False flagError = False for group in userGroupNames: if not self.addUsersGroupMail([userName], group): flagError = True break if flagError: return False self.printSUCCESS(_("Appended list of supplementary group") +\ " ...") # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя if options.has_key('U'): modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "active")] # Выключаем пользователя elif options.has_key('L'): modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "passive")] # Изменяем коментарий к пользователю if options.has_key('c'): comment = options['c'] modAttrs += [(ldap.MOD_REPLACE, 'sn', comment), (ldap.MOD_REPLACE, 'cn', comment)] # Изменяем пароль пользователя userPwd = self.getUserPassword(options, "p", "P") if userPwd == False: return False if userPwd: userPwdHash = self.execProg("slappasswd -s %s -h %s"\ %(userPwd, self.userCrypt)) if res[0][0][1].has_key('userPassword'): modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) # Заменяем альтернативные почтовые адреса # Первичный почтовый адрес primaryMail = "" if options.has_key('e'): # Удаляем предыдущие адреса self.delAlternateAddress(userName) altMails = options['e'].split(",") for altMail in altMails: if "@" in altMail: mail = altMail else: mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host")) if not primaryMail: primaryMail = mail if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR(_("Alternate email address") + ": " +\ str(mail) + " " + _("is found in Mail service") +\ " ...") return False modAttrs.append((ldap.MOD_ADD, 'mailAlternateAddress', mail)) # Изменяем основной почтовый адрес if primaryMail: if not self.servUnixObj.setUserMail(userName, primaryMail): self.printERROR(_("Failed set primary email for user %s \ in Unix service ...") %str(primaryMail)) return False if modAttrs: DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if options.has_key('c'): self.printSUCCESS(_("Modified comment") + " ...") if options.has_key('L'): self.printSUCCESS(_("Locked Mail user %s")%str(userName) + " ...") if options.has_key('U'): self.printSUCCESS(_("Unlocked Mail user %s")%str(userName) + " ...") if options.has_key('e'): self.printSUCCESS(_("Modified Mail alternate addresses") +\ "...") if options.has_key('P') or options.has_key('p'): self.printSUCCESS(_("Modified Mail user password") + " ...") return True @adminConnectLdap def addGroupMailServer(self, groupName, options): """Добавляет группу пользователей Mail""" # Проверим установлен ли сервис mail if not self.isServiceSetup("mail"): return False #Проверяем альтернативные почтовые адреса modAttrs = [] if options.has_key('e'): altMails = options['e'].split(",") for altMail in altMails: if "@" in altMail: mail = altMail else: mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host")) if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR( _("Alternate email address %s is found in Mail service")%\ str(mail) + " ...") return False modAttrs.append('mailAlternateAddress: %s' %mail) if self.searchMailGroupToName(groupName): self.printERROR( _("group name %s is found in Mail service")%\ str(groupName) + " ...") return False mail = "%s@%s" %(groupName,self.clVars.Get("sr_mail_host")) if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR( _("Email address %s is found in Mail service")%\ str(mail) + " ...") return False self.clVars.Set("ur_group",groupName) # Комментарий к группе groupGecos = self.servUnixObj.groupGecos if options.has_key('c'): groupGecos = options['c'] self.clVars.Set("ur_group_comment",groupGecos) ldifFile = self.ldifFileGroup groupRawLdif = self.createLdif(ldifFile) if not groupRawLdif: print self.getError() return False groupLdif = groupRawLdif.rstrip() + "\n" + "\n".join(modAttrs) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(groupLdif) if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False self.printSUCCESS(_("Added group in Mail service") + " ...") return True def modUserMailPasswd(self, userName, options): """Устанавливает пароль Mail пользователя и меняет его опции""" # Проверим установлен ли сервис mail if not self.isServiceSetup("mail"): return False res = self.searchMailUserToName(userName) if not res: self.printERROR( _("User %s is not found in Mail service") % str(userName) +\ " ...") return False # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя if options.has_key('u'): modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "active")] # Выключаем пользователя elif options.has_key('l'): modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "passive")] if not options: optPasswd = {"p":""} userPwd = self.getUserPassword(optPasswd, "p", False) if userPwd == False: return False userPwdHash =\ self.execProg("slappasswd -s %s -h %s"\ %(userPwd, self.userCrypt)) if res[0][0][1].has_key('userPassword'): modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if options.has_key('l'): self.printSUCCESS(_("Locked Mail user %s")% str(userName)+\ " ...") if options.has_key('u'): self.printSUCCESS(_("Unlocked Mail user %s")% str(userName)+\ " ...") if not options: self.printSUCCESS(_("Changed Mail user password") + " ...") return True return False def searchUsersInGroupMail(self, usersNames, groupName): """Ищет спиcок пользователей в группе, ищет в LDAP В случае успеха выводит список найденных пользователей если нет группы False если ничего не найдено пустой список """ res = self.searchMailGroupToName(groupName) if not res: return False else: findUsers = [] if res[0][0][1].has_key('rfc822member'): usersInGroup = res[0][0][1]['rfc822member'] for userName in usersNames: userMail = "%s@%s" %(userName, self.clVars.Get("sr_mail_host")) if userMail in usersInGroup: findUsers.append(userName) return findUsers def searchMailUserToName(self, userName): """Находит пользователя сервиса Mail по имени""" resSearch = self.searchLdapDN(userName, self.relUsersDN, "uid") return resSearch def searchUserToMail(self, mail): """Находит пользователя по почтовому адресу в сервисе Mail""" resSearch = self.searchLdapDN(mail, self.relUsersDN, "mail") if not resSearch: resSearch = self.searchLdapDN(mail, self.relUsersDN, "mailAlternateAddress") return resSearch def searchMailUser(self, nameOrMali): """Находит пользователя сервиса Mail по имени или email""" if "@" in nameOrMali: resSearch = self.searchUserToMail(nameOrMali) else: resSearch = self.searchMailUserToName(nameOrMali) return resSearch def searchGroupToMail(self, mail): """Находит группу по ее почтовому адресу""" resSearch = self.searchLdapDN(mail, self.relGroupsDN, "mail") if not resSearch: resSearch = self.searchLdapDN(mail, self.relGroupsDN, "mailAlternateAddress") return resSearch def createMailDir(self, userName, uid, gid): """Создание пользовательской директории для почты""" def createCNT(mailDir, uid, gid): """создание cur, new, tmp в текущей директории""" appendDirs = ["cur","new","tmp"] flagError = False for appDir in appendDirs: createDir = os.path.join(mailDir, appDir) if not self.createUserDir(uid, gid, createDir, False): flagError = True break if flagError: return False return True mailDir = os.path.join(self.clVars.Get("sr_mail_path"), userName) flagError = False if not self.createUserDir(uid, gid, mailDir): flagError = True if not flagError and not createCNT(mailDir, uid, gid): flagError = True if not flagError: mailDirs = [os.path.join(mailDir,".Drafts"), os.path.join(mailDir,".Sent"), os.path.join(mailDir,".Spam"), os.path.join(mailDir,".Trash")] for createDir in mailDirs: if not self.createUserDir(uid, gid, createDir, False): flagError = True break if not createCNT(createDir, uid, gid): flagError = True break if flagError: return False return True def addUsersGroupMail(self, users, groupName): """Добавляет пользователей из списка в Mail группу""" # Проверим установлен ли сервис mail if not self.isServiceSetup("mail"): return False if not self.searchMailGroupToName(groupName): self.printERROR(_("Group name is not found in Mail service") +\ " ...") return False flagFalse = False for userName in users: if not self.searchMailUserToName(userName): self.printERROR( _("User %s is not found in Mail service")%\ str(userName) + " ...") flagFalse = True break if flagFalse: return False foundUsersMail = self.searchUsersInGroupMail(users, groupName) foundUsers = [] if foundUsersMail: foundUsers = foundUsersMail addUsers = [] for user in users: if not(user in foundUsers): addUsers.append(user) modAttrs = [] for userName in addUsers: userMail = "%s@%s" %(userName,self.clVars.Get("sr_mail_host")) modAttrs.append((ldap.MOD_ADD, 'rfc822member', userMail)) if modAttrs: groupDN = self.addDN("cn="+groupName, self.relGroupsDN) return self.modAttrsDN(groupDN, modAttrs) return True def delUserInMailAndUnix(self, userName, flagDelUnixUser): """Удаляет пользователя без бекапа Удаляет из Mail и если установлен флаг из Unix """ if not self.delUserMailServer(userName, {}, False,False): return False if flagDelUnixUser: if not self.servUnixObj.delUserUnixServer(userName, {}, False, False): return False return True @adminConnectLdap def addUserMailServer(self, userName, options): """Добавляет почтового пользователя в LDAP-сервер""" # Проверим установлен ли сервис mail if not self.isServiceSetup("mail"): return False #Проверяем альтернативные почтовые адреса modAttrs = [] primaryMail = "" if options.has_key('e'): altMails = options['e'].split(",") for altMail in altMails: if "@" in altMail: mail = altMail else: mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host")) if not primaryMail: primaryMail = mail if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR( _("Alternate email address %s is found in Mail service")%\ str(mail) + " ...") return False modAttrs.append("mailAlternateAddress: %s" %mail) else: self.printERROR(\ _("Must be added one or more alternative addresses")) self.printWARNING("cl-useradd -e gst@calculate.org guest mail") return False if self.searchMailUserToName(userName): self.printERROR(_("User exists in Mail service")) return False else: mail = "%s@%s" %(userName,self.clVars.Get("sr_mail_host")) if self.searchUserToMail(mail) or\ self.searchGroupToMail(mail): self.printERROR( _("Email address %s is found in Mail service")%\ str(mail) + " ...") return False resUnix = self.servUnixObj.searchUnixUser(userName) resPwd = self.servUnixObj.searchPasswdUser(userName) # Пароль пользователя почты userPwd = self.getUserPassword(options, "p", "P") if userPwd == False: return False flagCreateUnixUser = False if not (resUnix or resPwd): flagCreateUnixUser = True # Добавим пользователя LDAP optUnix = {} # Группа пользователя if options.has_key('g'): optUnix['g'] = options['g'] # Полное имя пользователя if options.has_key('c'): optUnix['c'] = options['c'] if not self.servUnixObj.addUserUnixServer(userName, optUnix, False): self.printERROR (_("Can not added user")+ " " +\ str(userName) + _(" in Unix service")) return False resUnix = self.servUnixObj.searchUnixUser(userName) self.clVars.Set("ur_name", userName) #Полное имя пользователя fullNameUser = self.servUnixObj.fullNameUser if options.has_key('c'): fullNameUser = options['c'] else: if resUnix and resUnix[0][0][1].has_key('cn'): fullNameUser = resUnix[0][0][1]['cn'][0] self.clVars.Set("ur_fio",fullNameUser) if not userPwd: userPwdHash = "crypt{xxx}" else: userPwdHash =\ self.execProg("slappasswd -s %s -h %s" %(userPwd,self.userCrypt)) if not userPwdHash: self.printERROR(_("ERROR") + ": " +\ _("create crypto password")) if flagCreateUnixUser: self.servUnixObj.delUserUnixServer(userName, {}, False, False) return False self.clVars.Set("ur_hash",userPwdHash) ldifFile = self.ldifFileUser userRawLdif = self.createLdif(ldifFile) if not userRawLdif: print self.getError() if flagCreateUnixUser: self.servUnixObj.delUserUnixServer(userName, {}, False, False) return False userLdif = userRawLdif.rstrip() + "\n" + "\n".join(modAttrs) if not self.ldapObj.getError(): #Добавляем пользователя в LDAP self.ldapObj.ldapAdd(userLdif) #ldapObj.ldapAdd(userLdif1) # не переделывать на else flagError = False if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() flagError = True if not flagError: if resUnix: uid = int(resUnix[0][0][1]['uidNumber'][0]) gid = int(resUnix[0][0][1]['gidNumber'][0]) elif resPwd: uid = int(resPwd.split(":")[2]) gid = int(resPwd.split(":")[3]) else: self.printERROR(_("user are not found")) flagError = True if not flagError: # Востановим удаленного пользователя # Почтовая директория пользователя mailDir = os.path.join(self.clVars.Get("sr_mail_path"), userName) message = _("Restored deleted user %s data")% userName + "\n" +\ _("'yes', 'no'") resMailDir = self.restorePathDelUser(userName, mailDir, "mail/imap", message) removeMailDirBack = False if not resMailDir: flagError = True createDirMail = False else: term, createDirMail, removeMailDirBack = resMailDir # Создаем почтовую директорию if not flagError and createDirMail: if not self.createMailDir(userName, uid, gid): flagError = True # Записываем основной почтовый адрес if not flagError and primaryMail: if not self.servUnixObj.setUserMail(userName, primaryMail): self.printERROR(_("Failed set primary email for user %s in\ Unix service ...") %str(primaryMail)) flagError = True if not flagError and removeMailDirBack\ and os.path.exists(removeMailDirBack): self.removeDir(removeMailDirBack) self.removeEmptyDir(os.path.split(removeMailDirBack)[0]) if flagError: self.delUserInMailAndUnix(userName, flagCreateUnixUser) self.printERROR(_("Can not add user") + " ...") return False if flagCreateUnixUser: self.printSUCCESS(_("Added user in Unix service") + " ...") self.printSUCCESS(_("Added user in Mail service") + " ...") return True def setupMailServer(self, options): """Начальная настройка Mail сервиса""" # Принудительная установка forceOptions = False if options.has_key("f"): forceOptions = True # Создаем объект переменных self.createClVars() #self.clVars.printVars() #return True if self.clVars.Get("sr_unix_set") != "on": self.printERROR(_("Unix service is not setuped")) self.printWARNING(_("Setup Unix service")) self.printWARNING(" cl-setup unix") return False # В случае если сервер установлен if self.clVars.Get("sr_mail_set") == "on" and\ not forceOptions: self.printWARNING (_("WARNING") + ": " +\ _("Mail server is configured")+ ".") return True if not forceOptions: # предупреждение при выполнении этой программы будут изменены # конфигурационные файлы сервиса Mail (программы Postfix и Dovecot) self.printWARNING (_("WARNING") + ": " + _("Executing of the program will change") + " " + _("the configuration files of Mail service") +" ("+ _("programs Postfix and Dovecot") + ")." ) # если вы готовы продолжить работу программы нажмите Y если нет n messDialog = \ _("If you are ready to continue executing the program") + ", "+\ _("input 'yes'") +", "+ _("if not 'no'") if not self.dialogYesNo(messDialog): return True else: # делаем backup # Проверим запущен ли ldap if not self.getRunService("ldap"): # Запускаем LDAP сервер if not self.runLdapServer(): return False bakupObj = servLdap() bakupObj.backupServer() # Удаляем из автозапуска демона if not self.delDaemonAutostart("postfix"): return False # Удаляем из автозапуска демона if not self.delDaemonAutostart("dovecot"): return False # останавливаем сервис Mail if not self.stopServices(["mail"]): return False # Имя устанавливаемого сервиса self.clVars.Set("cl_pass_service","mail") self.clVars.Write("sr_mail_set","off") # Почтовый ност if options.has_key("mail-host"): fullHostName = options['mail-host'] else: fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'), self.clVars.Get('os_net_domain')) self.clVars.Set("sr_mail_host",fullHostName,True) if not self.applyProfilesFromService('mail'): return False # Проверим запущен ли ldap if not self.getRunService("ldap"): # Запускаем LDAP сервер if not self.runLdapServer(): return False else: if not self.restartLdapServer(): return False # Подключаемся к LDAP cерверу if not shareLdap.getLdapObjInFile(self): return False # Находим в LDAP Mail сервис resSearch = self.searchService() ret = True if resSearch: delDN = self.relDN ret = self.deleteDN(delDN) if ret: self.printOK(_("Remove Mail DN from LDAP Database") +" ...") else: self.printERROR(\ _("Can not remove Mail DN from LDAP Database")+\ " ...") if not ret: return False ldifFile = self.ldifFileBase baseLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False # Записываем данные администратора сервиса Mail ldapParser = iniLdapParser() ldapParser.setVar("mail", {"DN":self.clVars.Get("ld_mail_dn"), "PASS":self.clVars.Get("ld_mail_pw")}) self.printOK(_("Added ldif file") +" ...") textLine = self.execProg("newaliases") if not (textLine == None): self.printERROR(_("Can not create Postfix aliases") + " ...") return False textLine = self.execProg("/etc/init.d/postfix start") if "ok" in textLine: self.printOK(_("Starting") + " " + "Postfix" + " ...") else: self.printNotOK(_("Starting") + " " + "Postfix" + " ...") return False textLine = self.execProg("/etc/init.d/dovecot start") if "ok" in textLine: self.printOK(_("Starting") + " " + "Dovecot" + " ...") else: self.printNotOK(_("Starting") + " " + "Dovecot" + " ...") return False # Устанавливаем автозапуск демона if not self.setDaemonAutostart("postfix"): return False # Устанавливаем автозапуск демона if not self.setDaemonAutostart("dovecot"): return False #запишем переменные для сервера mailHost = self.clVars.Get("sr_mail_host") self.clVars.Write("sr_mail_host",mailHost,True,"local") #запишем переменные для клиента self.clVars.Set("sr_mail_send_host",fullHostName) clientVars = ["sr_mail_host","sr_mail_crypt", "sr_mail_port", "sr_mail_type","sr_mail_send_crypt","sr_mail_send_port", "sr_mail_send_host"] if not self.saveVarsClient(clientVars): return False self.clVars.Write("sr_mail_set","on") self.printOK(_("Mail service configured") + " ...") return True class servJabber(shareLdap): """Методы сервиса Jabber""" def __init__(self, unixObj=False): shareLdap.__init__(self) self.relGrDN = 'ou=Groups' self.relUsDN = 'ou=Users' self.relServDN = 'ou=Jabber' # DN сервиса self.relDN = self.addDN(self.relServDN,self.ServicesDN) # DN пользователей, относительно базового DN self.relUsersDN = self.addDN(self.relUsDN, self.relDN) # DN групп пользователей, относительно базового DN self.relGroupsDN = self.addDN(self.relGrDN, self.relDN) self.ldifFileBase =\ "/usr/lib/calculate/calculate-server/ldif/jabber_base.ldif" self.ldifFileUser =\ "/usr/lib/calculate/calculate-server/ldif/jabber_user.ldif" self.ldifFileGroup =\ "/usr/lib/calculate/calculate-server/ldif/jabber_group.ldif" if unixObj: # получаем объект сервиса Unix self.servUnixObj = unixObj else: # создаем объект сервиса Unix self.servUnixObj = servUnix() def searchGroupToName(self, groupName): """Находит группу сервиса Jabber по её имени""" resSearch = self.searchLdapDN(groupName, self.relGroupsDN, "cn") return resSearch def searchUserToId(self, jabberId): """Находит пользователя по Jabber ID в сервисе Jabber""" resSearch = self.searchLdapDN(jabberId, self.relUsersDN, "mail") return resSearch def searchUserToName(self, name): """Находит пользователя по имени в сервисе Jabber""" resSearch = self.searchLdapDN(name, self.relUsersDN, "uid") return resSearch def searchUsersToGroup(self, descr): """Находит пользователей по description""" resSearch = self.searchLdapDN(descr, self.relUsersDN, "departmentNumber") return resSearch def searchUserToNameOrId(self, nameOrId): """Находит пользователя сервиса Jabber по имени или id""" resSearch = self.searchUserToName(nameOrId) if resSearch: return resSearch resSearch = self.searchUserToId(nameOrId) return resSearch def setUserGroup(self, userName, groupName, userS=False, groupS=False): """Устанавливает Jabber группу для пользователя""" if groupS: groupSearch = groupS else: groupSearch = self.searchGroupToName(groupName) if not groupSearch: self.printERROR(_("Group name is not found in Jabber service") +\ " ...") return False if userS: userSearch = userS else: userSearch = self.searchUserToNameOrId(userName) if not userSearch: self.printERROR(_("User %s is not found in Jabber service")%\ str(userName) + " ...") return False modAttrs = [] descr = groupSearch[0][0][1]["cn"][0] uid = userSearch[0][0][1]["uid"][0] if userSearch[0][0][1].has_key('departmentNumber'): modAttrs.append((ldap.MOD_REPLACE, 'departmentNumber', descr)) else: modAttrs.append((ldap.MOD_ADD, 'departmentNumber', descr)) userDN = self.addDN("uid="+uid, self.relUsersDN) return self.modAttrsDN(userDN, modAttrs) def addUsersGroupJabber(self, users, groupName, replaceFlag=False): """Добавляет пользователей из списка в Jabber группу""" groupSearch = self.searchGroupToName(groupName) if not groupSearch: self.printERROR(_("Group name is not found in Jabber service") +\ " ...") return False flagFalse = False for userName in users: userSearch = self.searchUserToNameOrId(userName) if not userSearch: self.printERROR(_("User %s is not found in Jabber service")%\ str(userName) + " ...") flagFalse = True break if not replaceFlag and\ userSearch[0][0][1].has_key('departmentNumber'): self.printERROR(_("User %s is found in group")%\ str(userName) + " " + str(groupName) + " ...") flagFalse = True break if flagFalse: return False for userName in users: if not self.setUserGroup(userName, groupName): flagFalse = True break if flagFalse: return False return True def delUsersGroupJabber(self, users, groupName): """Удаляет пользователей из списка в Jabber группе""" groupSearch = self.searchGroupToName(groupName) if not groupSearch: self.printERROR(_("Group name is not found in Jabber service") +\ " ...") return False flagFalse = False res = True for userName in users: userSearch = self.searchUserToNameOrId(userName) if userSearch[0][0][1].has_key('departmentNumber'): if not userSearch[0][0][1]['departmentNumber'][0] == \ groupSearch[0][0][1]['cn'][0]: self.printERROR(_("User %s is not found in group")%\ str(userName) + " " + str(groupName) + " ...") res = False break else: self.printERROR(_("User %s is not a member of any group")%\ str(userName) + " ...") res = False break if not res: return False for userName in users: userSearch = self.searchUserToNameOrId(userName) uid = userSearch[0][0][1]['uid'][0] modAttrs = [(ldap.MOD_DELETE, 'departmentNumber', None)] userDN = self.addDN("uid="+uid, self.relUsersDN) res = self.modAttrsDN(userDN, modAttrs) if not res: break return res def renameGroup(self, oldName, newName): """Изменяет имя группы""" searchOldGroup = self.searchGroupToName(oldName) if not searchOldGroup: self.printERROR(\ _("Old group name %s not found in Jabber service")%str(oldName)+\ " ...") return False searchNewGroup = self.searchGroupToName(newName) if searchNewGroup: self.printERROR(\ _("New group name %s found in Jabber service")%str(newName)+\ " ...") return False groupDN = self.addDN("cn="+oldName, self.relGroupsDN) searchUsers = self.searchUsersToGroup(oldName) if searchUsers: flagError = False for data in searchUsers: uid = data[0][1]['uid'][0] userDN = self.addDN("uid="+uid, self.relUsersDN) modAttrs = [(ldap.MOD_REPLACE, 'departmentNumber', newName)] res = self.modAttrsDN(userDN, modAttrs) if not res: flagError = True break if flagError: return False newFirstDn = "cn=" + newName oldDN = groupDN res = self.modifyElemDN(oldDN, newFirstDn) return res def modUserJabberPasswd(self, userName, options): """Устанавливает пароль Jabber пользователя и меняет его опции""" # Проверим установлен ли сервис jabber if not self.isServiceSetup("jabber"): return False resSearch = self.searchUserToNameOrId(userName) if not resSearch: self.printERROR( _("User %s is not found in Jabber service") % str(userName) +\ " ...") return False # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя if options.has_key('u'): modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] # Выключаем пользователя elif options.has_key('l'): modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] if not options: optPasswd = {"p":""} userPwd = self.getUserPassword(optPasswd, "p", False) if userPwd == False: return False userPwdHash = userPwd if resSearch[0][0][1].has_key('userPassword'): modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: uid = resSearch[0][0][1]['uid'][0] DN = self.addDN("uid="+userName, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if options.has_key('l'): self.printSUCCESS(_("Locked Jabber user %s")% str(userName)+\ " ...") if options.has_key('u'): self.printSUCCESS(_("Unlocked Jabber user %s")%\ str(userName)+ " ...") if not options: self.printSUCCESS(_("Changed Jabber user password") + " ...") return True return False def modUserJabberServer(self, userName, options): """Модифицирует настройки пользователя Jabber в LDAP""" # Проверим установлен ли сервис jabber if not self.isServiceSetup("jabber"): return False res = self.searchUserToNameOrId(userName) if not res: self.printERROR( _("User %s is not found in Jabber service")%\ str(userName) + " ...") return False # Изменяет группу в которую входит пользователь if options.has_key('g'): userGroup = options['g'] if self.setUserGroup(userName, userGroup, res): self.printSUCCESS(_("Replaced user group") + " ...") else: self.printERROR(_("Not replaced user group") + " ...") return False #загружаем картинку if options.has_key('i'): photoFile = options['i'] if not self.setJpegPhotoUser(userName, photoFile): self.printERROR(_("Not added jpeg photo for user") + " " +\ str(userName)) return False # Изменяемые аттрибуты пользователя modAttrs = [] # Включаем пользователя if options.has_key('U'): modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")] # Выключаем пользователя elif options.has_key('L'): modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")] # Изменяем коментарий к пользователю if options.has_key('c'): comment = options['c'] modAttrs += [(ldap.MOD_REPLACE, 'sn', comment), (ldap.MOD_REPLACE, 'cn', comment)] # Изменяем пароль пользователя userPwd = self.getUserPassword(options, "p", "P") if userPwd == False: return False if userPwd: userPwdHash = userPwd if res[0][0][1].has_key('userPassword'): modAttrs.append((ldap.MOD_REPLACE, 'userPassword', userPwdHash)) else: modAttrs.append((ldap.MOD_ADD, 'userPassword', userPwdHash)) if modAttrs: uid = res[0][0][1]['uid'][0] DN = self.addDN("uid="+uid, self.relUsersDN) if not self.modAttrsDN(DN, modAttrs): return False if options.has_key('c'): self.printSUCCESS(_("Modified comment (full name)") + " ...") if options.has_key('L'): self.printSUCCESS(_("Locked Jabber user %s")%str(userName) + " ...") if options.has_key('U'): self.printSUCCESS(_("Unlocked Jabber user %s")%str(userName) + " ...") if options.has_key('P') or options.has_key('p'): self.printSUCCESS(_("Modified Jabber user password") + " ...") if options.has_key('i'): self.printSUCCESS(_("Set image %s for Jabber user")%\ str(options['i']) + " " + str(userName) + " ...") return True def modGroupJabberServer(self, groupName, options): """Модифицирует настройки группы пользователей Jabber""" # Проверим установлен ли сервис jabber if not self.isServiceSetup("jabber"): return False searchGroup = self.searchGroupToName(groupName) if not searchGroup: self.printERROR(_("Group name %s is not found in Jabber service")\ %str(groupName) + " ...") return False # Добавляем список пользователей в группу if options.has_key('a'): # добавляемые пользователи в группу users = options['a'].split(',') res = self.addUsersGroupJabber(users, groupName) if res: self.printSUCCESS(_("Appended list users to group") + " " +\ str(groupName) + " ...") else: self.printERROR(_("Can not append list users to group") +\ " " + str(groupName) + " ...") return False # Удаляем список пользователей из группы if options.has_key('d'): # удаляемые пользователи из группы users = options['d'].split(',') res = self.delUsersGroupJabber(users, groupName) if res: self.printSUCCESS(_("Deleted list users from group") + " " +\ str(groupName) + " ...") else: self.printERROR(_("Can not delete list users from group") +\ " " + str(groupName) + " ...") return False # Изменяем коментарий к группе if options.has_key('c'): gecos = options['c'] modAttrs = [(ldap.MOD_REPLACE, 'description', gecos)] groupDN = self.addDN("cn="+groupName, self.relGroupsDN) if self.modAttrsDN(groupDN, modAttrs): self.printSUCCESS(_("Modified group comment") + " ...") else: self.printERROR(_("Can not modify comment group") +\ " " + str(groupName) + " ...") return False # Изменяем имя группы if options.has_key('n'): newGroupName = options['n'] oldGroupName = searchGroup[0][0][1]["cn"][0] if self.renameGroup(oldGroupName, newGroupName): self.printSUCCESS(_("Group renamed") + " ...") else: self.printERROR(_("Can not rename group") +\ " " + str(groupName) + " ...") return False return True def delUserJabberServer(self, userName, options, printSuccess=True): """Удаляем Jabber пользователя""" # Проверим установлен ли сервис jabber if not self.isServiceSetup("jabber"): return False # Ищем Jabber пользователя resSearch = self.searchUserToNameOrId(userName) if not resSearch: self.printERROR (_("ERROR") + ": " +\ _("User %s is not found in Jabber service") % str(userName) +\ " ...") return False uid = resSearch[0][0][1]['uid'][0] # Удаляем пользователя delDN = self.addDN("uid=" + uid, self.relUsersDN) if not self.delDN(delDN): self.printERROR(_("Jabber user %s is not deleted")%userName +\ " ...") return False if printSuccess: self.printSUCCESS(_("Jabber user %s is deleted")%userName +\ " ...") return True def delGroupJabberServer(self, groupName, options): """Удаляет группу пользователей Jabber""" # Проверим установлен ли сервис jabber if not self.isServiceSetup("jabber"): return False res = self.searchGroupToName(groupName) if not res: self.printERROR( _("Group %s is not found in Jabber service")%groupName +\ " ...") return False users = [] flagError = False searchUsers = self.searchUsersToGroup(groupName) if searchUsers: for data in searchUsers: users.append(data[0][1]['uid'][0]) if not self.delUsersGroupJabber(users, groupName): flagError = True if not flagError: delDN = self.addDN("cn="+groupName, self.relGroupsDN) res = self.delDN(delDN) if not res: flagError = True if flagError: self.printERROR(_("Can not delete Jabber group") +\ " " + groupName + " ...") return False else: self.printSUCCESS( _("Jabber group %s is deleted")%groupName +\ " ...") return True @adminConnectLdap def addGroupJabberServer(self, groupName, options): """Добавляет группу пользователей Jabber""" # Проверим установлен ли сервис jabber if not self.isServiceSetup("jabber"): return False # Если группа существует выходим без ошибки if self.searchGroupToName(groupName): self.printERROR(\ _("group name %s is found in Jabber service") %\ str(groupName) + " ...") return False self.clVars.Set("ur_group",groupName) # Комментарий к группе groupGecos = self.servUnixObj.groupGecos if options.has_key('c'): groupGecos = options['c'] self.clVars.Set("ur_group_comment",groupGecos) ldifFile = self.ldifFileGroup groupLdif = self.createLdif(ldifFile) if not groupLdif: print self.getError() return False if not self.ldapObj.getError(): self.ldapObj.ldapAdd(groupLdif) if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False self.printSUCCESS(_("Added group in Jabber service") + " ...") return True @adminConnectLdap def addUserJabberServer(self, userName, options, checkSetup=True): """Добавляет jabber пользователя""" # Проверим установлен ли сервис jabber if checkSetup and not self.isServiceSetup("jabber"): return False #jabber id jabberId = "%s@%s" %(userName,self.clVars.Get("sr_jabber_host")) if self.searchUserToId(jabberId): self.printERROR(_("User exists in Jabber service")) return False # Пароль пользователя Jabber userPwd = self.getUserPassword(options, "p", "P") if userPwd == False: return False if not userPwd: userPwd = "crypt{xxx}" self.clVars.Set("ur_hash",userPwd) self.clVars.Set("ur_name", userName) #Полное имя пользователя fullNameUser = self.servUnixObj.fullNameUser if options.has_key('c'): fullNameUser = options['c'] else: if self.isServiceSetup("unix"): # Cоздаем обеъкт сервиса Unix servUnixObj = servUnix() resUnix = servUnixObj.searchUnixUser(userName) # Берем комментарий для пользователя из Unix if resUnix and resUnix[0][0][1].has_key('cn'): fullNameUser = resUnix[0][0][1]['cn'][0] self.clVars.Set("ur_fio",fullNameUser) ldifFile = self.ldifFileUser userLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): #Добавляем пользователя в LDAP self.ldapObj.ldapAdd(userLdif) #ldapObj.ldapAdd(userLdif1) # не переделывать на else if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False #загружаем картинку if options.has_key('i'): photoFile = options['i'] if not self.setJpegPhotoUser(userName, photoFile): self.printERROR(_("Not added jpeg photo for user") + " " +\ str(userName)) self.delUserJabberServer(userName, options, False) return False self.printSUCCESS(_("Added user in Jabber service") + " ...") return True def setupJabberServer(self, options): """Начальная настройка Jabber сервиса""" # Принудительная установка forceOptions = False if options.has_key("f"): forceOptions = True # Создаем объект переменных self.createClVars() #self.clVars.printVars() #return True if self.clVars.Get("sr_ldap_set") != "on": self.printERROR(_("LDAP service is not setuped")) self.printWARNING(_("Setup LDAP service")) self.printWARNING(" cl-setup ldap") return False # В случае если сервер установлен if self.clVars.Get("sr_jabber_set") == "on" and\ not forceOptions: self.printWARNING (_("WARNING") + ": " +\ _("Jabber server is configured")+ ".") return True if not forceOptions: # предупреждение при выполнении этой программы будут изменены # конфигурационные файлы сервиса Mail (программы Postfix и Dovecot) self.printWARNING (_("WARNING") + ": " + _("Executing of the program will change") + " " + _("the configuration files of Jabber service") +" ("+ _("program Ejabberd") + ")." ) # если вы готовы продолжить работу программы нажмите Y если нет n messDialog = \ _("If you are ready to continue executing the program") + ", "+\ _("input 'yes'") +", "+ _("if not 'no'") if not self.dialogYesNo(messDialog): return True else: # делаем backup # Проверим запущен ли ldap if not self.getRunService("ldap"): # Запускаем LDAP сервер if not self.runLdapServer(): return False bakupObj = servLdap() bakupObj.backupServer() # Удаляем из автозапуска демона if not self.delDaemonAutostart("ejabberd"): return False # останавливаем сервис Jabber if not self.stopServices(["jabber"]): return False # Имя устанавливаемого сервиса self.clVars.Set("cl_pass_service","jabber") self.clVars.Write("sr_jabber_set","off") if options.has_key("jabber-host"): fullHostName = options['jabber-host'] else: fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'), self.clVars.Get('os_net_domain')) self.clVars.Set("sr_jabber_host",fullHostName,True) # Cоздаем объект профиль устанавливая директорию jabber для # файлов профилей if not self.applyProfilesFromService('jabber'): return False # Проверим запущен ли ldap if not self.getRunService("ldap"): # Запускаем LDAP сервер if not self.runLdapServer(): return False else: if not self.restartLdapServer(): return False # Подключаемся к LDAP cерверу if not shareLdap.getLdapObjInFile(self): return False # Находим в LDAP Jabber сервис resSearch = self.searchService() ret = True if resSearch: delDN = self.relDN ret = self.deleteDN(delDN) if ret: self.printOK(_("Remove Jabber DN from LDAP Database") +" ...") else: self.printERROR(\ _("Can not remove Jabber DN from LDAP Database")+\ " ...") if not ret: return False ldifFile = self.ldifFileBase baseLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False # Администратор сервиса adminName = "admin" adminFullName = "%s@%s" %(adminName, self.clVars.Get("sr_jabber_host")) print _("Enter the %s password" % adminFullName) if not self.addUserJabberServer(adminName,{'p':""}, False): return False # Записываем данные администратора сервиса Jabber ldapParser = iniLdapParser() ldapParser.setVar("jabber", {"DN":self.clVars.Get("ld_jabber_dn"), "PASS":self.clVars.Get("ld_jabber_pw")}) self.printOK(_("Added ldif file") +" ...") # создаем сертификат если есть используем прежний self.execProg("/bin/bash /etc/jabber/self-cert.sh") if not os.path.exists("/etc/jabber/ssl.pem"): self.printERROR(_("Can not create Jabber certificate") + " ...") return False textLine = self.execProg("/etc/init.d/ejabberd start") if "ok" in textLine: self.printOK(_("Starting") + " " + "Ejabberd" + " ...") else: self.printNotOK(_("Starting") + " " + "Ejabberd" + " ...") return False # Устанавливаем автозапуск демона if not self.setDaemonAutostart("ejabberd"): return False #запишем переменные для сервера jabberHost = self.clVars.Get("sr_jabber_host") self.clVars.Write("sr_jabber_host",jabberHost,True,"local") #запишем переменные для клиента clientVars = ["sr_jabber_host","sr_jabber_crypt","sr_jabber_port"] if not self.saveVarsClient(clientVars): return False self.clVars.Write("sr_jabber_set","on") self.printOK(_("Jabber service configured") + " ...") return True class servSamba(shareLdap): """Методы севисa Samba""" def __init__(self, unixObj=False): shareLdap.__init__(self) self.relGrDN = 'ou=Groups' self.relUsDN = 'ou=Users' self.relCsDN = 'ou=Computers' self.relServDN = 'ou=Samba' self.relDN = self.addDN(self.relServDN,self.ServicesDN) # DN пользователей, относительно базового DN self.relUsersDN = self.addDN(self.relUsDN, self.relDN) # DN групп пользователей, относительно базового DN self.relGroupsDN = self.addDN(self.relGrDN, self.relDN) # DN, компьютеров относительно базового DN self.relComputersDN = self.addDN(self.relCsDN, self.relDN) self.ldifFileBase =\ "/usr/lib/calculate/calculate-server/ldif/samba_base.ldif" if unixObj: # получаем объект сервиса Unix self.servUnixObj = unixObj else: # создаем объект сервиса Unix self.servUnixObj = servUnix(self) def getLdapObjInFile(self): """Cоединение с LDAP администратором Samba сервиса""" return shareLdap.getLdapObjInFile(self, "samba") def delUserSambaServer(self,userName,options,printSuccess=True, backup=True, notDeletedDirs=[]): """Удаляем Samba пользователя""" # Проверим установлен ли сервис samba if not self.isServiceSetup("samba"): return False if "$" in userName: # удаляемая машина delUser = userName.replace('$','') + "$" if not self.searchSambaMachine(delUser): self.printERROR (_("ERROR") + ": " +\ _("Samba machine %s is not found in Samba service")%\ str(delUser)) return False else: # удаляемый пользователь delUser = userName if not self.searchSambaUser(delUser): self.printERROR (_("ERROR") + ": " +\ _("Samba user %s is not found in Samba service") %\ str(delUser)) return False winProfDir =\ os.path.join(self.clVars.Get("sr_samba_winprof_path"), userName) linProfDir =\ os.path.join(self.clVars.Get("sr_samba_linprof_path"), userName) userHomeDir =\ os.path.join(self.clVars.Get("sr_samba_home_path"), userName) userNetlogonDir =\ os.path.join(self.clVars.Get("sr_samba_winlogon_path"), userName) if options.has_key('r'): backup = False # Делаем сохранение данных удаляемого пользователя if backup: if os.path.exists(winProfDir) and os.listdir(winProfDir): if not self.backupDelUser(userName, 'samba/winprofile', winProfDir): return False if os.path.exists(linProfDir) and os.listdir(linProfDir): if not self.backupDelUser(userName, 'samba/linprofile', linProfDir): return False if os.path.exists(userHomeDir)and os.listdir(userHomeDir): if not self.backupDelUser(userName, 'samba/home', userHomeDir): return False if os.path.exists(userNetlogonDir) and os.listdir(userNetlogonDir): if not self.backupDelUser(userName, 'samba/netlogon', winProfDir): return False textLine = self.execProg("smbpasswd -x %s" %(delUser), False, False) flagError = False if textLine: if type(textLine) == types.ListType: listLine = [] for line in textLine: listLine.append(line.rstrip()) textLine = " ".join(listLine) else: flagError = True if not "Deleted user %s" %(delUser) in textLine: flagError = True if flagError: self.printERROR(_("ERROR") + ": " +\ _("Can not delete Samba user") + " " + str(delUser) + " ...") return False else: # Удаляем win профиль if not winProfDir in notDeletedDirs and\ os.path.exists(winProfDir): self.removeDir(winProfDir) # Удаляем lin профиль if not linProfDir in notDeletedDirs and\ os.path.exists(linProfDir): self.removeDir(linProfDir) # Удаляем домашнюю директорию if not userHomeDir in notDeletedDirs and\ os.path.exists(userHomeDir): self.removeDir(userHomeDir) # Удаляем netlogon if not userNetlogonDir in notDeletedDirs and\ os.path.exists(userNetlogonDir): self.removeDir(userNetlogonDir) if not self.servUnixObj.modUserUnixServer(userName,{"I":""},False): return False if printSuccess: self.printSUCCESS(_("Deleted Samba user %s") % str(delUser) +\ " ...") return True @adminConnectLdap def addUserSambaServer(self,userName,options,pwDialog=False, checkSetup=True): """Добавляет LDAP пользователя в LDAP-сервер""" # Проверим установлен ли сервис samba if checkSetup and not self.isServiceSetup("samba"): return False # Добавление машины samba if options.has_key('w'): if self.addMachineSambaServer(userName, options): return True else: return False resSearch = self.servUnixObj.searchUnixUser(userName) flagFoundPasswd = False if not resSearch: resSearch = self.servUnixObj.searchPasswdUser(userName) flagFoundPasswd = True ## создание пользователя Unix опция f #if not resSearch and not options.has_key('f'): #self.printERROR( #_("User %s is not found in Unix service")%\ #str(userName) + " ...") #return False if self.searchSambaUser(userName): self.printERROR(_("Samba user exists")) return False #пароль пользователя userPwd = "" #диалог ввода пароля if not pwDialog: pwDialog = [_("New SMB password"), _("Retype new SMB password")] userPwd = self.getUserPassword(options, "p", "P", pwDialog) if userPwd == False: return False flagCreateUnixUser = False if not resSearch: # Добавим пользователя LDAP optUnix = {} # id пользователя if options.has_key('u'): optUnix['u'] = options['u'] # Группа пользователя if options.has_key('g'): optUnix['g'] = options['g'] # Группы в которые входит пользователь if options.has_key('G'): optUnix['G'] = options['G'] # Полное имя пользователя if options.has_key('c'): optUnix['c'] = options['c'] # Cделаем пользователя видимым optUnix['v'] = "" if not self.servUnixObj.addUserUnixServer(userName, optUnix, False,userPwd): self.printERROR (_("Can not added user")+ " " +\ str(userName) + _(" in Unix service")) return False flagCreateUnixUser = True elif userPwd and not flagFoundPasswd: if not self.servUnixObj.modUserUnixPasswd(userName, {}, userPwd): return False elif not flagFoundPasswd: if not self.servUnixObj.modUserUnixServer(userName,{"V":""},False): return False if userPwd: textLine = self.execProg("smbpasswd -a -s %s" %(userName), "%s\n%s\n" %(userPwd,userPwd)) else: textLine = self.execProg("smbpasswd -a -n %s" %(userName)) if "Added" in str(textLine): flagError = False winProfDir =\ os.path.join(self.clVars.Get("sr_samba_winprof_path"), userName) linProfDir =\ os.path.join(self.clVars.Get("sr_samba_linprof_path"), userName) userHomeDir =\ os.path.join(self.clVars.Get("sr_samba_home_path"), userName) userNetlogonDir =\ os.path.join(self.clVars.Get("sr_samba_winlogon_path"), userName) message = _("Restored deleted user %s")% userName + "\n" +\ _("'yes', 'no'") resWinProf = self.restorePathDelUser(userName, winProfDir, "samba/winprofile", message) removeProfileBack = False if not resWinProf: flagError = True createDirWinProfile = False else: term, createDirWinProfile, removeProfileBack = resWinProf removeHomeBack = False if not flagError: resHome = self.restorePathDelUser(userName, userHomeDir, "samba/home", term) if not resHome: flagError = True createDirLogon = False else: term, createDirHome, removeHomeBack = resHome removeLogonBack = False if not flagError: resLogon = self.restorePathDelUser(userName, userNetlogonDir, "samba/netlogon", term) if not resLogon: flagError = True createDirHome = False else: term, createDirLogon, removeLogonBack = resLogon removeLinProfileBack = False if not flagError: resLinProf = self.restorePathDelUser(userName, linProfDir, "samba/linprofile", term) if not resLinProf: flagError = True createDirLinProfile = False else: term,createDirLinProfile,removeLinProfileBack = resLinProf # Cоздадим нужные директории if not flagError: resSearchUnix = self.servUnixObj.searchUnixUser(userName) resPasswd = False if resSearchUnix: uid = int(resSearchUnix[0][0][1]['uidNumber'][0]) gid = int(resSearchUnix[0][0][1]['gidNumber'][0]) else: resPasswd = self.servUnixObj.searchPasswdUser(userName) if resPasswd: uid = int(resPasswd.split(":")[2]) gid = int(resPasswd.split(":")[3]) # Не удаляемые директории notDeletedDirs = [] if os.path.exists(createDirHome): notDeletedDirs.append(createDirHome) if os.path.exists(createDirLogon): notDeletedDirs.append(createDirLogon) if os.path.exists(createDirWinProfile): notDeletedDirs.append(createDirWinProfile) if os.path.exists(createDirLinProfile): notDeletedDirs.append(createDirLinProfile) if (resPasswd or resSearchUnix) and\ (options.has_key('n') or int(uid) >=1000): # Cоздаем домашнюю директорию if createDirHome: if not self.createUserDir(uid, gid, createDirHome): flagError = True # Cоздаем иконку на домашеней директории if not flagError: fileTxt = "[Desktop Entry]\nIcon=user-home" fileDirectory = os.path.join(createDirHome, ".directory") if not self.createUserFile(fileDirectory, fileTxt, uid, gid): flagError = True # Cоздаем директорию netlogon if not flagError and createDirLogon: if not self.createUserDir(uid, gid, createDirLogon): flagError = True # cоздадим cmd файл для монтирования ресурсов в windows if not flagError: netbios = self.clVars.Get("sr_samba_netbios") netbios = netbios.upper() fileTxt="NET USE R: /D\r\nNET USE R: \\%s\share"\ %netbios fileDirectory = os.path.join(createDirLogon, "start.cmd") print "FILE =", fileDirectory if not self.createUserFile(fileDirectory, fileTxt, uid, gid): flagError = True # Cоздаем директорию профиля win if not flagError and createDirWinProfile: if not self.createUserDir(uid,gid,createDirWinProfile): flagError = True # Создаем директорию профиля lin if not flagError and createDirLinProfile: if not self.createUserDir(uid,gid,createDirLinProfile): flagError = True if not flagError: # Удаляем директорию бекапа профиля win if removeProfileBack and\ os.path.exists(removeProfileBack): self.removeDir(removeProfileBack) self.removeEmptyDir(os.path.split(removeProfileBack)[0]) # Удаляем директорию бекапа профиля lin if removeLinProfileBack and\ os.path.exists(removeLinProfileBack): self.removeDir(removeLinProfileBack) self.removeEmptyDir(os.path.split(removeLinProfileBack)[0]) # Удаляем бекап домашней директории if removeHomeBack and\ os.path.exists(removeHomeBack): self.removeDir(removeHomeBack) self.removeEmptyDir(os.path.split(removeHomeBack)[0]) # Удалим директорию logon пользователя if removeLogonBack and\ os.path.exists(removeLogonBack): self.removeDir(removeLogonBack) self.removeEmptyDir(os.path.split(removeLogonBack)[0]) if flagError: self.delUserSambaServer(userName,{},False,False,notDeletedDirs) if flagCreateUnixUser: self.servUnixObj.delUserUnixServer(userName, {}, False, False) self.printERROR(_("Can not add user") + " ...") return False if flagCreateUnixUser: self.printSUCCESS(_("Added user in Unix service") + " ...") self.printSUCCESS(_("Added user in Samba service") +" ...") return True else: if flagCreateUnixUser: self.servUnixObj.delUserUnixServer(userName, {}, False, False) self.printERROR(_("Can not add user") + " ...") return False def searchSambaUser(self, userName): """Находит пользователя сервиса Samba""" resSearch = self.searchLdapDN(userName, self.relUsersDN, "uid") return resSearch def searchSambaMachine(self, machineName): """Находит машину (компьютер) сервиса Samba""" resSearch = self.searchLdapDN(machineName, self.relComputersDN, "uid") return resSearch def addMachineSambaServer(self, machineName, options): """Добавляет Samba машину в LDAP-сервер""" machineLogin = machineName.replace('$','') + "$" res = self.searchSambaMachine(machineLogin) if res: if res[0][0][1].has_key('sambaSID'): self.printERROR(_("machine")+" "+machineLogin+" "+\ "is found in Samba service") return True # добавляем Samba машину textLine = self.execProg("smbpasswd -a -m %s" %machineLogin) if "Added" in str(textLine): self.printSUCCESS(_("Added machine in Samba service") + " ...") return True else: self.printERROR(_("Can not add machine") + " ...") return False else: # добавляем LDAP машину if not self.servUnixObj.addMachineLdapServer(machineLogin, options): return False # добавляем Samba машину textLine = self.execProg("smbpasswd -a -m %s" %machineLogin) if "Added" in str(textLine): self.printSUCCESS(_("Added machine in Samba service") + " ...") return True else: self.printERROR(_("Can not add machine")+ " ...") return False def setupSambaServer(self, options): """Начальная настройка Samba сервиса""" # Принудительная установка forceOptions = False # Cоздаем объект переменные self.createClVars() if options.has_key("f"): forceOptions = True if self.clVars.Get("sr_unix_set") != "on": self.printERROR(_("Unix service is not setuped")) self.printWARNING (_("Setup Unix service")) self.printWARNING(" cl-setup unix") return False # В случае если сервер установлен if self.clVars.Get("sr_samba_set") == "on" and\ not forceOptions: self.printWARNING (_("WARNING") + ": " +\ _("Samba server is configured")+ ".") return True if not forceOptions: # предупреждение при выполнении этой программы будут изменены # конфигурационные файлы сервиса Samba self.printWARNING (_("WARNING") + ": " + _("Executing of the program will change") + " " + _("the configuration files of Samba service") + ".") # если вы готовы продолжить работу программы нажмите Y если нет n messDialog = \ _("If you are ready to continue executing the program")+", "+\ _("input 'yes'") +", "+ _("if not 'no'") if not self.dialogYesNo(messDialog): return True else: # делаем backup # Проверим запущен ли ldap if not self.getRunService("ldap"): # Запускаем LDAP сервер if not self.runLdapServer(): return False bakupObj = servLdap() bakupObj.backupServer() # Удаляем из автозапуска демона if not self.delDaemonAutostart("samba"): return False # останавливаем сервис Samba if not self.stopServices(["samba"]): return False # Имя устанавливаемого сервиса self.clVars.Set("cl_pass_service","samba") self.clVars.Write("sr_samba_set","off") # Задаем рабочую группу if options.has_key("w"): workgroup = options['w'].strip() self.clVars.Set("sr_samba_domain",workgroup) # Задаем netbios имя if options.has_key("n"): netbios = options['n'].strip() self.clVars.Set("sr_samba_netbios",netbios) # Cоздаем объект профиль устанавливая директорию samba для # файлов профилей if not self.applyProfilesFromService('samba'): return False # Проверим запущен ли ldap if not self.getRunService("ldap"): # Запускаем LDAP сервер if not self.runLdapServer(): return False else: if not self.restartLdapServer(): return False # Записываем данные администратора сервиса Samba ldapParser = iniLdapParser() ldapParser.setVar("samba", {"DN":self.clVars.Get("ld_samba_dn"), "PASS":self.clVars.Get("ld_samba_pw")}) ldapParser = iniLdapParser() pswd = ldapParser.getVar("samba","PASS") if not pswd: self.printERROR(_("ERROR") + ": " +\ _("Samba admin password is not found")) return False textLine = self.execProg("smbpasswd -w %s" %(pswd)) if not "stored" in textLine: self.printERROR(_("ERROR") + ": " +\ _("Can not add Samba admin password")) return False textLine = self.execProg("/etc/init.d/slapd restart") if not "ok" in textLine: self.printNotOK(_("LDAP restart") + " ...") return False #Cоединение с Ldap (администратор) shareLdap.getLdapObjInFile(self) resSearch = self.searchService() ret = True if resSearch: delDN = self.relDN ret = self.deleteDN(delDN) if ret: self.printOK(_("Removed Samba DN from LDAP Database") +" ...") else: self.printERROR(\ _("Can not remove Samba DN from LDAP Database") +" ...") if not ret: return False ldifFile = self.ldifFileBase baseLdif = self.createLdif(ldifFile) if not self.ldapObj.getError(): self.ldapObj.ldapAdd(baseLdif) if self.ldapObj.getError(): print _("LDAP Error") + ": " + self.ldapObj.getError().strip() return False self.printOK(_("Added ldif file") +" ...") textLine = self.execProg("/etc/init.d/samba start") if "ok" in textLine: self.printOK(_("Starting") + " Samba ...") else: self.printNotOK(_("Starting") + " Samba ...") return False print _("Enter existing ROOT password") pwDialog = [_("ROOT password"), _("Retype ROOT password")] if not self.addUserSambaServer('root',{'p':""},pwDialog,False): return False clientName = 'client' clientGroup = 'client' clientUid = '900' clientGid = '900' # Проверяем на наличие группы client resGroupClient = self.servUnixObj.searchUnixGroupName(clientGroup) if not resGroupClient: # Создаем группу для пользователя client if not self.servUnixObj.addGroupUnixServer(clientGroup, {'g':clientGid}, False): self.printERROR(_("not created unix group 'client'")) return False # Добавляем пользователя client для smb ресурса [remote] if not self.addUserSambaServer('client',{'f':'','u':clientUid, 'g':clientGroup}, False,False): self.printERROR(_("not created samba user 'client'")) return False # Если нет то создадим директорию /var/calculate/remote remoteEnvFile = self.clVars.Get("cl_env_path")[0] remotePath = os.path.split(remoteEnvFile)[0] if not os.path.exists(remotePath): os.makedirs(remotePath) # права и владелец /var/calculate/remote if os.path.exists(remotePath): os.chown(remotePath,0,int(clientGid)) os.chmod(remotePath,02750) # изменяем владельца remote на client if not os.path.exists(remoteEnvFile): fd = os.open(remoteEnvFile, os.O_CREAT) os.close(fd) os.chmod(remoteEnvFile, 0640) if os.path.exists(remoteEnvFile): os.chown(remoteEnvFile,0,int(clientGid)) if not self.setDaemonAutostart("slapd"): return False # Устанавливаем автозапуск демона if not self.setDaemonAutostart("samba"): return False # если нет share то создадим sharePath = self.clVars.Get("sr_samba_share_path") if not os.path.exists(sharePath): os.makedirs(sharePath) # Создадим иконку для share fileTxt = "[Desktop Entry]\nIcon=folder-bookmarks" fileDirectory = os.path.join(sharePath,".directory") uid = 0 gid = 0 if not self.createUserFile(fileDirectory, fileTxt, uid, gid): return False #запишем переменные для сервера netbios = self.clVars.Get("sr_samba_netbios") self.clVars.Write("sr_mail_host",netbios,True,"local") #запишем переменные для клиента fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'), self.clVars.Get('os_net_domain')) self.clVars.Set("sr_samba_host",fullHostName,True) clientVars = ["sr_samba_host","ld_services_dn", "ld_unix_dn", "ld_bind_dn","ld_bind_pw","ld_base_dn"] if not self.saveVarsClient(clientVars): return False self.clVars.Write("sr_samba_set","on") self.printOK(_("Samba service configured") + " ...") return True def modUserSambaPasswd(self, userName, options): # Проверим установлен ли сервис samba if not self.isServiceSetup("samba"): return False if not self.searchSambaUser(userName): self.printERROR( _("Samba user %s is not found")%str(userName) + " ...") return False # отключаем samba account if options.has_key('l'): textLine = self.execProg("smbpasswd -d %s" %(userName)) if "Disabled user %s" %userName in textLine: self.printSUCCESS(_("Disabled Samba user %s")%str(userName)+ " ...") else: self.printERROR(_("Can not disable Samba user")+ " "+\ str(userName) + " ...") return False # включаем Samba account if options.has_key('u'): textLine = self.execProg("smbpasswd -e %s" %(userName)) if "Enabled user %s" %userName in textLine: self.printSUCCESS(_("Enabled Samba user %s")%str(userName) + " ...") else: self.printERROR(_("Can not enable Samba user")+ " "+\ str(userName) + " ...") return False if not options: optPasswd = {"p":""} userPwd = self.getUserPassword(optPasswd, "p", False) if userPwd == False: return False if userPwd: if not self.servUnixObj.modUserUnixPasswd(userName,{},userPwd): return False textLine = self.execProg("smbpasswd -a -s %s" %(userName), "%s\n%s\n" %(userPwd,userPwd)) if not (textLine == None): self.printERROR(_("Can not change Samba user password") +\ " ...") return False else: self.printSUCCESS( _("Samba password of user %s is changed")%\ str(userName) + " ...") return True return True def modUserSambaServer (self, userName, options): """Модифицирует настройки пользователя Samba в LDAP""" # Проверим установлен ли сервис samba if not self.isServiceSetup("samba"): return False # Находим Samba пользователя res = self.searchSambaUser(userName) if not res: self.printERROR( _("Samba user %s is not found in Samba service")%\ str(userName) + " ...") return False # отключаем Samba account if options.has_key('L'): textLine = self.execProg("smbpasswd -d %s" %(userName)) if "Disabled user %s" %userName in textLine: self.printSUCCESS(_("Disabled Samba user %s")%str(userName) + " ...") else: self.printERROR(_("Can not disable Samba user")+ " "+\ str(userName) + " ...") return False # включаем samba account elif options.has_key('U'): textLine = self.execProg("smbpasswd -e %s" %(userName)) if "Enabled user %s" %userName in textLine: self.printSUCCESS(_("Enabled Samba user %s")%str(userName) + " ...") else: self.printERROR(_("Can not enable Samba user")+ " "+\ str(userName) + " ...") return False # модифицируем пароль if options.has_key('P') or options.has_key('p'): pwDialog = [_("New SMB password"), _("Retype new SMB password")] pwdA = getpass.getpass(pwDialog[0]+":") pwdB = getpass.getpass(pwDialog[1]+":") if not (pwdA == pwdB): self.printERROR (_("ERROR") + ": " +\ _("password incorrect")+ ": " + _("try again")) return False userPwd = pwdA textLine = self.execProg("smbpasswd -s %s" %(userName), "%s\n%s\n" %(userPwd,userPwd)) if not (textLine == None): self.printERROR(_("Can not modify Samba user password") +\ " ...") return False self.printSUCCESS(_("Modified Samba user password") + " ...") return True class servLdap(shareLdap): """Методы севисa Ldap""" def __init__(self): shareLdap.__init__(self) self.ldifFileBase =\ "/usr/lib/calculate/calculate-server/ldif/ldap_base.ldif" # Для backup # Директория куда будет сохранен архив self.backupDirectory = "/var/calculate/server-backup/ldap" # ldif файл базы LDAP self.archLdifFile = "/tmp/LDAP_DATABASE.ldif" # приватная директория Samba self.sambaPrivate = "/var/lib/samba/private" # директория c алиасами сервиса Mail self.mailPrivate = "/etc/mail" # название файла где будет храниться список архивируемых файлов self.tmpListFile = "/tmp/list_CDS_files.txt" # Директория для хранения профилей backup self.backupDir = "backup" def savePrivateFile(self, fileName, data): """Записать файл с правами 0600""" try: FD = open (fileName, "w+") FD.close() os.chmod(fileName,0600) FD = open (fileName, "w+") FD.write(data) FD.close() except: return False return True def getServiceSetupPathProfiles(self): """находим пути к профилям установленных сервисов Выдаем два списка ([пути к профилям сервисов],[установленные сервисы]) """ servicePaths = [] servInstalled = [] # пути к директориям профилей profilePaths = self.clVars.Get("cl_profile_path") for profilePath in profilePaths: if self.clVars.Get("sr_ldap_set") == "on": serv = "ldap" servPath = os.path.join(profilePath,serv) if os.path.exists(servPath): servicePaths.append(servPath) servInstalled.append(serv) if self.clVars.Get("sr_unix_set") == "on": serv = "unix" servPath = os.path.join(profilePath,serv) if os.path.exists(servPath): servicePaths.append(servPath) servInstalled.append(serv) if self.clVars.Get("sr_samba_set") == "on": serv = "samba" servPath = os.path.join(profilePath,serv) if os.path.exists(servPath): servicePaths.append(servPath) servInstalled.append(serv) if self.clVars.Get("sr_mail_set") == "on": serv = "mail" servPath = os.path.join(profilePath,serv) if os.path.exists(servPath): servicePaths.append(servPath) servInstalled.append(serv) if self.clVars.Get("sr_jabber_set") == "on": serv = "jabber" servPath = os.path.join(profilePath,serv) if os.path.exists(servPath): servicePaths.append(servPath) servInstalled.append(serv) return (servicePaths, servInstalled) def backupServer(self): """Сохраняет настройки установленных сервисов и базу LDAP""" # создаем директорию backup-а if not os.path.exists(self.backupDirectory): try: os.makedirs(self.backupDirectory) except os.IOError: self.printERROR(_("Can not create directory") + ": " +\ str(self.backupDirectory)) return False # Соединяемся с LDAP shareLdap.getLdapObjInFile(self) # получаем ldif текст всей базы LDAP ldifText = self.fullElementDNtoText("") if not ldifText: self.printERROR( "Unix service DN is not found or empty") return False # генерируем название файла архива strData = time.strftime("%Y%m%d%H%M%S",time.localtime(time.time())) backupFile = "%s.tar.bz2" %strData # удаляем если существуют ldif файл базы LDAP и файл список if os.path.exists(self.archLdifFile): os.remove(self.archLdifFile) if os.path.exists(self.tmpListFile): os.remove(self.tmpListFile) # находим пути к профилям установленных сервисов servicePaths, servInstalled = self.getServiceSetupPathProfiles() if not servicePaths: self.printERROR("Services are not installed") return False # Все файлы которые нужно заархивировать allArchFiles = [] fileObj = cl_profile._file() dirObjs = fileObj.scanDirs(servicePaths) i = 0 for dirObj in dirObjs: for fileProfile in dirObj.files: archFile = fileProfile.split(servicePaths[i])[1] allArchFiles.append(archFile) i += 1 scanPrivDirs = [] if "ldap" in servInstalled: # Получаем путь к ini директории ldapParser = iniLdapParser() #iniPath = ldapParser.pathIniFile #scanPrivDirs.append(iniPath) dirDelUsers = self.clVars.Get("sr_deleted_path") if os.path.exists(dirDelUsers): scanPrivDirs.append(dirDelUsers) # Добавляем calulate.ldap allArchFiles.append(ldapParser.nameIniFile) # Добавляем calculate.env iniFile = "/" + self.clVars.Get("cl_env_path")[2] allArchFiles.append(iniFile) if "samba" in servInstalled: scanPrivDirs.append(self.sambaPrivate) if "mail" in servInstalled: scanPrivDirs.append(self.mailPrivate) if scanPrivDirs: dirObjs = fileObj.scanDirs(scanPrivDirs) for dirObj in dirObjs: for archFile in dirObj.files: allArchFiles.append(archFile) allArchFiles.append(self.archLdifFile) allArchFiles = self.unicList(allArchFiles) # Сохраняем файл список архивируемых файлов if not self.savePrivateFile (self.tmpListFile, "\n".join(allArchFiles)): self.printERROR(_("Can not create list archive files") + ": " +\ str(self.tmpListFile)) return False # Сохраняем ldif-файл базы LDAP if not self.savePrivateFile(self.archLdifFile, ldifText): self.printERROR(_("Can not create ldif file") + ": " +\ str(self.archLdifFile)) return False bFile = os.path.join(self.backupDirectory, backupFile) self.execProg("tar --files-from=%s -cjf %s"\ %(self.tmpListFile, bFile)) if os.path.exists(self.archLdifFile): os.remove(self.archLdifFile) if os.path.exists(self.tmpListFile): os.remove(self.tmpListFile) if os.path.exists(bFile): os.chmod(bFile,0600) self.printSUCCESS(_("Created archive file") + ": " +\ str(bFile)) return True else: self.printERROR(_("Can not create archive file") + ": " +\ str(bFile)) return False def backupLdapServer(self, options): if not options or (options and options.has_key("b")): return self.backupServer() if options.has_key("r"): return self.restoreServer() def startDaemons(self, service, daemons): """Стартует демонов""" flagError = False for daemon in daemons: if not self.getRunDaemons([daemon]): textLine = self.execProg("/etc/init.d/%s start" %(daemon)) if not ("ok" in textLine): self.printERROR( _("Daemon %s was not started") %daemon) flagError = True break if flagError: self.printNotOK(_("Starting") + " " + service.capitalize() + " " +\ _("service")) return False else: self.printOK(_("Starting") + " " + service.capitalize() + " " +\ _("service")) return True def startAllSetupServices(self): """Запускаем все работающие установленные сервисы а также прописываем в автозапуск """ # находим установленные сервисы servicePaths, servInstalled = self.getServiceSetupPathProfiles() if 'ldap' in servInstalled: if not self.startDaemons('ldap',['slapd']): return False # Устанавливаем автозапуск демона if not self.setDaemonAutostart("slapd"): return False flagError = False for service in servInstalled: if service == "unix" or service == "ldap": continue elif service == "mail": if not self.startDaemons('mail',['postfix', 'dovecot']): flagError = True break # Устанавливаем автозапуск демонов if not (self.setDaemonAutostart("postfix") and\ self.setDaemonAutostart("dovecot")): flagError = True break elif service == "jabber": if not self.startDaemons('jabber',['ejabberd']): flagError = True break # Устанавливаем автозапуск демона if not self.setDaemonAutostart("ejabberd"): flagError = True break else: if not self.startDaemons(service,[service]): flagError = True break # Устанавливаем автозапуск демона if not self.setDaemonAutostart(service): return False if flagError: return False else: return True def restoreServer(self): """Восстанавливает из архива все установленные сервисы Восстановленные сервисы будут запущены """ if not os.path.exists(self.backupDirectory): self.printERROR(_("Path for backup is not found") + ": " +\ str(self.backupDirectory)) return False # Получаем номер архивного файла archFiles = os.listdir(self.backupDirectory) maxFileNumber = 0 for archFile in archFiles: numbTxt = archFile.split(".")[0] try: numb = int(numbTxt) except: continue if maxFileNumber=", #'helpChapter':_("Common options"), #'help':_("change enviroment values") #}, #{'shortOption':"e", #'longOption':"env", #'optVal':"filter", #'helpChapter':_("Common options"), #'help':_("show enviroment values (filter for type, all - no filter)") #}, # Services {'progAccess':(6,), 'helpChapter':_("Services"), 'help':pcs(" ldap", self.column_width, "ldap " + servName, self.consolewidth-self.column_width) }, {'progAccess':(0,1,2,3,4,5,6,7,), 'helpChapter':_("Services"), 'help':pcs(" unix", self.column_width, "unix " + servName, self.consolewidth-self.column_width) }, {'progAccess':(3,4,5,6,7,), 'helpChapter':_("Services"), 'help':pcs(" samba", self.column_width, "samba " + servName, self.consolewidth-self.column_width) }, {'progAccess':(0,1,2,), 'helpChapter':_("Services"), 'help':pcs(" samba", self.column_width, _("using unix group"), self.consolewidth-self.column_width) }, {'progAccess':(0,1,2,3,4,5,6,7,), 'helpChapter':_("Services"), 'help':pcs(" mail", self.column_width, "mail " + servName, self.consolewidth-self.column_width) }, {'progAccess':(0,1,2,3,4,5,6,7,), 'helpChapter':_("Services"), 'help':pcs(" jabber", self.column_width, "jabber " + servName, self.consolewidth-self.column_width) }, ##{'helpChapter':_("Services"), ##'help':" mail \t\t\tmail " + servName + "\n" ##}, ##{'helpChapter':_("Services"), ##'help':" ftp \t\t\tftp " + servName + "\n" ##}, ##{'helpChapter':_("Services"), ##'help':" proxy \t\tproxy " + servName + "\n" ##}, ##{'helpChapter':_("Services"), ##'help':" radius \t\tradius " + servName + "\n" ##}, ##{'helpChapter':_("Services"), ##'help':" jabber \t\tjabber " + servName + "\n" ##}, ##{'helpChapter':_("Services"), ##'help':" addressbook \t\taddressbook " + servName + "\n" ##}, ##{'helpChapter':_("Services"), ##'help':" dhcp \t\t\tdhcp " + servName + "\n" ##}, ##{'helpChapter':_("Services"), ##'help':" named \t\tnamed " + servName + "\n" ##}, ##{'helpChapter':_("Services"), ##'help':" wiki \t\t\twiki " + servName + "\n" ##}, # Informative output { #'progAccess':(3,), 'helpChapter':"Copyright", 'help':Version }, # Использование { 'progAccess':(1,), 'helpChapter':_("Usage"), 'help': cmdName + " " +_("group") + " " + _("service") }, { 'progAccess':(0,2), 'helpChapter':_("Usage"), 'help': cmdName + " [" + _("options") + "] " +\ _("group") + " " + _("service") }, { 'progAccess':(3,4,5,7), 'helpChapter':_("Usage"), 'help': cmdName + " [" + _("options") + "] " + _("user") +\ " " + _("service") }, { 'progAccess':(6,), 'helpChapter':_("Usage"), 'help': cmdName + " [" + _("options") + "] "+\ " " + _("service") }, { 'progAccess':(8,), 'helpChapter':_("Usage"), 'help': cmdName + " [" + _("options") + "]" }, # Function { 'progAccess':(0,), 'helpChapter':"Function", 'help':_("Add group in LDAP directory service") }, { 'progAccess':(1,), 'helpChapter':"Function", 'help':_("Delete group from LDAP directory service") }, { 'progAccess':(2,), 'helpChapter':"Function", 'help':_("Modify group profiles in LDAP directory service") }, { 'progAccess':(3,), 'helpChapter':"Function", 'help':_("Add user in LDAP directory service") }, { 'progAccess':(4,), 'helpChapter':"Function", 'help':_("Delete user from LDAP directory service") }, { 'progAccess':(5,), 'helpChapter':"Function", 'help':_("Modify user profiles in LDAP directory service") }, { 'progAccess':(6,), 'helpChapter':"Function", 'help':_("Sets service in the system") }, { 'progAccess':(7,), 'helpChapter':"Function", 'help':_("Change user password") }, { 'progAccess':(8,), 'helpChapter':"Function", 'help':_("Backup service") }, # Примеры { 'progAccess':(0,), 'helpChapter':_("Examples"), 'help':pcs( " cl-groupadd guest ldap", self.column_width, "# " + _("add group guest in LDAP service"), self.consolewidth-self.column_width ) }, { 'progAccess':(1,), 'helpChapter':_("Examples"), 'help':pcs( " cl-groupdel guest unix", self.column_width, "# " + _("delete group guest from Unix service") + "." , self.consolewidth-self.column_width) }, { 'progAccess':(2,), 'helpChapter':_("Examples"), 'help':pcs( " cl-groupmod -a guest test unix", self.column_width, "# " + _("add user test to group guest in Unix service"), self.consolewidth-self.column_width ) }, { 'progAccess':(3,), 'helpChapter':_("Examples"), 'help':pcs(" cl-useradd guest samba", self.column_width, "# " +_("add user guest in Samba service") + ".", self.consolewidth - self.column_width) }, { 'progAccess':(4,), 'helpChapter':_("Examples"), 'help':pcs(" cl-userdel guest samba", self.column_width, "# " + _("delete user guest from Samba service") + ".", self.consolewidth-self.column_width) }, { 'progAccess':(5,), 'helpChapter':_("Examples"), 'help':pcs(" cl-usermod -a test guest unix", self.column_width, "# " + _("append user guest to the supplemental group test") +\ ".", self.consolewidth-self.column_width) }, { 'progAccess':(6,), 'helpChapter':_("Examples"), 'help':pcs(" cl-setup samba", self.column_width, "# "+_("set Samba service in the system") + ".", self.consolewidth-self.column_width) }, { 'progAccess':(7,), 'helpChapter':_("Examples"), 'help':pcs(" cl-passwd test samba", self.column_width, "# "+_("change password of user test for Samba service") + ".", self.consolewidth-self.column_width) }, { 'progAccess':(8,), 'helpChapter':_("Examples"), 'help':pcs(" cl-backup -r", self.column_width, "# "+_("restore all services") + ".", self.consolewidth-self.column_width) }, #{ #'helpChapter':_("Examples"), #'help':pcs(" " + cmdName + " --env boot", self.column_width, #"# "+_("show enviroment varibles which has type")+" 'boot'" +\ #".", #self.consolewidth-self.column_width) #}, #{'progAccess':(0,1,2,4,5,6), #'helpChapter':_("Examples"), #'help':pcs(" " + cmdName + " \\\n --set setup_march=x86_64", #self.column_width, "# "+ _("modify some env") + ".", #self.consolewidth-self.column_width) #}, ] self._cl_help__setParamHelp() # Удаляем ненужный аттрибут класса cl_profile.xmlShare self._createElement = False delattr(self, "_createElement") #Название всех сервисов self.allServ = [] self.__setAllServ() def processOptionsForDatavars(self, options, datavars): '''Обработать опции связанные с переменными окружения Параметры: options словарь опций ( <буква опции>:<значение> обрабатывает буквы 's' для установки параметров 'e' для отображения) datavars объект-хранилище переменных окружнения Возвращаемые значения: True удалось установить указанные параметры False метод вызван для просмотра переменных окружения, или установка переменных окружения прошла с ошибками. ''' # если это установка параметров if 's' in options: # если установки параметрв не произошло if not datavars.flFromCmdParam(options['s']): # вывод print _("Bad enviroment parameters") return False # если опция отображения параметров if 'e' in options: # вывод всех параметров if options['e'] == '*': datavars.printVars() # вывод параметров, используюя фильтр else: datavars.printVars( [i.strip() for i in options['e'].split(':')]) return False return True def handleCheckAccess(self,dataHash): """Дополнительная проверка опций-справок - опция доступна только если в разделах этой справки есть хотябы одна опция Входные параметры: dataHash словарь из списка self.data """ # если эта опция для реализации справки if 'longOption' in dataHash \ and dataHash['longOption'] in self.relOptions: # составляем список разделов которые должны быть не пустые # разделы из relOptions относящиеся к этой опции за исключением # разделов которые надо пропустить (relChapterPass) trueChapters = \ set(self.relOptions[dataHash['longOption']]).difference( \ self.relChapterPass) # перебираем все опции for unit in self.data: # если опция не отностится к выполняемой программе, то # ее пропустить if 'progAccess' in unit and \ not self.progName[self.cmdName] in unit['progAccess']: continue # если опция отностится к необходмой справки if unit['helpChapter'] in trueChapters: # опция справки - доступна return True # если не оказалось не одной опция для разделов этой справки return False # опция доступна, так как не справочная return True def __setAllServ(self): """Записывает в аттрибут self.allServ названия всех сервисов""" sServ = re.compile("\s*([^\s]+)\s*") for par in self.data: if par.has_key('helpChapter') and\ par['helpChapter'] == _("Services") and\ par.has_key('help') and self.access(par): res = sServ.search(par['help']) if res: self.allServ.append(res.group(1)) class tsOpt(cl_base.opt): """Класс для обработки параметров и вывода help Параметры: helpObj объект-справка содержащий необходимые опции parBeforeService дополнительные необходимые параметры перед указанным сервисом. (например "group" или "user") optService проверять хвост командной строки на наличие сервиса notOptError выдавать ошибку при отсутствии опций командной строки """ def __init__(self, helpObj, parBeforeService,optService=True, notOptError=False): # последний параметр является сервисом service = sys.argv[-1:][0].rstrip() # от cl_help получаем короткие и длинные опции if service in helpObj.allServ: shortOpt, longOpt = helpObj.getAllOpt('all', helpObj.relServices[service]) else: shortOpt,longOpt = helpObj.getAllOpt('all', helpObj.relOptions['h']) # вызвать конструктор объекта, распознающего опции cl_base.opt.__init__(self,shortOpt,longOpt) self.nameParams = parBeforeService + ['service'] self.sysArgv = sys.argv[1:] self.helpObj = helpObj self.__iter = 0 self.opt = {} self.params = {} self.getopt() # Обработка help self.flagHelp = False # определяем есть ли среди опций опции, которые влияют на показ # опциональных разделов (метод пересечения множеств) helpopt = \ tuple(set(self.opt.keys()).intersection(helpObj.relOptions.keys())) #Если есть опции help if len(helpopt) > 0: print helpObj.getHelp(helpObj.relOptions[helpopt[0]]) self.flagHelp = True #Если нет хвостов elif not self.params: if optService: print helpObj.getHelp(helpObj.relOptions['h']) self.flagHelp = True else: if self.params.has_key('service'): if not (self.params['service'] in helpObj.allServ) or\ len(self.nameParams) != self.__iter: self.handlerErrOpt() else: self.handlerErrOpt() # В случае остсутствия опций командной строки if notOptError and not self.opt and self.params.has_key('service'): self.printErrorNotOpt() self.flagHelp = True def printErrorNotOpt(self): """Сообщение в случае отсутствия опций""" print _("Options are absent.") def handlerOpt(self,option,value): # Обработчик (опция значение) #print option, value shortOpt = self.helpObj.getShortOpt(option) if not shortOpt: shortOpt = option if not shortOpt in self.opt: self.opt[shortOpt] = value def handlerErrOpt(self): # Обработчик ошибок argv = " ".join(sys.argv[1:]) print _("Unrecognized option") + ' "' + argv + '"\n' + \ _("Try") + ' "' + sys.argv[0].split("/")[-1] + ' --help" ' +\ _("for more information.") def handlerParam(self,param): # Обработчик хвостов (значение) self.__iter += 1 if self.__iter<=len(self.nameParams): self.params[self.nameParams[self.__iter-1]] = param