|
|
|
|
#-*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
# Copyright 2012-2013 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, time
|
|
|
|
|
from calculate.lib.utils.files import getModeFile
|
|
|
|
|
from calculate.lib.cl_print import color_print
|
|
|
|
|
from calculate.lib.cl_ldap import ldapUser
|
|
|
|
|
|
|
|
|
|
from calculate.lib.cl_lang import setLocalTranslate
|
|
|
|
|
setLocalTranslate('cl_client3',sys.modules[__name__])
|
|
|
|
|
|
|
|
|
|
class _shareData(color_print):
|
|
|
|
|
"""Share class"""
|
|
|
|
|
data = []
|
|
|
|
|
|
|
|
|
|
def getDataInFile(self, fileName='', lenData=0):
|
|
|
|
|
"""Get data list from file"""
|
|
|
|
|
return filter(lambda x: len(x)==lenData,
|
|
|
|
|
map(lambda x: x.rstrip().split(":"), open(fileName)))
|
|
|
|
|
|
|
|
|
|
def getFileAccess(self, perm="READ"):
|
|
|
|
|
if perm == "READ":
|
|
|
|
|
if os.access(self.fileName, os.R_OK):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Failed to read the file")+_(": ") +
|
|
|
|
|
self.fileName)
|
|
|
|
|
return False
|
|
|
|
|
elif perm == "WRITE":
|
|
|
|
|
if os.access(self.fileName, os.W_OK):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Failed to write to file")+_(": ") +
|
|
|
|
|
self.fileName)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getData(self):
|
|
|
|
|
if id(_shareData.data) == id(self.data):
|
|
|
|
|
self.data = self.data[:]
|
|
|
|
|
if self.data:
|
|
|
|
|
return self.data
|
|
|
|
|
elif self.getFileAccess(perm="READ"):
|
|
|
|
|
self.data = self.getDataInFile(fileName=self.fileName,
|
|
|
|
|
lenData=self.lenData)
|
|
|
|
|
return self.data
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def save(self):
|
|
|
|
|
if self.getFileAccess(perm="WRITE"):
|
|
|
|
|
buff = "\n".join(map(lambda x: ":".join(x), self.data)) + "\n"
|
|
|
|
|
FD = open(self.fileName, "w+")
|
|
|
|
|
FD.write(buff)
|
|
|
|
|
FD.close()
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def delete(self, name):
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
self.data = filter(lambda x: x[0]!=name, self.data)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def replace(self, name, listData):
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
flagFound = False
|
|
|
|
|
for index, listDataOld in enumerate(self.data):
|
|
|
|
|
if name == listDataOld[0]:
|
|
|
|
|
flagFound = True
|
|
|
|
|
if not self.equally(listData, self.data[index]):
|
|
|
|
|
self.data[index] = listData
|
|
|
|
|
if flagFound:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def equally(self, listDataA, listDataB):
|
|
|
|
|
if set(listDataA) == set(listDataB):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def get(self, name):
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
listData = filter(lambda x: x[0]==name, self.data)
|
|
|
|
|
if listData:
|
|
|
|
|
return listData[0]
|
|
|
|
|
else:
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
class passwd(_shareData):
|
|
|
|
|
'''Class for working with the file /etc/passwd'''
|
|
|
|
|
fileName = "/etc/passwd"
|
|
|
|
|
template = "%(login)s:x:%(uid)s:%(gid)s:%(gecos)s:%(directory)s:%(shell)s"
|
|
|
|
|
lenData = 7
|
|
|
|
|
|
|
|
|
|
def add(self, name, uid, gid, gecos="", directory="", shell="/bin/bash"):
|
|
|
|
|
if not directory:
|
|
|
|
|
directory = "/home/%s" %name
|
|
|
|
|
userData = self.template%{'login':name, 'uid':uid, 'gid':gid,
|
|
|
|
|
'gecos':gecos, 'directory':directory,
|
|
|
|
|
'shell':shell}
|
|
|
|
|
userList = userData.split(":")
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
ret = self.replace(name, userList)
|
|
|
|
|
if ret is False:
|
|
|
|
|
return False
|
|
|
|
|
elif ret is None:
|
|
|
|
|
self.data.append(userList)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class group(_shareData):
|
|
|
|
|
'''Class for working with the file /etc/group'''
|
|
|
|
|
fileName = "/etc/group"
|
|
|
|
|
template = "%(group_name)s:x:%(gid)s:%(user_list)s"
|
|
|
|
|
lenData = 4
|
|
|
|
|
|
|
|
|
|
def add(self, name, gid, userList=[]):
|
|
|
|
|
groupData = self.template%{'group_name':name, 'gid':gid,
|
|
|
|
|
'user_list':','.join(userList)}
|
|
|
|
|
groupList = groupData.split(":")
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
ret = self.replace(name, groupList)
|
|
|
|
|
if ret is False:
|
|
|
|
|
return False
|
|
|
|
|
elif ret is None:
|
|
|
|
|
self.data.append(groupList)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def replace(self, name, listData):
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
delEmpty = lambda y: filter(lambda x: x.strip(), y)
|
|
|
|
|
flagFound = False
|
|
|
|
|
for index, listDataOld in enumerate(self.data):
|
|
|
|
|
if name == listDataOld[0]:
|
|
|
|
|
flagFound = True
|
|
|
|
|
if not self.equally(listData, self.data[index]):
|
|
|
|
|
listDataWork = listData[:]
|
|
|
|
|
listDataWork[1] = self.data[index][1]
|
|
|
|
|
# Constant gid
|
|
|
|
|
listDataWork[2] = self.data[index][2]
|
|
|
|
|
# Join user list
|
|
|
|
|
userList = delEmpty(self.data[index][3].split(',') +\
|
|
|
|
|
listDataWork[3].split(','))
|
|
|
|
|
# unique list
|
|
|
|
|
userList = reduce(lambda x,y:\
|
|
|
|
|
(y in x and x) or x +[y],
|
|
|
|
|
userList,[])
|
|
|
|
|
listDataWork[3] = ','.join(userList)
|
|
|
|
|
self.data[index] = listDataWork
|
|
|
|
|
if flagFound:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def equally(self, listDataA, listDataB):
|
|
|
|
|
getData = lambda x: x[:1] + x[3:]
|
|
|
|
|
return _shareData.equally(self, getData(listDataA),
|
|
|
|
|
getData(listDataB))
|
|
|
|
|
|
|
|
|
|
def getSecondUserGroups(self, userName):
|
|
|
|
|
"""get all second user groups"""
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
userGroups = []
|
|
|
|
|
for group, x, gid, userList in self.data:
|
|
|
|
|
usersInGroup = userList.split(",")
|
|
|
|
|
if userName in usersInGroup:
|
|
|
|
|
userGroups.append(group)
|
|
|
|
|
return userGroups
|
|
|
|
|
|
|
|
|
|
def getUsersInGroup(self, name):
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
dataGroup = map(lambda x: x[3].split(","),
|
|
|
|
|
filter(lambda x: x[0]==name, self.data))
|
|
|
|
|
if dataGroup:
|
|
|
|
|
return dataGroup[0]
|
|
|
|
|
else:
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
def deleteUserInGroups(self, userName, groups):
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
data = []
|
|
|
|
|
for dataList in self.data:
|
|
|
|
|
groupName, x, gid, userList = dataList
|
|
|
|
|
if groupName in groups:
|
|
|
|
|
usersList = ",".join(filter(lambda x: x!=userName,
|
|
|
|
|
userList.split(",")))
|
|
|
|
|
dataList[3] = usersList
|
|
|
|
|
data.append(dataList)
|
|
|
|
|
self.data = data
|
|
|
|
|
return self.data
|
|
|
|
|
|
|
|
|
|
class shadow(_shareData):
|
|
|
|
|
'''Class for working with the file /etc/shadow'''
|
|
|
|
|
fileName = "/etc/shadow"
|
|
|
|
|
template = "%(login)s:%(hash)s:%(shadowLastChange)s:\
|
|
|
|
|
%(shadowMin)s:%(shadowMax)s:%(shadowWarning)s:::"
|
|
|
|
|
lenData = 9
|
|
|
|
|
|
|
|
|
|
def add(self, name, pwdHash,
|
|
|
|
|
shadowLastChange=str(int(time.time()/86400)), shadowMin="0",
|
|
|
|
|
shadowMax="99999", shadowWarning="7"):
|
|
|
|
|
shadowData = self.template%{'login':name, 'hash':pwdHash,
|
|
|
|
|
'shadowLastChange':shadowLastChange,
|
|
|
|
|
'shadowMin':shadowMin,
|
|
|
|
|
'shadowMax':shadowMax,
|
|
|
|
|
'shadowWarning':shadowWarning}
|
|
|
|
|
shadowList = shadowData.split(":")
|
|
|
|
|
if self.getData() is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
ret = self.replace(name, shadowList)
|
|
|
|
|
if ret is False:
|
|
|
|
|
return False
|
|
|
|
|
elif ret is None:
|
|
|
|
|
self.data.append(shadowList)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def equally(self, listDataA, listDataB):
|
|
|
|
|
getData = lambda x: x[:1] + x[2:]
|
|
|
|
|
return _shareData.equally(self, getData(listDataA),
|
|
|
|
|
getData(listDataB))
|
|
|
|
|
|
|
|
|
|
class _shareCache():
|
|
|
|
|
|
|
|
|
|
def save(self):
|
|
|
|
|
path = os.path.dirname(self.fileName)
|
|
|
|
|
if not os.path.exists(path):
|
|
|
|
|
try:
|
|
|
|
|
os.makedirs(path)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("Failed to create directory %s")%path)
|
|
|
|
|
return False
|
|
|
|
|
if not os.path.exists(self.fileName):
|
|
|
|
|
try:
|
|
|
|
|
open(self.fileName, "w")
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("Failed to create file %s")%self.fileName)
|
|
|
|
|
return False
|
|
|
|
|
if self.getFileAccess(perm="WRITE"):
|
|
|
|
|
modeFile = 0600
|
|
|
|
|
if getModeFile(self.fileName, mode="mode") != modeFile:
|
|
|
|
|
os.chmod(self.fileName, modeFile)
|
|
|
|
|
buff = "\n".join(map(lambda x: ":".join(x), self.data)) + "\n"
|
|
|
|
|
FD = open(self.fileName, "w+")
|
|
|
|
|
FD.write(buff)
|
|
|
|
|
FD.close()
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getData(self):
|
|
|
|
|
if id(_shareData.data) == id(self.data):
|
|
|
|
|
self.data = self.data[:]
|
|
|
|
|
if self.data:
|
|
|
|
|
return self.data
|
|
|
|
|
elif not os.path.exists(self.fileName):
|
|
|
|
|
return self.data
|
|
|
|
|
elif self.getFileAccess(perm="READ"):
|
|
|
|
|
self.data = self.getDataInFile(fileName=self.fileName,
|
|
|
|
|
lenData=self.lenData)
|
|
|
|
|
return self.data
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
class cachePasswd(_shareCache, passwd):
|
|
|
|
|
fileName = "/var/lib/calculate/calculate-client/cache/passwd"
|
|
|
|
|
|
|
|
|
|
class cacheGroup(_shareCache, group):
|
|
|
|
|
fileName = "/var/lib/calculate/calculate-client/cache/group"
|
|
|
|
|
|
|
|
|
|
def replace(self, name, listData):
|
|
|
|
|
return _shareData.replace(self, name, listData)
|
|
|
|
|
|
|
|
|
|
def equally(self, listDataA, listDataB):
|
|
|
|
|
return _shareData.equally(self, listDataA, listDataB)
|
|
|
|
|
|
|
|
|
|
class cacheShadow(_shareCache, shadow):
|
|
|
|
|
fileName = "/var/lib/calculate/calculate-client/cache/shadow"
|
|
|
|
|
|
|
|
|
|
class cacheCreateGroup(cacheGroup):
|
|
|
|
|
fileName = "/var/lib/calculate/calculate-client/cache/create_group"
|
|
|
|
|
|
|
|
|
|
class cacheCreatePasswd(cachePasswd):
|
|
|
|
|
fileName = "/var/lib/calculate/calculate-client/cache/create_passwd"
|
|
|
|
|
|
|
|
|
|
class userCache(color_print):
|
|
|
|
|
ldapObj = ldapUser()
|
|
|
|
|
|
|
|
|
|
def addUserToCache(self, userName, pwdHash):
|
|
|
|
|
'''Add LDAP user to cache'''
|
|
|
|
|
ldapData = self.ldapObj.getUserLdapInfo(userName, shadowAttr=True)
|
|
|
|
|
if not ldapData:
|
|
|
|
|
self.printERROR(_("User %s not found in LDAP")%userName)
|
|
|
|
|
return False
|
|
|
|
|
groupName = ldapData['group']
|
|
|
|
|
# Add user
|
|
|
|
|
cachePasswdObj = cachePasswd()
|
|
|
|
|
if not cachePasswdObj.add(userName, ldapData['uid'], ldapData['gid'],
|
|
|
|
|
gecos=ldapData['fullName'],
|
|
|
|
|
directory=ldapData['home'],
|
|
|
|
|
shell=ldapData['loginShell']):
|
|
|
|
|
return False
|
|
|
|
|
if not cachePasswdObj.save():
|
|
|
|
|
return False
|
|
|
|
|
cacheGroupObj = cacheGroup()
|
|
|
|
|
# Add primary group
|
|
|
|
|
if not cacheGroupObj.add(groupName,ldapData['gid']):
|
|
|
|
|
return False
|
|
|
|
|
# Add second groups
|
|
|
|
|
secondGroupsData = ldapData['groups']
|
|
|
|
|
cacheSecondUserGroups = cacheGroupObj.getSecondUserGroups(userName)
|
|
|
|
|
deleteSecondGroups = cacheSecondUserGroups
|
|
|
|
|
if secondGroupsData:
|
|
|
|
|
allUsersSecondGroups = []
|
|
|
|
|
for groupName, gid in secondGroupsData:
|
|
|
|
|
usersInGroup = cacheGroupObj.getUsersInGroup(groupName)
|
|
|
|
|
if usersInGroup is False:
|
|
|
|
|
return False
|
|
|
|
|
if not userName in usersInGroup:
|
|
|
|
|
usersInGroup.append(userName)
|
|
|
|
|
if not cacheGroupObj.add(groupName, gid, usersInGroup):
|
|
|
|
|
return False
|
|
|
|
|
allUsersSecondGroups.append(groupName)
|
|
|
|
|
deleteSecondGroups = list(set(cacheSecondUserGroups) -\
|
|
|
|
|
set(allUsersSecondGroups))
|
|
|
|
|
if not cacheGroupObj.deleteUserInGroups(userName, deleteSecondGroups):
|
|
|
|
|
return False
|
|
|
|
|
if not cacheGroupObj.save():
|
|
|
|
|
return False
|
|
|
|
|
# Add shadow user
|
|
|
|
|
cacheShadowObj = cacheShadow()
|
|
|
|
|
if not cacheShadowObj.add(userName, pwdHash,
|
|
|
|
|
shadowLastChange=ldapData['shadowLastChange'],
|
|
|
|
|
shadowMin=ldapData['shadowMin'],
|
|
|
|
|
shadowMax=ldapData['shadowMax'],
|
|
|
|
|
shadowWarning=ldapData['shadowWarning']):
|
|
|
|
|
return False
|
|
|
|
|
if not cacheShadowObj.save():
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUserFromCacheCreate(self, userName):
|
|
|
|
|
'''Delete LDAP user from createCache'''
|
|
|
|
|
cacheCreatePasswdObj = cacheCreatePasswd()
|
|
|
|
|
cacheUserData = cacheCreatePasswdObj.get(userName)
|
|
|
|
|
if cacheUserData is False:
|
|
|
|
|
return False
|
|
|
|
|
if not cacheUserData:
|
|
|
|
|
return True
|
|
|
|
|
gid = cacheUserData[3]
|
|
|
|
|
cacheCreateGroupObj = cacheCreateGroup()
|
|
|
|
|
cacheSecondGroups = cacheCreateGroupObj.getSecondUserGroups(userName)
|
|
|
|
|
if cacheSecondGroups is False:
|
|
|
|
|
return False
|
|
|
|
|
# delete user in second groups
|
|
|
|
|
if not cacheCreateGroupObj.deleteUserInGroups(userName,
|
|
|
|
|
cacheSecondGroups):
|
|
|
|
|
return False
|
|
|
|
|
# delete user
|
|
|
|
|
if not cacheCreatePasswdObj.delete(userName):
|
|
|
|
|
return False
|
|
|
|
|
if not cacheCreatePasswdObj.save():
|
|
|
|
|
return False
|
|
|
|
|
#delete groups
|
|
|
|
|
usersGids = map(lambda x: x[3], cacheCreatePasswdObj.data)
|
|
|
|
|
deleteGroups = map(lambda x: x[0],
|
|
|
|
|
filter(lambda x: not x[2] in usersGids and not x[3],
|
|
|
|
|
cacheCreateGroupObj.data))
|
|
|
|
|
for delGroupName in deleteGroups:
|
|
|
|
|
if not cacheCreateGroupObj.delete(delGroupName):
|
|
|
|
|
return False
|
|
|
|
|
if not cacheCreateGroupObj.save():
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUserFromCache(self, userName):
|
|
|
|
|
'''Delete LDAP user from cache'''
|
|
|
|
|
cachePasswdObj = cachePasswd()
|
|
|
|
|
cacheUserData = cachePasswdObj.get(userName)
|
|
|
|
|
if cacheUserData is False:
|
|
|
|
|
return False
|
|
|
|
|
if not cacheUserData:
|
|
|
|
|
return True
|
|
|
|
|
gid = cacheUserData[3]
|
|
|
|
|
cacheGroupObj = cacheGroup()
|
|
|
|
|
cacheSecondGroups = cacheGroupObj.getSecondUserGroups(userName)
|
|
|
|
|
if cacheSecondGroups is False:
|
|
|
|
|
return False
|
|
|
|
|
# delete user in second groups
|
|
|
|
|
if not cacheGroupObj.deleteUserInGroups(userName, cacheSecondGroups):
|
|
|
|
|
return False
|
|
|
|
|
# delete user
|
|
|
|
|
if not cachePasswdObj.delete(userName):
|
|
|
|
|
return False
|
|
|
|
|
if not cachePasswdObj.save():
|
|
|
|
|
return False
|
|
|
|
|
#delete groups
|
|
|
|
|
usersGids = map(lambda x: x[3], cachePasswdObj.data)
|
|
|
|
|
deleteGroups = map(lambda x: x[0],
|
|
|
|
|
filter(lambda x: not x[2] in usersGids and not x[3],
|
|
|
|
|
cacheGroupObj.data))
|
|
|
|
|
for delGroupName in deleteGroups:
|
|
|
|
|
if not cacheGroupObj.delete(delGroupName):
|
|
|
|
|
return False
|
|
|
|
|
if not cacheGroupObj.save():
|
|
|
|
|
return False
|
|
|
|
|
# delete shadow user
|
|
|
|
|
cacheShadowObj = cacheShadow()
|
|
|
|
|
if not cacheShadowObj.delete(userName):
|
|
|
|
|
return False
|
|
|
|
|
if not cacheShadowObj.save():
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUserFromSystem(self, userName):
|
|
|
|
|
'''Delete LDAP user from system files ( passwd, group, shadow )'''
|
|
|
|
|
cacheCreatePasswdObj = cacheCreatePasswd()
|
|
|
|
|
cacheCreatePasswdData = cacheCreatePasswdObj.get(userName)
|
|
|
|
|
if cacheCreatePasswdData is False:
|
|
|
|
|
return False
|
|
|
|
|
if not cacheCreatePasswdData:
|
|
|
|
|
return True
|
|
|
|
|
passwdObj = passwd()
|
|
|
|
|
userData = passwdObj.get(userName)
|
|
|
|
|
if userData is False:
|
|
|
|
|
return False
|
|
|
|
|
# delete user
|
|
|
|
|
if not userData:
|
|
|
|
|
return True
|
|
|
|
|
if not passwdObj.delete(userName):
|
|
|
|
|
return False
|
|
|
|
|
if not passwdObj.save():
|
|
|
|
|
return False
|
|
|
|
|
# delete user group
|
|
|
|
|
groupObj = group()
|
|
|
|
|
listGroupData = groupObj.getData()
|
|
|
|
|
if listGroupData is False:
|
|
|
|
|
return False
|
|
|
|
|
cacheCreateGroupObj = cacheCreateGroup()
|
|
|
|
|
secondUsersGroups = groupObj.getSecondUserGroups(userName)
|
|
|
|
|
usersGids = map(lambda x: x[3], passwdObj.data)
|
|
|
|
|
listGroupDataWork = []
|
|
|
|
|
for index, groupData in enumerate(listGroupData):
|
|
|
|
|
groupName, x, gid, listUsers = groupData
|
|
|
|
|
listUsers = filter(lambda x: x.strip(), listUsers.split(','))
|
|
|
|
|
listUsers = ",".join(filter(lambda x: x!=userName, listUsers))
|
|
|
|
|
cacheCreateGroupData = cacheCreateGroupObj.get(groupName)
|
|
|
|
|
if cacheCreateGroupData is False:
|
|
|
|
|
return False
|
|
|
|
|
if groupName in cacheCreateGroupData:
|
|
|
|
|
if not gid in usersGids and not listUsers:
|
|
|
|
|
continue
|
|
|
|
|
listGroupDataWork.append([groupName, x, gid, listUsers])
|
|
|
|
|
groupObj.data = listGroupDataWork
|
|
|
|
|
if not groupObj.save():
|
|
|
|
|
return False
|
|
|
|
|
# delete user shadow
|
|
|
|
|
shadowObj = shadow()
|
|
|
|
|
shadowData = shadowObj.get(userName)
|
|
|
|
|
if shadowData is False:
|
|
|
|
|
return False
|
|
|
|
|
if not shadowData:
|
|
|
|
|
return True
|
|
|
|
|
if not shadowObj.delete(userName):
|
|
|
|
|
return False
|
|
|
|
|
if not shadowObj.save():
|
|
|
|
|
return False
|
|
|
|
|
if not self.delUserFromCacheCreate(userName):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def isConnectToLdap(self):
|
|
|
|
|
connectData = self.ldapObj.getBindConnectData()
|
|
|
|
|
if not connectData:
|
|
|
|
|
return {}
|
|
|
|
|
bindDn, bindPw, host = connectData
|
|
|
|
|
usersDN = self.ldapObj.getUsersDN()
|
|
|
|
|
groupsDNs = self.ldapObj.getGroupsDN()
|
|
|
|
|
# Соединяемся с LDAP
|
|
|
|
|
if not self.ldapObj.ldapConnect(bindDn, bindPw, host):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def deleteCacheUsersFromSystem(self):
|
|
|
|
|
'''Delete cache users from system'''
|
|
|
|
|
cacheCreatePasswdObj = cacheCreatePasswd()
|
|
|
|
|
cacheCreateListPasswdData = cacheCreatePasswdObj.getData()
|
|
|
|
|
if cacheCreateListPasswdData is False:
|
|
|
|
|
return False
|
|
|
|
|
delUsersPasswd = map(lambda x: x[0], cacheCreateListPasswdData)
|
|
|
|
|
for delUser in delUsersPasswd:
|
|
|
|
|
if not self.delUserFromSystem(delUser):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def getLoginDomainUsers(self):
|
|
|
|
|
'''Get all domain login users'''
|
|
|
|
|
cacheCreatePasswdObj = cacheCreatePasswd()
|
|
|
|
|
cacheListCreatePasswdData = cacheCreatePasswdObj.getData()
|
|
|
|
|
if cacheListCreatePasswdData is False:
|
|
|
|
|
return False
|
|
|
|
|
return cacheListCreatePasswdData
|
|
|
|
|
|
|
|
|
|
def addCacheUsersFromSystem(self):
|
|
|
|
|
'''Add cache users from system'''
|
|
|
|
|
cachePasswdObj = cachePasswd()
|
|
|
|
|
cacheListPasswdData = cachePasswdObj.getData()
|
|
|
|
|
if cacheListPasswdData is False:
|
|
|
|
|
return False
|
|
|
|
|
# Add cache passwd users to system
|
|
|
|
|
passwdObj = passwd()
|
|
|
|
|
cacheCreatePasswdObj = cacheCreatePasswd()
|
|
|
|
|
cacheListCreatePasswdData = cacheCreatePasswdObj.getData()
|
|
|
|
|
if cacheListCreatePasswdData is False:
|
|
|
|
|
return False
|
|
|
|
|
# remove deleted users
|
|
|
|
|
cacheUsers = map(lambda x: x[0], cacheListPasswdData)
|
|
|
|
|
createUsers = map(lambda x: x[0], cacheListCreatePasswdData)
|
|
|
|
|
deletedUsers = list(set(createUsers) - set(cacheUsers))
|
|
|
|
|
for delUser in deletedUsers:
|
|
|
|
|
if not self.delUserFromSystem(delUser):
|
|
|
|
|
return False
|
|
|
|
|
if not self.delUserFromCache(delUser):
|
|
|
|
|
return False
|
|
|
|
|
addUsers = []
|
|
|
|
|
addUsersGid = []
|
|
|
|
|
notAddUsers = []
|
|
|
|
|
for cachePasswdData in cacheListPasswdData:
|
|
|
|
|
userName, x, uid, gid, gecos, directory, shell = cachePasswdData
|
|
|
|
|
retPasswd = passwdObj.get(userName)
|
|
|
|
|
if retPasswd is False:
|
|
|
|
|
return False
|
|
|
|
|
if not retPasswd:
|
|
|
|
|
if not cacheCreatePasswdObj.add(userName, uid, gid,
|
|
|
|
|
gecos=gecos,
|
|
|
|
|
directory=directory,
|
|
|
|
|
shell=shell):
|
|
|
|
|
return False
|
|
|
|
|
retCacheCreate = cacheCreatePasswdObj.get(userName)
|
|
|
|
|
if retCacheCreate is False:
|
|
|
|
|
return False
|
|
|
|
|
if retCacheCreate:
|
|
|
|
|
if not passwdObj.add(userName, uid, gid,
|
|
|
|
|
gecos=gecos,
|
|
|
|
|
directory=directory,
|
|
|
|
|
shell=shell):
|
|
|
|
|
return False
|
|
|
|
|
addUsers.append(userName)
|
|
|
|
|
addUsersGid.append(gid)
|
|
|
|
|
else:
|
|
|
|
|
notAddUsers.append(userName)
|
|
|
|
|
if passwdObj.data:
|
|
|
|
|
if not passwdObj.save():
|
|
|
|
|
return False
|
|
|
|
|
if not cacheCreatePasswdObj.save():
|
|
|
|
|
return False
|
|
|
|
|
cacheShadowObj = cacheShadow()
|
|
|
|
|
cacheListShadowData = cacheShadowObj.getData()
|
|
|
|
|
if cacheListShadowData is False:
|
|
|
|
|
return False
|
|
|
|
|
# Add cache shadow users to system
|
|
|
|
|
shadowObj = shadow()
|
|
|
|
|
for cacheShadowData in cacheListShadowData:
|
|
|
|
|
userName, pwdHash, shadowLastChange, shadowMin, shadowMax,\
|
|
|
|
|
shadowWarning, x,x,x = cacheShadowData
|
|
|
|
|
if userName in addUsers:
|
|
|
|
|
if not shadowObj.add(userName, pwdHash,
|
|
|
|
|
shadowLastChange=shadowLastChange,
|
|
|
|
|
shadowMin=shadowMin,
|
|
|
|
|
shadowMax=shadowMax,
|
|
|
|
|
shadowWarning=shadowWarning):
|
|
|
|
|
return False
|
|
|
|
|
if shadowObj.data:
|
|
|
|
|
if not shadowObj.save():
|
|
|
|
|
return False
|
|
|
|
|
cacheGroupObj = cacheGroup()
|
|
|
|
|
cacheListGroupData = cacheGroupObj.getData()
|
|
|
|
|
if cacheListGroupData is False:
|
|
|
|
|
return False
|
|
|
|
|
cacheCreateGroupObj = cacheCreateGroup()
|
|
|
|
|
# Add cache group users to system
|
|
|
|
|
groupObj = group()
|
|
|
|
|
setAddUsers = set(addUsers)
|
|
|
|
|
for cacheGroupData in cacheListGroupData:
|
|
|
|
|
groupName, x, gid, listUsers = cacheGroupData
|
|
|
|
|
retGroup = groupObj.get(groupName)
|
|
|
|
|
if retGroup is False:
|
|
|
|
|
return False
|
|
|
|
|
listUsers = filter(lambda x: x.strip(), listUsers.split(','))
|
|
|
|
|
if setAddUsers & set(listUsers) or gid in addUsersGid:
|
|
|
|
|
listUsers = filter(lambda x: not x in notAddUsers, listUsers)
|
|
|
|
|
if not retGroup:
|
|
|
|
|
if not cacheCreateGroupObj.add(groupName, gid, listUsers):
|
|
|
|
|
return False
|
|
|
|
|
if not groupObj.add(groupName, gid, listUsers):
|
|
|
|
|
return False
|
|
|
|
|
if groupObj.data:
|
|
|
|
|
if not groupObj.save():
|
|
|
|
|
return False
|
|
|
|
|
if cacheCreateGroupObj.data:
|
|
|
|
|
if not cacheCreateGroupObj.save():
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def syncCacheToLdap(self):
|
|
|
|
|
'''Compare cache users to LDAP users.
|
|
|
|
|
|
|
|
|
|
Deleting a user from the cache when the differences'''
|
|
|
|
|
if not self.isConnectToLdap():
|
|
|
|
|
self.printERROR(_("Failed to connect to the LDAP server"))
|
|
|
|
|
return False
|
|
|
|
|
cachePasswdObj = cachePasswd()
|
|
|
|
|
cacheListPasswdData = cachePasswdObj.getData()
|
|
|
|
|
if cacheListPasswdData is False:
|
|
|
|
|
return False
|
|
|
|
|
if not cacheListPasswdData:
|
|
|
|
|
return True
|
|
|
|
|
cacheGroupObj = cacheGroup()
|
|
|
|
|
cacheListGroupData = cacheGroupObj.getData()
|
|
|
|
|
if cacheListGroupData is False:
|
|
|
|
|
return False
|
|
|
|
|
cacheShadowObj = cacheShadow()
|
|
|
|
|
deletedCacheUsers = []
|
|
|
|
|
for cachePasswdData in cacheListPasswdData:
|
|
|
|
|
userName, x, uid, gid, gecos, directory, shell = cachePasswdData
|
|
|
|
|
ldapData = self.ldapObj.getUserLdapInfo(userName, shadowAttr=True)
|
|
|
|
|
if not ldapData:
|
|
|
|
|
deletedCacheUsers.append(userName)
|
|
|
|
|
continue
|
|
|
|
|
cacheGroupData = map(lambda x: x[0], filter(lambda x: x[2]==gid,
|
|
|
|
|
cacheListGroupData))
|
|
|
|
|
if not cacheGroupData:
|
|
|
|
|
deletedCacheUsers.append(userName)
|
|
|
|
|
continue
|
|
|
|
|
groupName = cacheGroupData[0]
|
|
|
|
|
cacheShadowData = cacheShadowObj.get(userName)
|
|
|
|
|
if cacheShadowData is False:
|
|
|
|
|
return False
|
|
|
|
|
if not cacheShadowData:
|
|
|
|
|
deletedCacheUsers.append(userName)
|
|
|
|
|
continue
|
|
|
|
|
x,x, shadowLastChange, shadowMin, shadowMax, shadowWarning,\
|
|
|
|
|
x,x,x = cacheShadowData
|
|
|
|
|
groups = cacheGroupObj.getSecondUserGroups(userName)
|
|
|
|
|
gidsGroups = map(lambda x: x[2],
|
|
|
|
|
filter(lambda x : x[0] in groups,
|
|
|
|
|
cacheGroupObj.data))
|
|
|
|
|
userShadowDict = {'uid': uid,
|
|
|
|
|
'gid': gid,
|
|
|
|
|
'fullName': gecos,
|
|
|
|
|
'home': directory,
|
|
|
|
|
'group': groupName,
|
|
|
|
|
'groups': (groups,gidsGroups),
|
|
|
|
|
'loginShell':shell,
|
|
|
|
|
'shadowLastChange':shadowLastChange,
|
|
|
|
|
'shadowMin':shadowMin,
|
|
|
|
|
'shadowMax':shadowMax,
|
|
|
|
|
'shadowWarning':shadowWarning}
|
|
|
|
|
flagDeleteUser = False
|
|
|
|
|
for attr, value in userShadowDict.items():
|
|
|
|
|
if attr == "groups":
|
|
|
|
|
for index, val in enumerate(value):
|
|
|
|
|
if set(map(lambda x: x[index],
|
|
|
|
|
ldapData[attr])) != set(val):
|
|
|
|
|
flagDeleteUser = True
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
if ldapData[attr] != value:
|
|
|
|
|
flagDeleteUser = True
|
|
|
|
|
break
|
|
|
|
|
if flagDeleteUser:
|
|
|
|
|
deletedCacheUsers.append(userName)
|
|
|
|
|
continue
|
|
|
|
|
# Deleted cache users
|
|
|
|
|
for delUserName in deletedCacheUsers:
|
|
|
|
|
if not self.delUserFromCache(delUserName):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def clearCache(self):
|
|
|
|
|
'''Clear cache files'''
|
|
|
|
|
cacheObjs = (cachePasswd(), cacheShadow(), cacheGroup(),
|
|
|
|
|
cacheCreateGroup(), cacheCreatePasswd())
|
|
|
|
|
for cacheObj in cacheObjs:
|
|
|
|
|
if not cacheObj.save():
|
|
|
|
|
return False
|
|
|
|
|
return True
|