#-*- coding: utf-8 -*- # Copyright 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, sys, re, time from cl_utils import pathJoin from cl_print import color_print from encrypt import encrypt from os import path from cl_utils import pathJoin from cl_lang import lang lang().setLanguage(sys.modules[__name__]) class _shareData: """Share class""" _reNumb = re.compile("^\d+$") def getDataInFile(self, fileName='', lenData=7): """Get data list from file""" return filter(lambda x: len(x)==lenData, map(lambda x: x.rstrip().split(":"), open(fileName))) class migrateGroups(_shareData): """Migrate group to new system""" maxGid = 65000 minGid = 1000 fileGroups = "/etc/group" def __init__(self, prefixNewSystem): self.prefixNewSystem = prefixNewSystem def getData(self, fileName=''): if not fileName: fileName = self.fileGroups return self.getDataInFile(fileName=fileName, lenData=4) def getThisData(self): """Get data migrate groups in this system""" return filter(lambda x:\ self._reNumb.match(x[2]) and self.minGid<=int(x[2])<=self.maxGid, self.getData()) def getNewData(self): """Get data migrate groups in new system""" fileName = pathJoin(self.prefixNewSystem, self.fileGroups) return filter(lambda x:\ self._reNumb.match(x[2]) and self.minGid<=int(x[2])<=self.maxGid, self.getData(fileName=fileName)) def getNewDataSystemGroups(self): """Get data system groups in new system""" fileName = pathJoin(self.prefixNewSystem, self.fileGroups) return filter(lambda x:\ self._reNumb.match(x[2]) and\ (int(x[2])>self.maxGid or int(x[2])self.maxId) or int(x[2])self.maxId) or int(x[2])=self.minSysId, self.dataUsers): return True else: # add user guest pwd = "guest" encryptObj = encrypt() pwdHash = encryptObj.getHashPasswd(pwd, "shadow_ssha256") if pwdHash is False: return False if not self.addUser("guest", pwdHash): return False return True def createHomeDirs(self,addUsersList,existsMigrateUsers): """Create home directories for all migreate users""" def createHome(userdata): if not userdata[5].startswith('/dev/'): homedir = pathJoin(self.prefixNewSystem,userdata[5]) if not path.exists(homedir): os.mkdir(homedir) os.chown(homedir,int(userdata[2]),int(userdata[3])) users = list(set(map(lambda x:x[0],addUsersList)+existsMigrateUsers)-\ set(["root"])) try: map(createHome,filter(lambda x:x[0] in users, self.dataUsers)) except Exception,e: raise DistributiveError( _("Failed to create the user's home directory")) def migrate(self, addUsersList=[], pwdUsersList=[], existsMigrateUsers=[]): """Migrate users ang groups to new system""" if not self.checkPermFiles(): return False migrateUsers = map(lambda x: x[0], addUsersList + pwdUsersList) for existMigrUser in existsMigrateUsers: if not existMigrUser in migrateUsers: migrateUsers.append(existMigrUser) # add root to migrate users dataUsers = self.objUsers.getNewProcessedData(migrateUsers) dataGroups = self.objGroups.getNewProcessedData() thisSystemUsers, newSystemUsers, newUsers, thisUsers =\ map(lambda x: map(lambda y: y[0],x), dataUsers) objShadow = migrateShadow(thisSystemUsers, newSystemUsers, newUsers, thisUsers, self.prefixNewSystem) dataShadow = objShadow.getNewProcessedData() self.dataGroups = reduce(lambda x,y: x+y, dataGroups, []) self.dataUsers = reduce(lambda x,y: x+y, dataUsers, []) self.dataShadow = reduce(lambda x,y: x+y, dataShadow, []) self.addThisUsersToGroups(thisUsers) for userName, pwdHash, maxDays, warnDays in pwdUsersList: if not self.changePassword(userName, pwdHash, maxDays=maxDays, warnDays=warnDays): return False for userName, pwdHash in addUsersList: if self.isSystemUser(userName): self.printERROR(_("%s is a system user") %userName) return False ret = self.addUser(userName, pwdHash) if not ret: return False elif ret == "EXISTS": if not self.changePassword(userName, pwdHash): return False if not newUsers or not thisUsers: # add user guest if not self.createUserGuest(): return False self.saveNewFiles() self.createHomeDirs(addUsersList,existsMigrateUsers) return True class currentUsers(migrate): """Current users""" def __init__(self): self.prefixNewSystem = '/' self.objGroups = migrateGroups(self.prefixNewSystem) self.objUsers = migrateUsers(self.prefixNewSystem) def addUsers(self,*users_passwd): """Added users and groups to current system""" if not self.checkPermFiles(): return False getDataInFile = _shareData().getDataInFile self.dataUsers = getDataInFile(fileName=migrateUsers.filePasswd, lenData=7) self.dataGroups = getDataInFile(fileName=migrateGroups.fileGroups, lenData=4) self.dataShadow = getDataInFile(fileName=migrateShadow.fileShadow, lenData=9) getHash = encrypt().getHashPasswd for userName, pwd in zip(users_passwd[0::2], users_passwd[1::2]): pwdHash = getHash(pwd,"shadow_ssha256") if not self.addUser(userName, pwdHash): return False self.saveNewFiles() return True def hasUsers(self,*users): """Is users in system""" if not self.checkPermFiles(): return False getDataInFile = _shareData().getDataInFile self.dataUsers = map(lambda x:x[0], getDataInFile(fileName=migrateUsers.filePasswd,lenData=7)) return set(self.dataUsers) >= set(users)