#-*- coding: utf-8 -*- # Copyright 2008-2010 Calculate Ltd. http://www.calculate-linux.org # # 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 # Ввод pwd import getpass import types from cl_utils import removeDir from cl_print import color_print from server.share import servicesAPI from server.utils import rawInput, isCorrectStringNet, addInfoUser, \ addInfoGroup, dialogYesNo # Перевод модуля import cl_lang tr = cl_lang.lang() tr.setLocalDomain('cl_lib') tr.setLanguage(sys.modules[__name__]) import cl_overriding class users(color_print): """Общие методы для серверных программ, (работа с пользователями и группами)""" # Объект с методами доступа к другим сервисам servicesAPIObj = servicesAPI() # Статические группы staticGroups = {\ 'client':addInfoGroup('client', '900', 'Client group', '2801', '2'), 'Domain Admins':addInfoGroup('Domain Admins', '512', 'Domain Administrators', '512', '2'), 'Domain Users':addInfoGroup('Domain Users', '513', 'Domain Users', '513', '2'), 'Domain Guests':addInfoGroup('Domain Guests', '514', 'Domain Guests Users', '514', '2'), 'Domain Computers':addInfoGroup('Domain Computers', '515', 'Domain Computers accounts', '515', '2'), 'Administrators':addInfoGroup('Administrators', '544', 'Domain Members can fully \ administer the computer/sambaDomainName', '544', '5', "S-1-5-32-544"), 'Account Operators':addInfoGroup('Account Operators', '548', 'Domain Users to manipulate \ users accounts', '548', '5', "S-1-5-32-548"), 'System Operators':addInfoGroup('System Operators', '549', 'Domain System Operators', '549', '5', "S-1-5-32-549"), 'Print Operators':addInfoGroup('Print Operators', '550', 'Domain Print Operators', '550', '5', "S-1-5-32-550"), 'Backup Operators':addInfoGroup('Backup Operators', '551', 'Domain Members can bypass \ file security to back up files', '551', '5', "S-1-5-32-551"), 'Replicators':addInfoGroup('Replicators', '552', 'Domain Supports file replication \ in a sambaDomainName', '552', '5', "S-1-5-32-552"), } # Статические пользователи staticUsers = {\ 'client':addInfoUser('client', '900', '900', 'Client samba user'), 'admin':addInfoUser('admin', '901', '544', 'Admin samba user')} def getUserUidAndGid(self, userName, groupName=""): """Находит в системе uid и gid пользователя userName - имя пользователя и имя группы пользователя """ if not groupName: groupName = userName import pwd try: uid = pwd.getpwnam(userName)[2] except: self.printERROR(_("User %s not found on this system")%userName) return () try: import grp gid = grp.getgrnam(groupName)[2] except: self.printERROR(_("Group %s not found on this system")\ %groupName) return () return (uid, gid) def __restoreDelUser(self,userName,service,srcDir,message,unixObj=False): """Возвращаем данные удаленного пользователя""" # Ищем Unix пользователя searchUnixUser = self.servicesAPIObj.searchUnixUser(userName, unixObj) # id пользователя strUid = "" if searchUnixUser: strUid = searchUnixUser[0][0][1]['uidNumber'][0] else: resPasswd = self.servicesAPIObj.searchPasswdUser(userName, unixObj) 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 = dialogYesNo(message) if dialogRes and dialogRes == True: try: copyDir(srcDir, delBackDir) except: self.printERROR( _("Failed to restore user data in directory %s")\ %srcDir) return False self.printSUCCESS(_("Restore user data is in directory %s")\ %srcDir) return "Yes", delBackDir elif dialogRes == False: return "No", delBackDir elif dialogRes == None: return "Cancel", delBackDir return True def restorePathDelUser(self,userName,destDir,relDir,message,unixObj=False): """Восстанавливает директорию удаленного пользователя""" removedDir = 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": try: removeDir(resRestore[1]) except: flagError = True if not flagError: removedDir = resRestore[1] term = False elif resRestore[0] == "Yes": createDir = False removedDir = resRestore[1] term = True if flagError or term == "": return False else: return (term, createDir, removedDir) def backupDelUser(self, userName, service, srcDir, unixObj=False): """Сохраняем данные удаляемого пользователя""" # Ищем Unix пользователя searchUnixUser = self.servicesAPIObj.searchUnixUser(userName, unixObj) # 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 in directory %s")\ %delBackDir) self.printERROR(_("Unable to create directory %s for storing " "deleted user data")\ %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: copyDir(delBackDir,srcDir) except: self.printERROR( _("Failed to copy deleted user data in directory %s")\ %delBackDir) return False self.printSUCCESS( _("Created a directory for storing deleted user data")\ %delBackDir) return True def removeEmptyDir(self, rmDir): """Удаление пустых директорий""" if not os.path.exists(rmDir): self.printERROR(_("Directory %s, to be removed, not found") %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 does not exist") %userDir) return False fd = os.open(fileName, os.O_CREAT) os.close(fd) os.chmod(fileName, mode) os.chown(fileName,uid,gid) if fileTxt: FD = open(fileName, "r+") FD.write(fileTxt) FD.close() return True def getUserAllowNetwork(self, strPrompt, strNetAllow): """Получаем от пользователя доверительные сети вывод - список доверительных сетей """ def printW(): cl_overriding.printSUCCESS( _("Incorrect string of available networks")) cl_overriding.printSUCCESS(\ _("Example - allow networks: 10.0.0.0/24 10.0.10.0/24")) cl_overriding.printSUCCESS(_("Try again\n")) strNet = rawInput(strPrompt, strNetAllow) i = 0 while i<3 and not isCorrectStringNet(strNet): printW() strNet = rawInput(strPrompt, strNet) i +=1 if i == 3 and not isCorrectStringNet(strNet): printW() self.printERROR(_("You used four attempts, \ if you want to continue to run the program again")) return False return isCorrectStringNet(strNet)