Added module cl_client_cache

master3.3
Самоукин Алексей 14 years ago
parent 76c1266e32
commit 04f532b012

@ -0,0 +1,559 @@
#-*- 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 cl_ldap import ldapUser
from cl_lang import lang
lang().setLanguage(sys.modules[__name__])
class _shareData(color_print):
"""Share class"""
data = []
#_reNumb = re.compile("^\d+$")
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(_("Can not read to file")+": "+self.fileName)
return False
elif perm == "WRITE":
if os.access(self.fileName, os.W_OK):
return True
else:
self.printERROR(_("Can not 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
self.data[index] = listData
if flagFound:
return True
else:
return None
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
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
class _shareCache():
def save(self):
path = os.path.dirname(self.fileName)
if not os.path.exists(path):
try:
os.makedirs(path)
except:
self.printERROR(_("Can not create directory %s")%path)
return False
if not os.path.exists(self.fileName):
try:
open(self.fileName, "w")
except:
self.printERROR(_("Can not create file %s")%self.fileName)
return False
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 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"
class cacheShadow(_shareCache, shadow):
fileName = "/var/lib/calculate/calculate-client/cache/shadow"
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(_("Can not found user %s in LDAP")%userName)
return False
passwdObj = passwd()
userData = passwdObj.get(userName)
if userData is False:
return False
elif userData:
self.printWARNING(_("User %s found in /etc/passwd")%userName)
self.printWARNING(\
_("User Account will not be recorded in the cache"))
return True
groupName = ldapData['group']
groupObj = group()
# is cached group?
flagCacheGroup = True
groupData = groupObj.get(groupName)
if groupData is False:
return False
elif groupData:
flagCacheGroup = False
# 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
# Add group
if flagCacheGroup:
cacheGroupObj = cacheGroup()
if not cacheGroupObj.add(groupName,ldapData['gid']):
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 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]
flagDeleteGroup = len(filter(lambda x:x[3]==gid,cachePasswdObj.data))==1
# delete user
if not cachePasswdObj.delete(userName):
return False
if not cachePasswdObj.save():
return False
# delete shadow user
cacheShadowObj = cacheShadow()
if not cacheShadowObj.delete(userName):
return False
if not cacheShadowObj.save():
return False
# delete group
if flagDeleteGroup:
cacheGroupObj = cacheGroup()
cacheListGroupData = cacheGroupObj.getData()
if cacheListGroupData is False:
return False
cacheGroupData = map(lambda x: x[0], filter(lambda x: x[2]==gid,
cacheListGroupData))
# delete group
if cacheGroupData:
groupName = cacheGroupData[0]
if not cacheGroupObj.delete(groupName):
return False
if not cacheGroupObj.save():
return False
return True
def delUserFromSystem(self, userName):
'''Delete LDAP user from system files ( passwd, group, shadow )'''
cachePasswdObj = cachePasswd()
cacheUserData = cachePasswdObj.get(userName)
if cacheUserData is False:
return False
if not cacheUserData:
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
gid = userData[3]
cacheGroupObj = cacheGroup()
cacheListGroupData = cacheGroupObj.getData()
if cacheListGroupData is False:
return False
cacheGroupData = map(lambda x: x[0], filter(lambda x: x[2]==gid,
cacheListGroupData))
# delete group
if cacheGroupData:
groupName = cacheGroupData[0]
groupObj = group()
groupData = groupObj.get(groupName)
if groupData is False:
return False
if not groupObj.delete(groupName):
return False
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
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'''
cachePasswdObj = cachePasswd()
cacheListPasswdData = cachePasswdObj.getData()
if cacheListPasswdData is False:
return False
delUsersPasswd = map(lambda x: x[0], cacheListPasswdData)
passwdObj = passwd()
for delUser in delUsersPasswd:
if not passwdObj.delete(delUser):
return False
if delUsersPasswd:
if not passwdObj.save():
return False
cacheShadowObj = cacheShadow()
cacheListShadowData = cacheShadowObj.getData()
if cacheListShadowData is False:
return False
delUsersShadow = map(lambda x: x[0], cacheListShadowData)
shadowObj = shadow()
for delUser in delUsersShadow:
if not shadowObj.delete(delUser):
return False
if delUsersShadow:
if not shadowObj.save():
return False
cacheGroupObj = cacheGroup()
cacheListGroupData = cacheGroupObj.getData()
if cacheListGroupData is False:
return False
delGroups = map(lambda x: x[0], cacheListGroupData)
groupObj = group()
for delGroup in delGroups:
if not groupObj.delete(delGroup):
return False
if delGroups:
if not groupObj.save():
return False
return True
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()
for cachePasswdData in cacheListPasswdData:
userName, x, uid, gid, gecos, directory, shell = cachePasswdData
if not passwdObj.add(userName, uid, gid,
gecos=gecos,
directory=directory,
shell=shell):
return False
if cacheListPasswdData:
if not passwdObj.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 not shadowObj.add(userName, pwdHash,
shadowLastChange=shadowLastChange,
shadowMin=shadowMin,
shadowMax=shadowMax,
shadowWarning=shadowWarning):
return False
if cacheListShadowData:
if not shadowObj.save():
return False
cacheGroupObj = cacheGroup()
cacheListGroupData = cacheGroupObj.getData()
if cacheListGroupData is False:
return False
# Add cache group users to system
groupObj = group()
for cacheGroupData in cacheListGroupData:
groupName, x, gid, x = cacheGroupData
if not groupObj.add(groupName, gid):
return False
if cacheListGroupData:
if not groupObj.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(_("Can not conected to 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
userShadowDict = {'uid': uid,
'gid': gid,
'fullName': gecos,
'home': directory,
'group': groupName,
'loginShell':shell,
'shadowLastChange':shadowLastChange,
'shadowMin':shadowMin,
'shadowMax':shadowMax,
'shadowWarning':shadowWarning}
flagDeleteUser = False
for attr, value in userShadowDict.items():
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
# sync groups
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
deletedCacheGroups = []
for cacheGroupData in cacheListGroupData:
groupName, x , gid, x = cacheGroupData
if not filter(lambda x: x[3]==gid, cacheListPasswdData):
deletedCacheGroups.append(groupName)
# Delete groups
for delGroupName in deletedCacheGroups:
if not cacheGroupObj.delete(cacheGroupObj):
return False
if deletedCacheGroups:
if not cacheGroupObj.save():
return False
return True
def clearCache(self):
'''Clear cache files'''
cacheObjs = (cachePasswd(), cacheShadow(), cacheGroup())
for cacheObj in cacheObjs:
if not cacheObj.save():
return False
return True
Loading…
Cancel
Save