|
|
|
@ -37,7 +37,8 @@ import tty
|
|
|
|
|
# Работа со временем
|
|
|
|
|
import time
|
|
|
|
|
import datetime
|
|
|
|
|
|
|
|
|
|
# Создание временных файлов
|
|
|
|
|
import tempfile
|
|
|
|
|
|
|
|
|
|
Version = "calculate-server 2.0.7"
|
|
|
|
|
|
|
|
|
@ -759,7 +760,7 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
|
|
|
|
|
modAttrs = []
|
|
|
|
|
if not self.stringIsJpeg(photoData):
|
|
|
|
|
flagError = False
|
|
|
|
|
fOut, fIn, fErr = popen2.popen3("convert %s jpg:-" %photoPath)
|
|
|
|
|
fOut, fIn, fErr = popen2.popen3("convert '%s' jpg:-" %photoPath)
|
|
|
|
|
fIn.close()
|
|
|
|
|
if fErr.read():
|
|
|
|
|
self.printERROR(_("Can not convert file '%s' in jpeg format")\
|
|
|
|
@ -5086,7 +5087,6 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
self.printOK(_("Rebuilding all services") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def rebuildLdapServer(self, options):
|
|
|
|
|
"""Перегенерирует конфигурационные файлы, и базу данных LDAP"""
|
|
|
|
|
return self.rebuildServer(options)
|
|
|
|
@ -5101,6 +5101,18 @@ outdated. If the backup is obsolete, use cl-backup."))
|
|
|
|
|
self.clVars = clVars
|
|
|
|
|
else:
|
|
|
|
|
self.createClVars()
|
|
|
|
|
if serviceUpdate in ["all","unix","samba"]:
|
|
|
|
|
# создаем объект репликации
|
|
|
|
|
objRepl = servRepl()
|
|
|
|
|
if self.clVars.Get("ld_repl_id") and\
|
|
|
|
|
self.clVars.Get("ld_repl_set") == "on":
|
|
|
|
|
# Добавляем в крон скрипт для чистки директорий
|
|
|
|
|
if not objRepl.cronReplicationON():
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# Удаляем из крона скрипт для чистки директорий
|
|
|
|
|
if not objRepl.cronReplicationOFF():
|
|
|
|
|
return False
|
|
|
|
|
# Настройка почты
|
|
|
|
|
if serviceUpdate in ["all","mail"]:
|
|
|
|
|
if options.has_key("t"):
|
|
|
|
@ -5926,6 +5938,7 @@ class cl_ldap(shareLdap):
|
|
|
|
|
'cl-rebuild':10,
|
|
|
|
|
'repldap':11,
|
|
|
|
|
'cl-replication':12,
|
|
|
|
|
'replcron':13,
|
|
|
|
|
}
|
|
|
|
|
# Cвязь сервисов и действующих опций
|
|
|
|
|
self.relServices = {"samba":[_("Common options"),
|
|
|
|
@ -6768,6 +6781,11 @@ the password will be changed only for Samba account")
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("servers replication (comma delimited)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(12,),
|
|
|
|
|
'longOption':"off",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("replication off")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(0,1,2,4,5,6),
|
|
|
|
|
#'shortOption':"s",
|
|
|
|
|
#'longOption':"set",
|
|
|
|
@ -6887,7 +6905,7 @@ the password will be changed only for Samba account")
|
|
|
|
|
'help': cmdName + " " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(10,),
|
|
|
|
|
'progAccess':(10,13),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName
|
|
|
|
|
},
|
|
|
|
@ -6952,7 +6970,18 @@ services")
|
|
|
|
|
'progAccess':(11,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Writes information about the user in the LDAP branch \
|
|
|
|
|
'Replication'.")
|
|
|
|
|
'Replication'")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(12,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Setup and configure replication between LDAP servers")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(13,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Deletes the users directories, which had been previously \
|
|
|
|
|
removed from the LDAP using replication")
|
|
|
|
|
},
|
|
|
|
|
# Примеры
|
|
|
|
|
{
|
|
|
|
@ -7585,6 +7614,8 @@ class servRepl(shareLdap):
|
|
|
|
|
"ld_services_dn","ld_bind_dn",
|
|
|
|
|
"ld_bind_pw","ld_base_dn",
|
|
|
|
|
"ur_organization","ur_signature"]
|
|
|
|
|
# файл для удаления данных несуществущих пользователей по cron
|
|
|
|
|
self.replCronFile = "replcron"
|
|
|
|
|
|
|
|
|
|
def prepAndSaveEnv(self):
|
|
|
|
|
"""Подготовка переменных и их запись в файлы в случае rebuild"""
|
|
|
|
@ -7948,6 +7979,145 @@ class servRepl(shareLdap):
|
|
|
|
|
i+=1
|
|
|
|
|
return replServersList
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def deleteNotFoundUserData(self, options, logObj=False):
|
|
|
|
|
"""Удаляет пользовательские данные если пользователь не найден"""
|
|
|
|
|
if logObj:
|
|
|
|
|
logObj.writeSuccess(_("start script"))
|
|
|
|
|
# Cоздаем объект переменные
|
|
|
|
|
self.createClVars()
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix", False):
|
|
|
|
|
errMessage = _("Service %s is not installed")%"unix" + " ..."
|
|
|
|
|
if logObj:
|
|
|
|
|
logObj.writeError(errMessage)
|
|
|
|
|
self.printERROR(errMessage)
|
|
|
|
|
return False
|
|
|
|
|
# Проверяем соединение с LDAP
|
|
|
|
|
if not self.servUnixObj.getLdapObjInFile():
|
|
|
|
|
errMessage = _("Can not connect Unix service to LDAP server")
|
|
|
|
|
if logObj:
|
|
|
|
|
logObj.writeError(errMessage)
|
|
|
|
|
self.printERROR(errMessage)
|
|
|
|
|
return False
|
|
|
|
|
#logObj.writeSuccess(messages)
|
|
|
|
|
#logObj.writeError(errMessage)
|
|
|
|
|
# Пути в которых есть данные пользователей
|
|
|
|
|
foundPaths = [self.clVars.Get("sr_samba_winprof_path"),
|
|
|
|
|
self.clVars.Get("sr_samba_linprof_path"),
|
|
|
|
|
self.clVars.Get("sr_samba_home_path"),
|
|
|
|
|
self.clVars.Get("sr_samba_winlogon_path"),
|
|
|
|
|
self.clVars.Get("sr_mail_path"),
|
|
|
|
|
os.path.join(self.clVars.Get("sr_ftp_path"), "pub/users")]
|
|
|
|
|
pathProg = os.getcwd()
|
|
|
|
|
for path in foundPaths:
|
|
|
|
|
if os.path.isdir(path):
|
|
|
|
|
os.chdir(path)
|
|
|
|
|
users = os.listdir(".")
|
|
|
|
|
users = filter(lambda x: os.path.isdir(x), users)
|
|
|
|
|
for userName in users:
|
|
|
|
|
if not self.servUnixObj.searchUnixUser(userName) and\
|
|
|
|
|
not self.servUnixObj.searchPasswdUser(userName):
|
|
|
|
|
self.removeDir(userName)
|
|
|
|
|
message = _("deleted %s")\
|
|
|
|
|
%os.path.join(path,userName)
|
|
|
|
|
if logObj:
|
|
|
|
|
logObj.writeSuccess(message)
|
|
|
|
|
self.printWARNING(message)
|
|
|
|
|
if os.path.exists(pathProg):
|
|
|
|
|
os.chdir(pathProg)
|
|
|
|
|
if logObj:
|
|
|
|
|
logObj.writeSuccess(_("end script ... [ok]"))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def cronReplicationON(self):
|
|
|
|
|
"""Включает в cron обработку файла replcron"""
|
|
|
|
|
replCronFile = os.path.join("/usr/bin",self.replCronFile)
|
|
|
|
|
fileNameCron = tempfile.mktemp(".cron")
|
|
|
|
|
warning = _("Please do not remove the line, it was added to the \
|
|
|
|
|
calculate-server")
|
|
|
|
|
textCronInsert = "30 3 * * 1 %s"%replCronFile
|
|
|
|
|
listCronLines = self.execProg("crontab -l",False,False)
|
|
|
|
|
# Удаляем из элементов переводы строк
|
|
|
|
|
listCronLinesSrc = map(lambda x: x.split('\n')[0],listCronLines)
|
|
|
|
|
# Удаляем из элементов все начиная с #
|
|
|
|
|
listCronLines = map(lambda x: x.split("#")[0].strip(),listCronLinesSrc)
|
|
|
|
|
foundCronLine = False
|
|
|
|
|
listCronLinesOut = []
|
|
|
|
|
i = 0
|
|
|
|
|
for textCron in listCronLines:
|
|
|
|
|
if not textCron.strip():
|
|
|
|
|
i += 1
|
|
|
|
|
continue
|
|
|
|
|
elemLine=re.split(\
|
|
|
|
|
"[^\t ]+\s+[^\t ]+\s+[^\t ]+\s+[^\t ]+\s+[^\t ]+\s+" ,textCron)
|
|
|
|
|
if len(elemLine) == 2 and elemLine[1] == replCronFile:
|
|
|
|
|
foundCronLine = True
|
|
|
|
|
break
|
|
|
|
|
listCronLinesOut.append(listCronLinesSrc[i])
|
|
|
|
|
i +=1
|
|
|
|
|
if foundCronLine:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
if listCronLinesOut:
|
|
|
|
|
self.createUserFile(fileNameCron,
|
|
|
|
|
"\n".join(listCronLinesOut) + "\n"+\
|
|
|
|
|
"%s # %s\n"%(textCronInsert,warning),
|
|
|
|
|
0,0)
|
|
|
|
|
else:
|
|
|
|
|
self.createUserFile(fileNameCron,
|
|
|
|
|
"%s # %s\n"%(textCronInsert,warning),
|
|
|
|
|
0,0)
|
|
|
|
|
textLine = self.execProg("crontab %s"%fileNameCron)
|
|
|
|
|
if not (textLine == None):
|
|
|
|
|
self.printERROR(_("Can not added crontab file"))
|
|
|
|
|
if os.path.exists(fileNameCron):
|
|
|
|
|
os.remove(fileNameCron)
|
|
|
|
|
return False
|
|
|
|
|
if os.path.exists(fileNameCron):
|
|
|
|
|
os.remove(fileNameCron)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def cronReplicationOFF(self):
|
|
|
|
|
"""Отключает в crontab обработку файла replcron"""
|
|
|
|
|
replCronFile = os.path.join("/usr/bin",self.replCronFile)
|
|
|
|
|
fileNameCron = tempfile.mktemp(".cron")
|
|
|
|
|
listCronLines = self.execProg("crontab -l",False,False)
|
|
|
|
|
# Удаляем из элементов переводы строк
|
|
|
|
|
listCronLinesSrc = map(lambda x: x.split('\n')[0],listCronLines)
|
|
|
|
|
# Удаляем из элементов все начиная с #
|
|
|
|
|
listCronLines = map(lambda x: x.split("#")[0].strip(), listCronLinesSrc)
|
|
|
|
|
listCronLinesOut = []
|
|
|
|
|
i = 0
|
|
|
|
|
for textCron in listCronLines:
|
|
|
|
|
if not textCron.strip():
|
|
|
|
|
i +=1
|
|
|
|
|
continue
|
|
|
|
|
elemLine=re.split(\
|
|
|
|
|
"[^\t ]+\s+[^\t ]+\s+[^\t ]+\s+[^\t ]+\s+[^\t ]+\s+" ,textCron)
|
|
|
|
|
if len(elemLine) == 2 and elemLine[1] == replCronFile:
|
|
|
|
|
i +=1
|
|
|
|
|
continue
|
|
|
|
|
listCronLinesOut.append(listCronLinesSrc[i])
|
|
|
|
|
i += 1
|
|
|
|
|
if listCronLinesOut:
|
|
|
|
|
self.createUserFile(fileNameCron,
|
|
|
|
|
"\n".join(listCronLinesOut)+"\n",
|
|
|
|
|
0,0)
|
|
|
|
|
else:
|
|
|
|
|
self.createUserFile(fileNameCron,
|
|
|
|
|
"\n",
|
|
|
|
|
0,0)
|
|
|
|
|
textLine = self.execProg("crontab %s"%fileNameCron)
|
|
|
|
|
if not (textLine == None):
|
|
|
|
|
self.printERROR(_("Can not added crontab file"))
|
|
|
|
|
if os.path.exists(fileNameCron):
|
|
|
|
|
os.remove(fileNameCron)
|
|
|
|
|
return False
|
|
|
|
|
if os.path.exists(fileNameCron):
|
|
|
|
|
os.remove(fileNameCron)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def setupReplServer(self, options, service):
|
|
|
|
|
"""Начальная настройка репликации"""
|
|
|
|
|
# Cоздаем объект переменные
|
|
|
|
@ -7960,26 +8130,35 @@ class servRepl(shareLdap):
|
|
|
|
|
self.clVars.Write("ld_repl_set", "off")
|
|
|
|
|
# Включаем репликацию
|
|
|
|
|
self.clVars.Set("ld_repl_set", "on")
|
|
|
|
|
if not options.has_key('r') or not options['r']:
|
|
|
|
|
if not options.has_key('off') and\
|
|
|
|
|
(not options.has_key('r') or not options['r']):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Not specified replication servers\
|
|
|
|
|
(command line option '-r')") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
replServers = options['r'].split(',')
|
|
|
|
|
# Преобразуем короткие имена в длинные
|
|
|
|
|
hostName = self.clVars.Get('os_net_hostname')
|
|
|
|
|
domain = self.clVars.Get('os_net_domain')
|
|
|
|
|
replServers = self.chortToFullName(replServers, domain)
|
|
|
|
|
fullHostName = "%s.%s"%(hostName,domain)
|
|
|
|
|
# Удаляем похожие сервера и текущий сервер из списка
|
|
|
|
|
replServers = self.genReplServers(replServers, hostName, fullHostName)
|
|
|
|
|
# Если серверы отсуствуют - ошибка
|
|
|
|
|
if not replServers:
|
|
|
|
|
if options.has_key('off') and options.has_key('r'):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Not a valid list of servers replication") + " ...")
|
|
|
|
|
_("You can not use the option to '--off',\
|
|
|
|
|
together with option '-r'") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем текущий сервер в серверы репликации
|
|
|
|
|
replServers.insert(0,fullHostName)
|
|
|
|
|
replServers = []
|
|
|
|
|
if options.has_key('r'):
|
|
|
|
|
replServers = options['r'].split(',')
|
|
|
|
|
# Преобразуем короткие имена в длинные
|
|
|
|
|
hostName = self.clVars.Get('os_net_hostname')
|
|
|
|
|
domain = self.clVars.Get('os_net_domain')
|
|
|
|
|
replServers = self.chortToFullName(replServers, domain)
|
|
|
|
|
fullHostName = "%s.%s"%(hostName,domain)
|
|
|
|
|
# Удаляем похожие сервера и текущий сервер из списка
|
|
|
|
|
replServers = self.genReplServers(replServers, hostName,
|
|
|
|
|
fullHostName)
|
|
|
|
|
# Если серверы отсуствуют - ошибка
|
|
|
|
|
if not replServers:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Not a valid list of servers replication") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем текущий сервер в серверы репликации
|
|
|
|
|
replServers.insert(0,fullHostName)
|
|
|
|
|
# В случае если сервер установлен
|
|
|
|
|
if self.clVars.Get("sr_ldap_set") != "on":
|
|
|
|
|
self.printERROR(\
|
|
|
|
@ -7990,23 +8169,28 @@ class servRepl(shareLdap):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Set Replication error, Unix service not setuped") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
replSambaServers = self.clVars.Get("ld_repl_samba_servers")
|
|
|
|
|
if replSambaServers:
|
|
|
|
|
replSambaServers = replSambaServers.split(",")
|
|
|
|
|
replUnixServers = list(set(replSambaServers)|set(replServers))
|
|
|
|
|
else:
|
|
|
|
|
replUnixServers = replServers
|
|
|
|
|
# Устанавливаем переменную серверы репл. для Unix сервиса
|
|
|
|
|
self.clVars.Set("ld_repl_unix_servers",
|
|
|
|
|
",".join(replUnixServers),True)
|
|
|
|
|
if replSambaServers:
|
|
|
|
|
replAllServers = list(\
|
|
|
|
|
if options.has_key('r'):
|
|
|
|
|
replSambaServers = self.clVars.Get("ld_repl_samba_servers")
|
|
|
|
|
if replSambaServers:
|
|
|
|
|
replSambaServers = replSambaServers.split(",")
|
|
|
|
|
replUnixServers =list(\
|
|
|
|
|
set(replSambaServers)|set(replServers))
|
|
|
|
|
else:
|
|
|
|
|
replUnixServers = replServers
|
|
|
|
|
# Устанавливаем переменную серверы репл. для Unix сервиса
|
|
|
|
|
self.clVars.Set("ld_repl_unix_servers",
|
|
|
|
|
",".join(replUnixServers),True)
|
|
|
|
|
if replSambaServers:
|
|
|
|
|
replAllServers = list(\
|
|
|
|
|
set(replUnixServers)|set(replSambaServers))
|
|
|
|
|
else:
|
|
|
|
|
replAllServers = replUnixServers
|
|
|
|
|
# Устанавливаем переменную серверы репл. для всех сервисов
|
|
|
|
|
self.clVars.Set("ld_repl_servers",
|
|
|
|
|
",".join(replAllServers),True)
|
|
|
|
|
else:
|
|
|
|
|
replAllServers = replUnixServers
|
|
|
|
|
# Устанавливаем переменную серверы репл. для всех сервисов
|
|
|
|
|
self.clVars.Set("ld_repl_servers",
|
|
|
|
|
",".join(replAllServers),True)
|
|
|
|
|
elif options.has_key('off'):
|
|
|
|
|
# Вылючаем репликацию
|
|
|
|
|
self.clVars.Set("ld_repl_set", "off")
|
|
|
|
|
elif service == "samba":
|
|
|
|
|
if self.clVars.Get("sr_samba_set") != "on":
|
|
|
|
|
self.printERROR(\
|
|
|
|
@ -8015,6 +8199,9 @@ class servRepl(shareLdap):
|
|
|
|
|
replUnixServers = self.clVars.Get("ld_repl_unix_servers")
|
|
|
|
|
if replUnixServers:
|
|
|
|
|
replUnixServers = replUnixServers.split(",")
|
|
|
|
|
if options.has_key('off'):
|
|
|
|
|
# Очищаем cерверы репликации Samba
|
|
|
|
|
self.clVars.Set("ld_repl_samba_servers", "", True)
|
|
|
|
|
replSambaServers = self.clVars.Get("ld_repl_samba_servers")
|
|
|
|
|
if replSambaServers:
|
|
|
|
|
replSambaServers = replSambaServers.split(",")
|
|
|
|
@ -8031,6 +8218,9 @@ class servRepl(shareLdap):
|
|
|
|
|
# Устанавливаем переменную серверы репл. для всех сервисов
|
|
|
|
|
self.clVars.Set("ld_repl_servers",
|
|
|
|
|
",".join(replAllServers),True)
|
|
|
|
|
if not self.clVars.Get("ld_repl_id"):
|
|
|
|
|
# Вылючаем репликацию
|
|
|
|
|
self.clVars.Set("ld_repl_set", "off")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("incorrect service '%s' in method setupReplServer")%service+" ...")
|
|
|
|
@ -8043,17 +8233,34 @@ class servRepl(shareLdap):
|
|
|
|
|
#Cоединение с Ldap (администратор)
|
|
|
|
|
if not shareLdap.getLdapObjInFile(self):
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем ветку репликации
|
|
|
|
|
if not self.addReplDN():
|
|
|
|
|
return False
|
|
|
|
|
# Проверяем существует ли id текущего сервера
|
|
|
|
|
if not self.clVars.Get("ld_repl_id"):
|
|
|
|
|
self.printERROR(_("Not found 'serverID' this server") + " ...")
|
|
|
|
|
self.printERROR(_("variable 'ld_repl_id' empty") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('r'):
|
|
|
|
|
# Добавляем ветку репликации
|
|
|
|
|
if not self.addReplDN():
|
|
|
|
|
return False
|
|
|
|
|
# Проверяем существует ли id текущего сервера
|
|
|
|
|
if not self.clVars.Get("ld_repl_id"):
|
|
|
|
|
self.printERROR(_("Not found 'serverID' this server") + " ...")
|
|
|
|
|
self.printERROR(_("variable 'ld_repl_id' empty") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Делаем update сервиса
|
|
|
|
|
if not self.servLdapObj.updateServer({},service,self.clVars):
|
|
|
|
|
return False
|
|
|
|
|
if self.clVars.Get("ld_repl_set") == "on":
|
|
|
|
|
# Добавляем в крон скрипт для чистки директорий
|
|
|
|
|
if not self.cronReplicationON():
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# Удаляем из крона скрипт для чистки директорий
|
|
|
|
|
if not self.cronReplicationOFF():
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем переменные
|
|
|
|
|
self.clVars.Delete("ld_repl_servers","local","server")
|
|
|
|
|
self.clVars.Delete("ld_repl_samba_servers","local","server")
|
|
|
|
|
self.clVars.Delete("ld_repl_unix_servers","local","server")
|
|
|
|
|
self.clVars.Delete("ld_repl_pw")
|
|
|
|
|
self.clVars.Delete("ld_repl_set")
|
|
|
|
|
self.printOK(_("Replication off for all services") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
#запишем переменные для сервера
|
|
|
|
|
# в /etc/calculate.env
|
|
|
|
|
self.clVars.Write("ld_repl_pw",
|
|
|
|
|