|
|
|
@ -15,13 +15,21 @@
|
|
|
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
|
|
import os, sys, re
|
|
|
|
|
from cl_print import color_print
|
|
|
|
|
#from cl_print import color_print
|
|
|
|
|
from cl_datavars import DataVars
|
|
|
|
|
from server.utils import execProg
|
|
|
|
|
from cl_template import template
|
|
|
|
|
|
|
|
|
|
from cl_api import packagesAPI, APIError
|
|
|
|
|
from server.ldap import iniLdapParser, ldapFunction, shareldap
|
|
|
|
|
from server.utils import genSleep
|
|
|
|
|
from cl_utils import removeDir, _error
|
|
|
|
|
from cl_lang import lang
|
|
|
|
|
lang().setLanguage(sys.modules[__name__])
|
|
|
|
|
tr = lang()
|
|
|
|
|
tr.setLocalDomain('cl_ldap')
|
|
|
|
|
tr.setLanguage(sys.modules[__name__])
|
|
|
|
|
|
|
|
|
|
__version__ = "2.2.0.0"
|
|
|
|
|
__app__ = "calculate-ldap"
|
|
|
|
|
|
|
|
|
|
from cl_abstract import abs_api_service
|
|
|
|
|
|
|
|
|
@ -64,7 +72,7 @@ class shareVars:
|
|
|
|
|
self.clVars = clVars
|
|
|
|
|
return self.clVars
|
|
|
|
|
|
|
|
|
|
class serviceAPI(abs_api_service, shareVars, Template):
|
|
|
|
|
class internalMethods(abs_api_service, shareVars, Template):
|
|
|
|
|
'''Methods ldap service'''
|
|
|
|
|
prioritet = 25
|
|
|
|
|
nameService = "ldap"
|
|
|
|
@ -89,7 +97,6 @@ class serviceAPI(abs_api_service, shareVars, Template):
|
|
|
|
|
|
|
|
|
|
def get_pkg_name(self):
|
|
|
|
|
'''Get name service'''
|
|
|
|
|
from cl_ldap_service import __app__
|
|
|
|
|
return __app__
|
|
|
|
|
|
|
|
|
|
def get_vars(self):
|
|
|
|
@ -206,6 +213,10 @@ class serviceAPI(abs_api_service, shareVars, Template):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def updateVars(self):
|
|
|
|
|
self.createClVars()
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def get_service_info(self, request):
|
|
|
|
|
'''Get service information'''
|
|
|
|
|
res = ""
|
|
|
|
@ -238,3 +249,225 @@ class serviceAPI(abs_api_service, shareVars, Template):
|
|
|
|
|
self.clVars.Set("cl_ldap_update_action","up", force=True)
|
|
|
|
|
return Template.applyTemplates(self)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class Singleton(object):
|
|
|
|
|
_instance = None
|
|
|
|
|
def __new__(cls, *args, **kwargs):
|
|
|
|
|
if not cls._instance:
|
|
|
|
|
cls._instance = super(Singleton, cls).__new__(
|
|
|
|
|
cls, *args, **kwargs)
|
|
|
|
|
return cls._instance
|
|
|
|
|
|
|
|
|
|
class allMethods(Singleton, internalMethods, shareldap):
|
|
|
|
|
"""Методы севисa Ldap"""
|
|
|
|
|
# Базовый ldif файл
|
|
|
|
|
ldifFileBase = '/usr/lib/calculate-2.2/calculate-ldap/ldif/base.ldif'
|
|
|
|
|
apiFile = '/usr/lib/calculate-2.2/calculate-ldap/pym/cl_ldap_api.py'
|
|
|
|
|
libAPIObj = packagesAPI()
|
|
|
|
|
|
|
|
|
|
def removeLdapDatabase(self):
|
|
|
|
|
"""Удаляем предыдущую базу данных"""
|
|
|
|
|
pathDatabase = "/var/lib/openldap-data"
|
|
|
|
|
#if os.path.exists(pathDatabase) and os.listdir(pathDatabase):
|
|
|
|
|
#if os.system("rm /var/lib/openldap-data/* &>/dev/null") !=0:
|
|
|
|
|
#self.printERROR("Can't remove /var/lib/openldap-data/*")
|
|
|
|
|
#return False
|
|
|
|
|
#return True
|
|
|
|
|
if os.path.exists(pathDatabase):
|
|
|
|
|
fileOrDirNames = os.listdir(pathDatabase)
|
|
|
|
|
if fileOrDirNames:
|
|
|
|
|
for fileOrDirName in fileOrDirNames:
|
|
|
|
|
fullFileOrDirName = os.path.join(pathDatabase,
|
|
|
|
|
fileOrDirName)
|
|
|
|
|
if os.path.isdir(fullFileOrDirName):
|
|
|
|
|
try:
|
|
|
|
|
removeDir(pathDatabase)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("Can't remove directory %s")\
|
|
|
|
|
%fullFileOrDirName)
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
try:
|
|
|
|
|
os.remove(fullFileOrDirName)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("Can't remove file %s")\
|
|
|
|
|
%fullFileOrDirName)
|
|
|
|
|
return False
|
|
|
|
|
self.printOK(_("Erased LDAP Database") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def connectLdapServer(self):
|
|
|
|
|
"""Соединяемся с LDAP сервером
|
|
|
|
|
|
|
|
|
|
используем DN и пароль временного админстратора
|
|
|
|
|
"""
|
|
|
|
|
# Если раннее была ошибка то выходим
|
|
|
|
|
if self.getError():
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
self.getError().strip())
|
|
|
|
|
return False
|
|
|
|
|
tmpDn = self.clVars.Get("ld_temp_dn")
|
|
|
|
|
tmpPw = self.clVars.Get("ld_temp_pw")
|
|
|
|
|
ldapObj = ldapFunction(tmpDn, tmpPw)
|
|
|
|
|
# Генератор задержек
|
|
|
|
|
wait = genSleep()
|
|
|
|
|
while ldapObj.getError():
|
|
|
|
|
try:
|
|
|
|
|
# Задержка
|
|
|
|
|
wait.next()
|
|
|
|
|
except StopIteration:
|
|
|
|
|
break
|
|
|
|
|
# Очистка ошибки
|
|
|
|
|
_error.error = []
|
|
|
|
|
ldapObj = ldapFunction(tmpDn, tmpPw)
|
|
|
|
|
self.ldapObj = ldapObj
|
|
|
|
|
self.conLdap = ldapObj.conLdap
|
|
|
|
|
if ldapObj.getError():
|
|
|
|
|
# Удаляем одинаковые ошибки
|
|
|
|
|
listError = []
|
|
|
|
|
for e in ldapObj.error:
|
|
|
|
|
if not e in listError:
|
|
|
|
|
listError.append(e)
|
|
|
|
|
_error.error = listError
|
|
|
|
|
self.printERROR(_("Can not connected to LDAP server"))
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def setup(self, force=False):
|
|
|
|
|
"""Настройка LDAP сервиса (создание дерева)"""
|
|
|
|
|
# Принудительная установка
|
|
|
|
|
if self.clVars.Get("sr_ldap_set") == "on" and not force:
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("LDAP server is configured")+ ".")
|
|
|
|
|
return True
|
|
|
|
|
if not force:
|
|
|
|
|
# предупреждение при выполнении этой программы будут изменены
|
|
|
|
|
# конфигурационные файлы и база данных сервиса LDAP а также
|
|
|
|
|
# конфигурационные файлы установленных сервисов
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("Executing of the program will change") + " " +\
|
|
|
|
|
_("the configuration files and database of LDAP service")+\
|
|
|
|
|
".")
|
|
|
|
|
# если вы готовы продолжить работу программы нажмите Y если нет n
|
|
|
|
|
messDialog = \
|
|
|
|
|
_("If you are ready to continue executing the program")+", "+\
|
|
|
|
|
_("input 'yes'") +", "+ _("if not 'no'")
|
|
|
|
|
if not dialogYesNo(messDialog):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
# делаем backup
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.is_start():
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.start():
|
|
|
|
|
return False
|
|
|
|
|
#if not self.backupServer():
|
|
|
|
|
#return False
|
|
|
|
|
if self.is_runlevel():
|
|
|
|
|
# Удаляем из автозапуска демона
|
|
|
|
|
if not self.del_runlevel():
|
|
|
|
|
return False
|
|
|
|
|
listAPIObj = self.libAPIObj.all.APIList()
|
|
|
|
|
listAPIObjReverse = self.libAPIObj.all.APIListReverse()
|
|
|
|
|
if filter(lambda x:\
|
|
|
|
|
x.api.get_pkg_name()=="calculate_ldap",listAPIObj):
|
|
|
|
|
self.printERROR(_("Can not found API module in package "
|
|
|
|
|
"calculate-ldap"))
|
|
|
|
|
self.printWARNING(_("Run: cl-ldap-setup --install"))
|
|
|
|
|
return False
|
|
|
|
|
# Останавливаем все установленные сервисы
|
|
|
|
|
for obj in listAPIObjReverse:
|
|
|
|
|
apiObj = obj.api
|
|
|
|
|
if hasattr(apiObj, 'stop') and not apiObj.stop():
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем из автозагрузки все установленные сервисы
|
|
|
|
|
for obj in listAPIObjReverse:
|
|
|
|
|
apiObj = obj.api
|
|
|
|
|
if hasattr(apiObj, 'del_runlevel') and not apiObj.del_runlevel():
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем из крона скрипт для чистки удаленых пользователей
|
|
|
|
|
# создаем объект репликации
|
|
|
|
|
#objRepl = servRepl()
|
|
|
|
|
#if not objRepl.cronReplicationOFF():
|
|
|
|
|
#return False
|
|
|
|
|
# Удаляем из share файл .replrun
|
|
|
|
|
#if not self.servSambaObj.delReplFile(self.clVars):
|
|
|
|
|
#return False
|
|
|
|
|
# Удаляем переменные
|
|
|
|
|
for obj in listAPIObjReverse:
|
|
|
|
|
apiObj = obj.api
|
|
|
|
|
if hasattr(apiObj,'del_vars_from_env') and \
|
|
|
|
|
not apiObj.del_vars_from_env():
|
|
|
|
|
return False
|
|
|
|
|
# Получим путь к ldap файлу
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
ldapFile = ldapParser.nameIniFile
|
|
|
|
|
# Удаляем ldap файл
|
|
|
|
|
if os.path.exists(ldapFile):
|
|
|
|
|
os.remove(ldapFile)
|
|
|
|
|
self.clVars.Write("sr_ldap_set", "off",force=True)
|
|
|
|
|
self.clVars.Set("sr_ldap_set", "on", force=True)
|
|
|
|
|
self.clVars.Set("cl_ldap_setup_action","up", force=True)
|
|
|
|
|
# Первый проход
|
|
|
|
|
self.clVars.Set("cl_pass_step", "1", True)
|
|
|
|
|
if self.applyTemplates() is False:
|
|
|
|
|
self.printERROR(_("Can not apply templates") + ":" + " " +\
|
|
|
|
|
_("first pass"))
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем старую базу данных
|
|
|
|
|
if not self.removeLdapDatabase():
|
|
|
|
|
return False
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.start():
|
|
|
|
|
return False
|
|
|
|
|
# Соединяемся с LDAP временным пользователем
|
|
|
|
|
if not self.connectLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
# Получаем текст нужного ldif-a
|
|
|
|
|
baseLdif = self.createLdif(self.ldifFileBase)
|
|
|
|
|
# Если нет ошибок при соединении применяем ldif
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
self.ldapObj.ldapAdd(baseLdif)
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
self.printOK(_("Added ldif file") + " ...")
|
|
|
|
|
# Второй проход,
|
|
|
|
|
# удаляем временного пользователя root из конфигурационного файла
|
|
|
|
|
self.clVars.Set("cl_pass_step","2",True)
|
|
|
|
|
if self.applyTemplates() is False:
|
|
|
|
|
self.printERROR(_("Can not apply profiles") +":"+ _("second pass"))
|
|
|
|
|
return False
|
|
|
|
|
# Перезапускаем LDAP сервер
|
|
|
|
|
if not self.restart():
|
|
|
|
|
return False
|
|
|
|
|
# Записываем данные администратора сервера
|
|
|
|
|
ldapParser.setVar("admin",
|
|
|
|
|
{"DN":self.clVars.Get("ld_admin_dn"),
|
|
|
|
|
"PASS":self.clVars.Get("ld_admin_pw")})
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.add_runlevel():
|
|
|
|
|
return False
|
|
|
|
|
# Записываем переменные для пользователя
|
|
|
|
|
#clientVars = ["ur_organization", "ur_signature"]
|
|
|
|
|
#if not self.saveVarsClient(clientVars):
|
|
|
|
|
#return False
|
|
|
|
|
self.clVars.Write("sr_ldap_set","on",force=True)
|
|
|
|
|
self.printOK(_("LDAP service configured") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
REGISTERED_METHODS = ['add_runlevel', 'apply_templates',
|
|
|
|
|
'get_pkg_name', 'get_prioritet', 'get_service_info', 'get_service_name',
|
|
|
|
|
'get_vars','is_runlevel', 'is_setup', 'is_start', 'restart', 'scheme', 'setup',
|
|
|
|
|
'start', 'stop']
|
|
|
|
|
|
|
|
|
|
class serviceAPI(object):
|
|
|
|
|
"""Proxy object"""
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.__subject = allMethods()
|
|
|
|
|
for attr in dir(self.__subject):
|
|
|
|
|
if attr in REGISTERED_METHODS:
|
|
|
|
|
object.__setattr__(self, attr, getattr(self.__subject, attr))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|