diff --git a/pym/cl_base.py b/pym/cl_base.py index b8b212b..4a8626e 100644 --- a/pym/cl_base.py +++ b/pym/cl_base.py @@ -760,7 +760,7 @@ class DataVars(object): self.__LevelsVar.append((self.__levelNumber, nameVar)) self.__levelNumber += 1 #nameMethod = "get_" + nameVar - if self.__dict__.has_key(nameVar): + if hasattr(self, nameVar): ret = self.__getattribute__(nameVar).Get() elif self.__findVarData(nameVar): dictVar, methodFill =self.__findVarData(nameVar) @@ -790,7 +790,7 @@ class DataVars(object): def __Set(self, nameVar, value, force=False): nameMethod = "get_" +nameVar - if not self.__dict__.has_key(nameVar) and self.__findVarData(nameVar): + if not hasattr(self, nameVar) and self.__findVarData(nameVar): dictVar, methodFill =self.__findVarData(nameVar) varobj = var(self) # Устанавливаем аттрибуты @@ -798,7 +798,7 @@ class DataVars(object): if methodFill: varobj.Fill = methodFill self.__setattr__(nameVar, varobj) - if self.__dict__.has_key(nameVar): + if hasattr(self, nameVar): if not force and "r" in getattr(self, nameVar).mode: print _("Attempt to rewrite a variable for reading:%s")\ %nameVar @@ -855,11 +855,11 @@ class DataVars(object): vname - имя переменной """ - if self.__dict__.has_key(vname): - if self.__dict__[vname].service == 'Global': + if hasattr(self, vname): + if getattr(self, vname).service == 'Global': return 'calculate' else: - return self.__dict__[vname].service.lower() + return getattr(self, vname).service.lower() def __writeVarValue(self, vname, val, location, header): '''Записать значение в calculate.ini @@ -907,9 +907,10 @@ class DataVars(object): Параметры: vname имя переменной location расположение ini файла ('default', 'local', 'remote') + header раздел ini файла ('client', 'server', 'calculate') Возвращаемые значение: - True удалено успешна + True удалено успешно False удаление не удалсь ''' # получаем все пути до ini файлов @@ -932,6 +933,9 @@ class DataVars(object): # Получаем секцию конфигурационного файла if not header: header = self.__getSection(vname) + if not header: + self.Get(vname) + header = self.__getSection(vname) # Удаляем переменную retDelVar = config.delVar(header, vname) retDelArea = True @@ -1049,11 +1053,7 @@ class DataVars(object): '''Заполнить конфигурацию переменных для инсталятора''' self.Set('setup_pass','install',True) - #def defined(self, vname): - #if vname: - #if self.__dict__.has_key(vname): - #return True - #return False + def defined(self, vname): return True @@ -1062,7 +1062,7 @@ class DataVars(object): def exists(self, nameVar): """ Определяет существует ли переменная с таким имененм """ - if self.__dict__.has_key(nameVar): + if hasattr(self, nameVar): return True foundVar = False # Ищем переменную в импортируемых модулях diff --git a/pym/cl_profile.py b/pym/cl_profile.py index cde1513..161c37d 100644 --- a/pym/cl_profile.py +++ b/pym/cl_profile.py @@ -129,7 +129,7 @@ class _terms(_error): flagError = True if function: reFunction = re.compile(\ - "([a-zA-Z0-9\_\-]+)\([a-zA-Z0-9_\-\+\,\*\/\.]+\)") + "([a-zA-Z0-9\_\-]+)\([a-zA-Z0-9_\-\+\,\*\/\.\'\"]+\)") searchFunct = reFunction.search(vals[0]) if searchFunct: flagError = False @@ -2178,7 +2178,97 @@ class utfBin: resS = reVar.search(textProfileTmp) return textProfileTmp -class profile(_file, _terms, xmlShare): +class ldapProfile(): + """Работа с LDAP сервером для профилей""" + # Соединение с LDAP сервером + conLdap = False + + def getLDAPDataInConfig(self): + """Получение имени LDAP сервера и DN пользователей под пользователем""" + fileName = "/etc/ldap.conf" + serverName = "" + usersDN = "" + bindDN = "" + bindPW = "" + strServer = ("host","HOST") + lenStrServer = len(strServer[0]) + strDN = ("nss_base_passwd","NSS_BASE_PASSWD") + lenStrDN = len(strDN[0]) + strBindDN = ("binddn", "BINDDN") + lenStrBindDN = len(strBindDN[0]) + strBindPW = ("bindpw", "BINDPW") + lenStrBindPW = len(strBindPW[0]) + splList = (" ", "\t") + try: + for i in open(fileName): + if not serverName and\ + filter(lambda x: i.startswith(x),strServer) and\ + len(i)>lenStrServer: + spl = i[lenStrServer] + if spl in splList: + serverName = i.rpartition(spl)[2].strip() + + if not bindDN and\ + filter(lambda x: i.startswith(x),strBindDN) and\ + len(i)>lenStrBindDN: + spl = i[lenStrBindDN] + if spl in splList: + bindDN = i.rpartition(spl)[2].strip() + + if not bindPW and\ + filter(lambda x: i.startswith(x),strBindPW) and\ + len(i)>lenStrBindPW: + spl = i[lenStrBindPW] + if spl in splList: + bindPW = i.rpartition(spl)[2].strip() + + if not usersDN and filter(lambda x: i.startswith(x), strDN) and\ + len(i)>lenStrDN: + spl = i[lenStrDN] + if spl in splList: + usersDN = i.rpartition(spl)[2].partition('?')[0].strip() + if serverName and usersDN and bindDN and bindPW: + break + except: + return () + if serverName and usersDN and bindDN and bindPW: + return (serverName, usersDN, bindDN, bindPW) + else: + return () + + def getUserDataInLDAP(self, userName): + """Получаем домашнюю директорию пользователя из LDAP""" + if not self.conLdap: + import cl_utils2 + data = self.getLDAPDataInConfig() + if not data: + return "" + serverName, usersDN, bindDN, bindPW = data + # Подключаемся к LDAP + ldapObj = cl_utils2.ldapFun(bindDN, bindPW, serverName) + if self.getError(): + return "" + self.conLdap = ldapObj.conLdap + searchScope = ldap.SCOPE_ONELEVEL + searchFilter = "uid=%s" %(userName) + retrieveAttributes = ["uidNumber", + "gidNumber" + "homeDirectory"] + resSearch = ldapObj.ldapSearch(usersDN, searchScope, + searchFilter, retrieveAttributes) + if resSearch: + if resSearch[0][0][1].has_key('uidNumber'): + uid = searchUser[0][0][1]['uidNumber'][0] + if resSearch[0][0][1].has_key('gidNumber'): + gid = searchUser[0][0][1]['gidNumber'][0] + if resSearch[0][0][1].has_key('homeDirectory'): + homeDir = resSearch[0][0][1]['homeDirectory'][0] + if uid and gid and homeDir: + return uid, gid, homeDir + return "" + + +class profile(_file, _terms, xmlShare, ldapProfile): """Класс для работы с профилями На вход 2 параметра: объект хранения переменных, имя сервиса - не @@ -2214,13 +2304,13 @@ class profile(_file, _terms, xmlShare): varStart = "#-" varEnd = "-#" self._reVar = re.compile(("%s[a-zA-Z0-9_-]+%s")%(varStart,varEnd),re.M) - self._reFunc = re.compile(("%s[a-zA-Z0-9_\-\+\(\)\, \*\/\.]+%s")\ + self._reFunc = re.compile(("%s[a-zA-Z0-9_\-\+\(\)\, \*\/\.\'\"]+%s")\ %(varStart,varEnd),re.M) self._deltVarStart = len(varStart) self._deltVarEnd = len(varEnd) # Условия self._reTermBloc = re.compile("#\?(?P[a-zA-Z0-9\-_]+)\ -(?P\([a-zA-Z0-9_\-\+\,\*\/\.]+\))?\ +(?P\([a-zA-Z0-9_\-\+\,\*\/\.\'\"]+\))?\ (?P[\>\<\=\!\&\|]+\ [a-zA-Z0-9\>\<\=\!\|\&\-\+\*\/_\.\,\(\)]*)#\ \n*(?P.+?)\n*#(?P=rTerm)#(?P[ ,\t]*\n?)",re.M|re.S) @@ -2712,6 +2802,134 @@ class profile(_file, _terms, xmlShare): textProfileTmp[resS.end():] return textProfileTmp + def loadVarsIni(iniFileName, localVarsIni, isLoadVarsIni): + """ Читает файл fileName + создает и заполняет переменные на основе этого файла + Используеться совместно c funcIni + """ + # получить объект настроенный на ini + config = cl_base.iniParser(iniFileName) + # получаем все секции из конфигурационного файла + allsect = config.getAllSectionNames() + if not allsect: + isLoadVarsIni = False + return isLoadVarsIni + # Заполняем переменные для funcIni + for sect in allsect: + sectVars = config.getAreaVars(sect) + for name in sectVars.keys(): + nameVar = "%s.%s"%(sect,name) + valueVar = sectVars[name] + localVarsIni[nameVar] = valueVar + if localVarsIni: + isLoadVarsIni = True + else: + isLoadVarsIni = False + return isLoadVarsIni + + def funcIni(funTxt,resS,localVarsIni,isLoadVarsIni, uid, gid, homeDir, + textProfileTmp): + """локальная функция записывает и считывает значение переменной + + из ini файла ~./calculate/ini.env + """ + # ~/.calculate + if not homeDir: + homeDir = "" + userName = self.objVar.Get("ur_login") + if not userName: + print _("error in profile %s")%nameProfile + print _("error profile term %s")%str(funTxt) + print _("template variable 'ur_login' is empty") + cl_base.exit(1) + import pwd + flagFoundUser = False + try: + pwdObj = pwd.getpwnam(userName) + uid = pwdObj.pw_uid + gid = pwdObj.pw_gid + homeDir = pwdObj.pw_dir + flagFoundUser = True + except: + data = self.getUserDataInLDAP(userName) + if data: + uid, gid, homeDir = data + flagFoundUser = True + else: + flagFoundUser = True + if not flagFoundUser: + print _("error in profile %s")%nameProfile + print _("error profile term %s")%str(funTxt) + print _("Can not found user %s")%str(userName) + cl_base.exit(1) + pathConfig = os.path.join(homeDir, ".calculate") + fileConfig = os.path.join(pathConfig,"ini.env") + # Создаем директорию + if not os.path.exists(pathConfig): + os.makedirs(pathConfig) + os.chown(pathConfig, int(uid), int(gid)) + termsRaw = funTxt[4:-1].split(",") + flagFirst = True + terms = [] + for term in termsRaw: + if flagFirst: + terms.append(term.replace(" ","")) + flagFirst = False + else: + val = term.strip() + # Флаг (не найдены кавычки) + flagNotFoundQuote = True + for el in ('"',"'"): + if val.startswith(el) and val.endswith(el): + terms.append(val[1:-1]) + flagNotFoundQuote = False + break + if flagNotFoundQuote: + terms.append(val) + # Название локальной переменной + nameLocVar = terms[0] + namesVar = nameLocVar.split(".") + if len(namesVar) == 1: + nameLocVar = "main.%s"%nameLocVar + elif len(namesVar)>2: + print _("error in profile %s")%nameProfile + print _("error profile term %s")%str(funTxt) + cl_base.exit(1) + replace = "" + if len(terms) == 1: + if isLoadVarsIni is None: + # читаем переменные из файла + isLoadVarsIni = loadVarsIni(fileConfig, localVarsIni, + isLoadVarsIni) + if nameLocVar in localVarsIni.keys(): + replace = localVarsIni[nameLocVar] + elif len(terms) == 2: + if isLoadVarsIni is None: + # читаем переменные из файла + isLoadVarsIni = loadVarsIni(fileConfig, localVarsIni, + isLoadVarsIni) + # Значение локальной переменной + valueLocVar = terms[1] + localVarsIni[nameLocVar] = valueLocVar + else: + print _("error in profile %s")%nameProfile + print _("error profile term %s")%str(funTxt) + cl_base.exit(1) + textProfileTmp = textProfileTmp[:resS.start()] + replace +\ + textProfileTmp[resS.end():] + return (isLoadVarsIni, uid, gid, homeDir, textProfileTmp) + + # Локальные переменные для ini файла + localVarsIni = {} + # Был ли прочитан ini файл + isLoadVarsIni = None + # uid пользователя + uid = "" + # gid пользователя + gid = "" + # Путь к домашней директории пользователя + homeDir = "" + # Локальные переменные localVars = {} # Регулярное выражние для сложения @@ -2746,8 +2964,47 @@ class profile(_file, _terms, xmlShare): elif funTxt[:5] == "push(": textProfileTmp = funcPush(funTxt,resS,localVars,textProfileTmp) resS = self._reFunc.search(textProfileTmp) + elif funTxt[:4] == "ini(": + isLoadVarsIni, uid, gid, homeDir, textProfileTmp = funcIni(\ + funTxt, resS, + localVarsIni, + isLoadVarsIni, + uid, + gid, + homeDir, + textProfileTmp) + resS = self._reFunc.search(textProfileTmp) else: resS = False + if not isLoadVarsIni is None and localVarsIni and homeDir: + # Записываем переменные в конфигурационный файл + pathConfig = os.path.join(homeDir,".calculate","ini.env") + # Очистка файла + if os.path.exists(pathConfig): + FD = open(pathConfig, "r+") + FD.truncate(0) + FD.seek(0) + FD.close() + # Запись переменных + # Создание объкта парсера + config = cl_base.iniParser(pathConfig) + # секции будущего конфигурационного файла + sects = list(set(map(lambda x: x.split(".")[0],\ + localVarsIni.keys()))) + for sect in sects: + dictVar = {} + for varName in localVarsIni.keys(): + if varName.startswith("%s."%sect): + nameVar = varName.rpartition(".")[2] + valueVar = localVarsIni[varName] + if valueVar: + dictVar[nameVar] = valueVar + if dictVar: + # Запись переменных в секцию + config.setVar(sect, dictVar) + # Меняем права + if os.path.exists(pathConfig) and uid and gid: + os.chown(pathConfig, int(uid), int(gid)) return textProfileTmp def applyTermsProfile(self, textProfile, nameProfile, nameSystemFile=False): diff --git a/pym/cl_vars.py b/pym/cl_vars.py index d69f409..be174fd 100644 --- a/pym/cl_vars.py +++ b/pym/cl_vars.py @@ -86,3 +86,6 @@ class Data: # Действие программы cl_pass_run = {'mode':"w"} + + #Логин пользователя + ur_login = {'mode':"w"}