|
|
|
|
#-*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
|
|
|
|
|
#
|
|
|
|
|
# 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
|
|
|
|
|
import sys
|
|
|
|
|
import re
|
|
|
|
|
#import popen2
|
|
|
|
|
import ldap
|
|
|
|
|
import cStringIO, StringIO
|
|
|
|
|
from ldif import LDIFParser, LDIFWriter
|
|
|
|
|
import cl_base
|
|
|
|
|
import cl_profile
|
|
|
|
|
import cl_utils2
|
|
|
|
|
import cl_utils
|
|
|
|
|
# Для подсчета символов
|
|
|
|
|
import termios, fcntl, struct
|
|
|
|
|
# Ввод pwd
|
|
|
|
|
import getpass
|
|
|
|
|
# Статистика файла
|
|
|
|
|
import stat
|
|
|
|
|
import types
|
|
|
|
|
import time
|
|
|
|
|
# Для ввода символа
|
|
|
|
|
import tty
|
|
|
|
|
import termios
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Version = "calculate-server 0.0.3"
|
|
|
|
|
|
|
|
|
|
tr = cl_base.lang()
|
|
|
|
|
tr.setLanguage(sys.modules[__name__])
|
|
|
|
|
|
|
|
|
|
pcs = cl_utils.prettyColumnStr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def adminConnectLdap(fun):
|
|
|
|
|
"""Cоединение с LDAP администратором сервиса (декоратор)
|
|
|
|
|
|
|
|
|
|
соединение с LDAP и проверка установки необходимых переменных
|
|
|
|
|
"""
|
|
|
|
|
def ret (self, *arg, **argv):
|
|
|
|
|
flagError = False
|
|
|
|
|
if not self.clVars:
|
|
|
|
|
self.createClVars()
|
|
|
|
|
if not self.ldapObj:
|
|
|
|
|
if not self.getLdapObjInFile():
|
|
|
|
|
flagError = True
|
|
|
|
|
if not self.baseDN:
|
|
|
|
|
if self.clVars.defined("ld_base_dn"):
|
|
|
|
|
self.baseDN = self.clVars.Get("ld_base_dn")
|
|
|
|
|
if not self.baseDN:
|
|
|
|
|
self.printERROR (_('Not found LDAP base DN'))
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return fun(self, *arg , **argv)
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
class iniLdapParser(cl_base.iniParser):
|
|
|
|
|
"""Класс для работы c ini-файлом ldap"""
|
|
|
|
|
def __init__(self):
|
|
|
|
|
# название ini файла
|
|
|
|
|
self.nameIniFile = "/etc/calculate/calculate.ldap"
|
|
|
|
|
cl_base.iniParser.__init__(self, self.nameIniFile)
|
|
|
|
|
# права создаваемого ini-файла
|
|
|
|
|
self.setMode(0600)
|
|
|
|
|
pathIniFile = os.path.split(self.nameIniFile)[0]
|
|
|
|
|
if not os.path.exists(pathIniFile):
|
|
|
|
|
os.makedirs(pathIniFile)
|
|
|
|
|
|
|
|
|
|
class addLdif(LDIFParser):
|
|
|
|
|
"""Класс необходимый для добавления записей в LDAP"""
|
|
|
|
|
def __init__(self, strInput,ldapCon):
|
|
|
|
|
FD = cStringIO.StringIO(strInput)
|
|
|
|
|
LDIFParser.__init__(self, FD)
|
|
|
|
|
self.ldapCon = ldapCon
|
|
|
|
|
|
|
|
|
|
def handle(self, dn, entry):
|
|
|
|
|
self.ldapCon.add_s(dn, entry.items())
|
|
|
|
|
|
|
|
|
|
class ldapFunction(cl_utils2.ldapFun):
|
|
|
|
|
'''Объект для работы с LDAP сервером'''
|
|
|
|
|
def __init__(self, dnUser, password):
|
|
|
|
|
cl_utils2.ldapFun.__init__(self, dnUser, password)
|
|
|
|
|
|
|
|
|
|
def ldapAdd(self, strLdif):
|
|
|
|
|
"""Добавляем строку содержащую ldif в LDAP
|
|
|
|
|
|
|
|
|
|
Если данные существуют - ошибка
|
|
|
|
|
"""
|
|
|
|
|
if self.conLdap:
|
|
|
|
|
try:
|
|
|
|
|
# Записываем параметры из ldif файла в LDAP сервер
|
|
|
|
|
parser = addLdif(strLdif,self.conLdap)
|
|
|
|
|
parser.parse()
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.setError(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
except:
|
|
|
|
|
self.setError("Error in ldif file")
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.setError(_("No connect to LDAP server"))
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# Импортированные классы в cl_ldap
|
|
|
|
|
# Запись ошибок
|
|
|
|
|
imp_cl_err = cl_profile._error
|
|
|
|
|
# Работа с XML
|
|
|
|
|
imp_cl_xml = cl_profile.xmlShare
|
|
|
|
|
# Обработка параметров командной строки
|
|
|
|
|
imp_cl_help = cl_utils2.cl_help
|
|
|
|
|
# Форматированный вывод
|
|
|
|
|
imp_cl_smcon = cl_utils2.cl_smartcon
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
|
|
|
|
|
"""Класс где храняться общие методы для всех сервисов"""
|
|
|
|
|
|
|
|
|
|
def addInfoGroup(self, name, gid, comment):
|
|
|
|
|
"""Добавляем информацию о группе"""
|
|
|
|
|
class group():
|
|
|
|
|
"""Информация о группе"""
|
|
|
|
|
name = ""
|
|
|
|
|
gid = ""
|
|
|
|
|
comment = ""
|
|
|
|
|
gr = group()
|
|
|
|
|
gr.name = name
|
|
|
|
|
gr.gid = gid
|
|
|
|
|
gr.comment = comment
|
|
|
|
|
return gr
|
|
|
|
|
|
|
|
|
|
def addInfoUser(self, name, uid, gid, comment):
|
|
|
|
|
"""Добавляем информацию о пользователе"""
|
|
|
|
|
class user():
|
|
|
|
|
"""Информация о пользователе"""
|
|
|
|
|
name = ""
|
|
|
|
|
uid = ""
|
|
|
|
|
gid = ""
|
|
|
|
|
comment = ""
|
|
|
|
|
us = user()
|
|
|
|
|
us.name = name
|
|
|
|
|
us.uid = uid
|
|
|
|
|
us.gid = gid
|
|
|
|
|
us.comment = comment
|
|
|
|
|
return us
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
# Переменная объект Vars
|
|
|
|
|
self.clVars = False
|
|
|
|
|
# Переменная объект ldapFunction
|
|
|
|
|
self.ldapObj = False
|
|
|
|
|
# Переменная соединение с LDAP сервером
|
|
|
|
|
self.conLdap = False
|
|
|
|
|
# Базовый DN LDAP сервера
|
|
|
|
|
self.baseDN = False
|
|
|
|
|
# DN сервисов относительно базового
|
|
|
|
|
self.ServicesDN = "ou=Services"
|
|
|
|
|
# Статические группы
|
|
|
|
|
self.staticGroups = {\
|
|
|
|
|
'client':self.addInfoGroup('client',
|
|
|
|
|
'900',
|
|
|
|
|
'Client samba group'),
|
|
|
|
|
'admin':self.addInfoGroup('admin',
|
|
|
|
|
'901',
|
|
|
|
|
'Admin samba group'),
|
|
|
|
|
'Computers':self.addInfoGroup('Computers',
|
|
|
|
|
'902',
|
|
|
|
|
'Computer group')}
|
|
|
|
|
# Статические пользователи
|
|
|
|
|
self.staticUsers = {\
|
|
|
|
|
'client':self.addInfoUser('client',
|
|
|
|
|
'900',
|
|
|
|
|
'900',
|
|
|
|
|
'Client samba user'),
|
|
|
|
|
'admin':self.addInfoUser('admin',
|
|
|
|
|
'901',
|
|
|
|
|
'901',
|
|
|
|
|
'Admin samba user')}
|
|
|
|
|
|
|
|
|
|
def restorePathDelUser(self,userName,destDir,relDir,message,unixObj=False):
|
|
|
|
|
"""Восстанавливает директорию удаленного пользователя"""
|
|
|
|
|
removeDir = False
|
|
|
|
|
flagError = False
|
|
|
|
|
resRestore = self.restoreDelUser(userName, relDir,
|
|
|
|
|
destDir, message,unixObj)
|
|
|
|
|
# Если ошибка то выходим
|
|
|
|
|
if not resRestore:
|
|
|
|
|
flagError = True
|
|
|
|
|
# Флаг создания директории профиля пользователя
|
|
|
|
|
createDir = destDir
|
|
|
|
|
term = ""
|
|
|
|
|
if resRestore == True:
|
|
|
|
|
term = message
|
|
|
|
|
if not flagError and type(resRestore) == types.TupleType:
|
|
|
|
|
# Если cansel
|
|
|
|
|
if resRestore[0] == "Cancel":
|
|
|
|
|
# Удаляем пользователя
|
|
|
|
|
flagError = True
|
|
|
|
|
term = None
|
|
|
|
|
# Если No
|
|
|
|
|
elif resRestore[0] == "No":
|
|
|
|
|
if not self.removeDir(resRestore[1]):
|
|
|
|
|
flagError = True
|
|
|
|
|
if not flagError:
|
|
|
|
|
removeDir = resRestore[1]
|
|
|
|
|
term = False
|
|
|
|
|
elif resRestore[0] == "Yes":
|
|
|
|
|
createDir = False
|
|
|
|
|
removeDir = resRestore[1]
|
|
|
|
|
term = True
|
|
|
|
|
if flagError or term == "":
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return (term, createDir, removeDir)
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def restoreDelUser(self,userName,service,srcDir,message,unixObj=False):
|
|
|
|
|
"""Возвращаем данные удаленного пользователя"""
|
|
|
|
|
# Ищем Unix пользователя
|
|
|
|
|
if unixObj:
|
|
|
|
|
servUnixObj = unixObj
|
|
|
|
|
else:
|
|
|
|
|
servUnixObj = self.servUnixObj
|
|
|
|
|
searchUnixUser = servUnixObj.searchUnixUser(userName)
|
|
|
|
|
# id пользователя
|
|
|
|
|
strUid = ""
|
|
|
|
|
if searchUnixUser:
|
|
|
|
|
strUid = searchUnixUser[0][0][1]['uidNumber'][0]
|
|
|
|
|
else:
|
|
|
|
|
resPasswd = servUnixObj.searchPasswdUser(userName)
|
|
|
|
|
if resPasswd:
|
|
|
|
|
strUid = resPasswd.split(":")[2]
|
|
|
|
|
if strUid:
|
|
|
|
|
delBackDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_deleted_path"),
|
|
|
|
|
"%s-%s"%(userName,strUid),
|
|
|
|
|
service)
|
|
|
|
|
if strUid and os.path.exists(delBackDir) and os.listdir(delBackDir):
|
|
|
|
|
if message == None or type(message) == types.BooleanType:
|
|
|
|
|
dialogRes = message
|
|
|
|
|
else:
|
|
|
|
|
dialogRes = self.dialogYesNo(message)
|
|
|
|
|
if dialogRes and dialogRes == True:
|
|
|
|
|
try:
|
|
|
|
|
self.copyDir(srcDir, delBackDir)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("Not restore user data in dir %s")\
|
|
|
|
|
%srcDir)
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Restore user data in dir %s")\
|
|
|
|
|
%srcDir)
|
|
|
|
|
return "Yes", delBackDir
|
|
|
|
|
elif dialogRes == False:
|
|
|
|
|
return "No", delBackDir
|
|
|
|
|
elif dialogRes == None:
|
|
|
|
|
return "Cancel", delBackDir
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def backupDelUser(self, userName, service, srcDir, unixObj=False):
|
|
|
|
|
"""Сохраняем данные удаляемого пользователя"""
|
|
|
|
|
# Ищем Unix пользователя
|
|
|
|
|
if unixObj:
|
|
|
|
|
servUnixObj = unixObj
|
|
|
|
|
else:
|
|
|
|
|
servUnixObj = self.servUnixObj
|
|
|
|
|
searchUnixUser = servUnixObj.searchUnixUser(userName)
|
|
|
|
|
# id пользователя
|
|
|
|
|
strUid = ""
|
|
|
|
|
if searchUnixUser:
|
|
|
|
|
strUid = searchUnixUser[0][0][1]['uidNumber'][0]
|
|
|
|
|
if strUid:
|
|
|
|
|
delBackDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_deleted_path"),
|
|
|
|
|
"%s-%s"%(userName,strUid),
|
|
|
|
|
service)
|
|
|
|
|
if os.path.exists(delBackDir) and os.listdir(delBackDir):
|
|
|
|
|
self.printERROR(_("Found deleted user data dir %s")\
|
|
|
|
|
%delBackDir)
|
|
|
|
|
self.printERROR(_("Not created deleted user data dir %s")\
|
|
|
|
|
%delBackDir)
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
delBackDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_deleted_path"),
|
|
|
|
|
"%s"%(userName),
|
|
|
|
|
service)
|
|
|
|
|
i = 0
|
|
|
|
|
while os.path.exists(delBackDir):
|
|
|
|
|
i += 1
|
|
|
|
|
delBackDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_deleted_path"),
|
|
|
|
|
"%s_%s"%(userName,i),
|
|
|
|
|
service)
|
|
|
|
|
# Cоздаем директорию хранения удаленных пользователей
|
|
|
|
|
if not os.path.exists(self.clVars.Get("sr_deleted_path")):
|
|
|
|
|
os.makedirs(self.clVars.Get("sr_deleted_path"))
|
|
|
|
|
#Делаем сохранение директории
|
|
|
|
|
try:
|
|
|
|
|
self.copyDir(delBackDir,srcDir)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("Not created deleted user data dir %s")\
|
|
|
|
|
%delBackDir)
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Created deleted user data dir %s")\
|
|
|
|
|
%delBackDir)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def stringIsJpeg(self, string):
|
|
|
|
|
"""Определяет является ли строка jpeg изображением"""
|
|
|
|
|
if len(string)<8:
|
|
|
|
|
return False
|
|
|
|
|
FD = cStringIO.StringIO(string)
|
|
|
|
|
isJpeg = False
|
|
|
|
|
FD.seek(0, 0)
|
|
|
|
|
(firstByte, secondByte) = FD.read(2)
|
|
|
|
|
if (ord(firstByte) == 0xff and ord(secondByte) == 0xd8):
|
|
|
|
|
(firstByte, secondByte) = FD.read(2)
|
|
|
|
|
if (ord(firstByte) == 0xff and ord(secondByte) == 0xe0):
|
|
|
|
|
isJpeg = True
|
|
|
|
|
return isJpeg
|
|
|
|
|
|
|
|
|
|
def setDaemonAutostart(self, daemon):
|
|
|
|
|
"""Прописывает демона в автозагрузку"""
|
|
|
|
|
execStr = "rc-update add %s default" %daemon
|
|
|
|
|
textLine = self.execProg(execStr)
|
|
|
|
|
if "added to runlevel" in textLine or\
|
|
|
|
|
"already installed in runlevel" in textLine:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printError(_("ERROR") + ": " + execStr)
|
|
|
|
|
self.printError(_("Not added at default runlevel")+ " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def delDaemonAutostart(self, daemon):
|
|
|
|
|
"""Удаляет демона из автозагрузки"""
|
|
|
|
|
execStr = "rc-update del %s default" %daemon
|
|
|
|
|
textLine = self.execProg(execStr)
|
|
|
|
|
if "removed from the following runlevels" in textLine or\
|
|
|
|
|
"not found in any of the specified runlevels" in textLine:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printError(_("ERROR") + ": " + execStr)
|
|
|
|
|
self.printError(_("Not deleted from default runlevel")+ " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def runLdapServer(self):
|
|
|
|
|
"""Запускает LDAP сервер"""
|
|
|
|
|
textLine = self.execProg("/etc/init.d/slapd start")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("Starting LDAP")+ " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def restartLdapServer(self):
|
|
|
|
|
"""Запускает LDAP сервер"""
|
|
|
|
|
textLine = self.execProg("/etc/init.d/slapd restart")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("Restarting LDAP")+ " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def stopLdapServer(self):
|
|
|
|
|
"""Останавливает LDAP сервер"""
|
|
|
|
|
textLine = self.execProg("/etc/init.d/slapd stop")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
#self.printOK(_("LDAP stop")+ " ...")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("Stopping LDAP")+ " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getALLServices(self):
|
|
|
|
|
"""Получаем все сервисы которые описаны в профилях"""
|
|
|
|
|
# путь к директории профилей
|
|
|
|
|
profilePath = self.clVars.Get("cl_profile_path")[0]
|
|
|
|
|
data = os.listdir(profilePath)
|
|
|
|
|
service = []
|
|
|
|
|
for fileData in data:
|
|
|
|
|
if os.path.isdir(os.path.join(profilePath, fileData)):
|
|
|
|
|
service.append(fileData)
|
|
|
|
|
if service:
|
|
|
|
|
# После добавления сервисов в класс необходимо удалить
|
|
|
|
|
# apache и jabber
|
|
|
|
|
service.remove('backup')
|
|
|
|
|
service.remove('apache')
|
|
|
|
|
return service
|
|
|
|
|
|
|
|
|
|
def applyProfilesFromService(self, service):
|
|
|
|
|
"""Применяем профили для данного сервиса"""
|
|
|
|
|
# Cоздаем объект профиль устанавливая директорию
|
|
|
|
|
# service для файлов профилей
|
|
|
|
|
clProf = cl_profile.profile(self.clVars,service)
|
|
|
|
|
# Объединяем профили
|
|
|
|
|
clProf.applyProfiles()
|
|
|
|
|
if clProf.getError():
|
|
|
|
|
self.printERROR(clProf.getError())
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def searchService(self):
|
|
|
|
|
"""Поиск DN сервиса"""
|
|
|
|
|
name, value = self.relServDN.split('=')
|
|
|
|
|
resSearch = self.searchLdapDN(value, self.ServicesDN, name)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def delServicesAutostart(self, servInstalled):
|
|
|
|
|
"""Удаляет из автозагрузки сервисы
|
|
|
|
|
|
|
|
|
|
Входные данные - список названий сервисов
|
|
|
|
|
"""
|
|
|
|
|
flagError = False
|
|
|
|
|
flagLdap = False
|
|
|
|
|
for service in servInstalled:
|
|
|
|
|
if service == "unix" or service == "ldap":
|
|
|
|
|
if not self.delDaemonAutostart("slapd"):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
continue
|
|
|
|
|
elif service == "mail":
|
|
|
|
|
if not self.delDaemonAutostart("postfix"):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if not self.delDaemonAutostart("dovecot"):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
continue
|
|
|
|
|
elif service == "jabber":
|
|
|
|
|
if not self.delDaemonAutostart("ejabberd"):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
continue
|
|
|
|
|
else:
|
|
|
|
|
if not self.delDaemonAutostart("service"):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
continue
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def stopServices(self, servInstalled):
|
|
|
|
|
"""Останавливает все сервисы поданные на вход этому методу
|
|
|
|
|
|
|
|
|
|
Входные даннные - список названий сервисов
|
|
|
|
|
"""
|
|
|
|
|
flagError = False
|
|
|
|
|
flagLdap = False
|
|
|
|
|
for service in servInstalled:
|
|
|
|
|
if service == "unix" or service == "ldap":
|
|
|
|
|
flagLdap = True
|
|
|
|
|
continue
|
|
|
|
|
elif service == "mail":
|
|
|
|
|
if self.getRunDaemons(["postfix"]):
|
|
|
|
|
textLine = self.execProg("/etc/init.d/postfix stop")
|
|
|
|
|
if not ("ok" in textLine):
|
|
|
|
|
self.printERROR( "Postfix" + " " +
|
|
|
|
|
_("service is not stopped"))
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if self.getRunDaemons(["dovecot"]):
|
|
|
|
|
textLine = self.execProg("/etc/init.d/dovecot stop")
|
|
|
|
|
if not ("ok" in textLine):
|
|
|
|
|
self.printERROR(str("Dovecot") + " " +
|
|
|
|
|
_("service is not stopped"))
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
continue
|
|
|
|
|
elif service == "jabber":
|
|
|
|
|
if self.getRunService("jabber"):
|
|
|
|
|
textLine = self.execProg("/etc/init.d/ejabberd stop")
|
|
|
|
|
if not ("ok" in textLine):
|
|
|
|
|
self.printERROR( "Ejabberd" + " " +
|
|
|
|
|
_("service is not stopped"))
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
listProcess = self.execProg("ps ax",False,False)
|
|
|
|
|
killPid = []
|
|
|
|
|
for process in listProcess:
|
|
|
|
|
if "erlang" in process:
|
|
|
|
|
killPid.append(process.split(" ")[0])
|
|
|
|
|
if killPid and " ".join(killPid).strip():
|
|
|
|
|
textLine = self.execProg("kill %s" %" ".join(killPid))
|
|
|
|
|
if not (textLine == None):
|
|
|
|
|
self.printERROR(_("Can not 'kill %s'")\
|
|
|
|
|
%" ".join(killPid))
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
elif self.getRunService(service):
|
|
|
|
|
stopService = service
|
|
|
|
|
textLine = self.execProg("/etc/init.d/%s stop" %(stopService))
|
|
|
|
|
if not ("ok" in textLine):
|
|
|
|
|
self.printERROR( str(service) + " " +
|
|
|
|
|
_("service is not stopped"))
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagLdap:
|
|
|
|
|
if self.getRunService('ldap'):
|
|
|
|
|
textLine = self.execProg("/etc/init.d/slapd stop")
|
|
|
|
|
if not ("ok" in textLine):
|
|
|
|
|
self.printERROR( "LDAP" + " " +
|
|
|
|
|
_("service is not stopped"))
|
|
|
|
|
flagError = True
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def getUserPassword(self, options, optDialog, optStdIn, pwDialog=False):
|
|
|
|
|
"""Получить пароль у пользователя
|
|
|
|
|
|
|
|
|
|
options - полученные опции командной строки
|
|
|
|
|
optDialog - опция командной строки для вывода диалога для получения
|
|
|
|
|
пароля
|
|
|
|
|
optStdIn - опция командной строки для получения пароля из
|
|
|
|
|
стандартного ввода (stdin)
|
|
|
|
|
pwDialog - структура для вывода приглашения в режиме диалога
|
|
|
|
|
"""
|
|
|
|
|
userPwd = ""
|
|
|
|
|
if optStdIn and options.has_key(optStdIn):
|
|
|
|
|
pwdA = sys.stdin.readline().rstrip()
|
|
|
|
|
pwdB = sys.stdin.readline().rstrip()
|
|
|
|
|
elif optDialog and options.has_key(optDialog):
|
|
|
|
|
if not pwDialog:
|
|
|
|
|
pwDialog = [_("New password"),
|
|
|
|
|
_("Retype new password")]
|
|
|
|
|
pwdA = getpass.getpass(pwDialog[0]+":")
|
|
|
|
|
pwdB = getpass.getpass(pwDialog[1]+":")
|
|
|
|
|
if (optStdIn and options.has_key(optStdIn)) or\
|
|
|
|
|
(optDialog and options.has_key(optDialog)):
|
|
|
|
|
if not pwdA or not (pwdA == pwdB):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("password incorrect")+ ": " + _("try again"))
|
|
|
|
|
return False
|
|
|
|
|
userPwd = pwdA
|
|
|
|
|
userPwd = re.sub("(\W)", r"\\\1",userPwd)
|
|
|
|
|
return userPwd
|
|
|
|
|
|
|
|
|
|
def getRunDaemons(self, daemons, printError=False):
|
|
|
|
|
"""Проверка, запущены ли демоны"""
|
|
|
|
|
baseDir = "/var/run"
|
|
|
|
|
runDaemons = {}
|
|
|
|
|
for daemon in daemons:
|
|
|
|
|
# Проверка на запуск демона postfix
|
|
|
|
|
if daemon == 'postfix':
|
|
|
|
|
flagRun = False
|
|
|
|
|
listProcess = self.execProg("ps ax",False,False)
|
|
|
|
|
for process in listProcess:
|
|
|
|
|
if "postfix/master" in process:
|
|
|
|
|
flagRun = True
|
|
|
|
|
break
|
|
|
|
|
if flagRun:
|
|
|
|
|
runDaemons['postfix'] = True
|
|
|
|
|
else:
|
|
|
|
|
runDaemons['postfix'] = False
|
|
|
|
|
continue
|
|
|
|
|
addDirDict = {"slapd":("openldap","slapd.pid"),
|
|
|
|
|
"samba":("samba","smbd.pid"),
|
|
|
|
|
"dovecot":("dovecot","master.pid"),
|
|
|
|
|
"ejabberd":("/var/lib/init.d/daemons","ejabberd")}
|
|
|
|
|
if addDirDict[daemon][0][:1] == "/":
|
|
|
|
|
pidDir = addDirDict[daemon][0]
|
|
|
|
|
else:
|
|
|
|
|
pidDir = baseDir + "/" + addDirDict[daemon][0]
|
|
|
|
|
if os.access(pidDir, os.F_OK) and os.listdir(pidDir) and\
|
|
|
|
|
os.path.exists(os.path.join(pidDir,addDirDict[daemon][1])):
|
|
|
|
|
runDaemons[daemon] = True
|
|
|
|
|
else:
|
|
|
|
|
runDaemons[daemon] = False
|
|
|
|
|
if printError:
|
|
|
|
|
for daemon in daemons:
|
|
|
|
|
if not runDaemons[daemon]:
|
|
|
|
|
self.printERROR(_("Daemon %s is not started") %daemon)
|
|
|
|
|
if False in runDaemons.values():
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def getRunService(self, nameService, printError=False):
|
|
|
|
|
"""Проверка, запущен ли сервис с данным именем"""
|
|
|
|
|
flagError = False
|
|
|
|
|
if nameService == "mail":
|
|
|
|
|
daemons = ['postfix','dovecot']
|
|
|
|
|
if not self.getRunDaemons(daemons,printError):
|
|
|
|
|
flagError = True
|
|
|
|
|
elif nameService == "ldap":
|
|
|
|
|
if not self.getRunDaemons(['slapd'],printError):
|
|
|
|
|
flagError = True
|
|
|
|
|
elif nameService == "jabber":
|
|
|
|
|
if not self.getRunDaemons(['ejabberd'],printError):
|
|
|
|
|
flagError = True
|
|
|
|
|
else:
|
|
|
|
|
if not self.getRunDaemons([nameService],printError):
|
|
|
|
|
flagError = True
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR( nameService.capitalize + " " +
|
|
|
|
|
_("service is not started") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def unicList(self, lst):
|
|
|
|
|
"""Список уникальных элементов из списка не уникальных"""
|
|
|
|
|
return list(set(lst))
|
|
|
|
|
|
|
|
|
|
def setJpegPhotoUser(self, userName, photoPath, attr="uid"):
|
|
|
|
|
"""Добавляем jpeg фотографию пользователя в LDAP"""
|
|
|
|
|
import popen2
|
|
|
|
|
try:
|
|
|
|
|
FD = open(photoPath)
|
|
|
|
|
photoData = FD.read()
|
|
|
|
|
FD.close()
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("Not open file") + ": " + str(photoPath))
|
|
|
|
|
return False
|
|
|
|
|
searchUser = self.searchLdapDN(userName, self.relUsersDN, attr)
|
|
|
|
|
if not searchUser:
|
|
|
|
|
self.printERROR(_("User") + " " + str(userName) + " "+\
|
|
|
|
|
_("not found"))
|
|
|
|
|
return False
|
|
|
|
|
modAttrs = []
|
|
|
|
|
if not self.stringIsJpeg(photoData):
|
|
|
|
|
flagError = False
|
|
|
|
|
fOut, fIn, fErr = popen2.popen3("convert %s jpg:-" %photoPath)
|
|
|
|
|
fIn.close()
|
|
|
|
|
if fErr.read():
|
|
|
|
|
self.printERROR(_("Can not convert file '%s' in jpeg format")\
|
|
|
|
|
%photoPath)
|
|
|
|
|
flagError = True
|
|
|
|
|
fErr.close()
|
|
|
|
|
if not flagError:
|
|
|
|
|
photoData = fOut.read()
|
|
|
|
|
if not self.stringIsJpeg(photoData):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not convert file '%s' in jpeg format") %photoPath)
|
|
|
|
|
flagError = True
|
|
|
|
|
fOut.close()
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
if searchUser[0][0][1].has_key('jpegPhoto'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'jpegPhoto', photoData))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'jpegPhoto', photoData))
|
|
|
|
|
userDN = self.addDN("%s=%s"%(attr,userName),self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(userDN, modAttrs):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def removeDir(self, rmDir):
|
|
|
|
|
"""Рекурсивное удаление директории"""
|
|
|
|
|
if not os.path.exists(rmDir):
|
|
|
|
|
self.printERROR(_("Not found remove dir %s") %rmDir)
|
|
|
|
|
return False
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
# Сканируем директорию
|
|
|
|
|
scanObjs = fileObj.scanDirs([rmDir])
|
|
|
|
|
for fileRm in scanObjs[0].files:
|
|
|
|
|
# Удаляем файлы
|
|
|
|
|
os.remove(fileRm)
|
|
|
|
|
for linkRm in scanObjs[0].links:
|
|
|
|
|
# Удаляем ссылки
|
|
|
|
|
os.unlink(linkRm[1])
|
|
|
|
|
scanObjs[0].dirs.sort(lambda x, y: cmp(len(y), len(x)))
|
|
|
|
|
for dirRm in scanObjs[0].dirs:
|
|
|
|
|
# Удаляем директории
|
|
|
|
|
os.rmdir(dirRm)
|
|
|
|
|
os.rmdir(rmDir)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def removeEmptyDir(self, rmDir):
|
|
|
|
|
"""Удаление пустых директорий"""
|
|
|
|
|
if not os.path.exists(rmDir):
|
|
|
|
|
self.printERROR(_("Not found remove dir %s") %rmDir)
|
|
|
|
|
return False
|
|
|
|
|
rDir = rmDir
|
|
|
|
|
while os.listdir(rDir) == []:
|
|
|
|
|
os.rmdir(rDir)
|
|
|
|
|
rDir = os.path.split(rDir)[0]
|
|
|
|
|
if rDir == "/":
|
|
|
|
|
break
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def createUserDir(self, uid, gid, userDir, mode=0700):
|
|
|
|
|
"""Создание пользовательской директории"""
|
|
|
|
|
if not os.path.exists(userDir):
|
|
|
|
|
os.makedirs(userDir)
|
|
|
|
|
if mode:
|
|
|
|
|
os.chmod(userDir,mode)
|
|
|
|
|
os.chown(userDir,uid,gid)
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Path %s exists") %userDir)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def createUserFile(self, fileName, fileTxt, uid, gid, mode=0644):
|
|
|
|
|
"""Создает пользовательский файл с содержимым
|
|
|
|
|
|
|
|
|
|
Если директория файла не существует то ошибка
|
|
|
|
|
"""
|
|
|
|
|
userDir = os.path.split(fileName)[0]
|
|
|
|
|
if not os.path.exists(userDir):
|
|
|
|
|
self.printERROR(_("Path %s not exists") %userDir)
|
|
|
|
|
return False
|
|
|
|
|
fd = os.open(fileName, os.O_CREAT)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
os.chmod(fileName, mode)
|
|
|
|
|
os.chown(fileName,uid,gid)
|
|
|
|
|
FD = open(fileName, "r+")
|
|
|
|
|
FD.write(fileTxt)
|
|
|
|
|
FD.close()
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def saveVarsClient(self, listVarName):
|
|
|
|
|
"""Записывает переменные для клиента calcualte-client"""
|
|
|
|
|
#считаем переменные для клиента
|
|
|
|
|
dictVar = {}
|
|
|
|
|
flagError = False
|
|
|
|
|
for varName in listVarName:
|
|
|
|
|
value = self.clVars.Get(varName)
|
|
|
|
|
if not value and value != "":
|
|
|
|
|
self.printERROR(_("Variables %s is empty")%varName)
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
dictVar[varName] = value
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
#Запишем переменные в клиентскую секцию
|
|
|
|
|
for name,value in dictVar.items():
|
|
|
|
|
value = str(value)
|
|
|
|
|
if not self.clVars.Write(name,value,True,"remote","client"):
|
|
|
|
|
self.printERROR(_("Error writing variable %s")%name)
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def isServiceSetup(self, service):
|
|
|
|
|
"""Проверяет установлен ли сервис"""
|
|
|
|
|
if self.clVars:
|
|
|
|
|
if self.clVars.Get("sr_%s_set"%service) == "on":
|
|
|
|
|
return True
|
|
|
|
|
self.printERROR(_("Service %s is not installed")%service + " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def copyDir(self, destDir, srcDir):
|
|
|
|
|
"""Копируем директорию в другое место
|
|
|
|
|
|
|
|
|
|
При копировании сохраняются владелец, группа, права
|
|
|
|
|
"""
|
|
|
|
|
if not os.path.exists(destDir):
|
|
|
|
|
# Создаем домашнюю директорию
|
|
|
|
|
os.makedirs(destDir)
|
|
|
|
|
# Файловый объект
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
# Сканируем директорию
|
|
|
|
|
scanObjs = fileObj.scanDirs([srcDir])
|
|
|
|
|
if not scanObjs:
|
|
|
|
|
return True
|
|
|
|
|
for dirSrc in scanObjs[0].dirs:
|
|
|
|
|
#создаем в домашней директории директории из srcDir
|
|
|
|
|
dirName = destDir + dirSrc.split(srcDir)[1]
|
|
|
|
|
os.mkdir(dirName)
|
|
|
|
|
mode,uid,gid = fileObj.getModeFile(dirSrc)
|
|
|
|
|
os.chown(dirName, uid,gid)
|
|
|
|
|
os.chmod(destDir, mode)
|
|
|
|
|
for fileCopy in scanObjs[0].files:
|
|
|
|
|
oldFile = destDir + fileCopy.split(srcDir)[1]
|
|
|
|
|
#копируем файлы
|
|
|
|
|
fileObj.openFiles(fileCopy, oldFile)
|
|
|
|
|
fileObj.saveOldFile()
|
|
|
|
|
fileObj.oldProfile = False
|
|
|
|
|
fileObj.closeFiles()
|
|
|
|
|
os.chown(oldFile, fileObj._uid, fileObj._gid)
|
|
|
|
|
os.chmod(oldFile, fileObj._mode)
|
|
|
|
|
for linkCreate in scanObjs[0].links:
|
|
|
|
|
#копируем ссылки
|
|
|
|
|
dst = destDir + linkCreate[1].split(srcDir)[1]
|
|
|
|
|
srcDestList = linkCreate[0].split(srcDir)
|
|
|
|
|
if len(srcDestList)>1:
|
|
|
|
|
src = destDir + srcDestList[1]
|
|
|
|
|
else:
|
|
|
|
|
src = linkCreate[0]
|
|
|
|
|
os.symlink(src,dst)
|
|
|
|
|
mode,uid,gid = fileObj.getModeFile(linkCreate)
|
|
|
|
|
#Изменение прав на ссылки
|
|
|
|
|
os.lchown(dst, uid, gid)
|
|
|
|
|
mode,uid,gid = fileObj.getModeFile(srcDir)
|
|
|
|
|
os.chmod(destDir, mode)
|
|
|
|
|
os.chown(destDir, uid,gid)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def addDN(self, *arg):
|
|
|
|
|
"""Складывает текстовые элементы DN"""
|
|
|
|
|
DNs = []
|
|
|
|
|
for dn in arg:
|
|
|
|
|
if dn:
|
|
|
|
|
DNs.append(dn)
|
|
|
|
|
return ','.join(DNs)
|
|
|
|
|
|
|
|
|
|
def chownR(self, directory, uid, gid):
|
|
|
|
|
"""изменяет владельца и группу
|
|
|
|
|
|
|
|
|
|
для всех файлов и директорий внутри directory
|
|
|
|
|
"""
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
scanObjs = fileObj.scanDirs([directory])
|
|
|
|
|
# меняем владельца домашней директории
|
|
|
|
|
os.chown(directory, uid,gid)
|
|
|
|
|
# Меняем владельца директорий
|
|
|
|
|
for dirCh in scanObjs[0].dirs:
|
|
|
|
|
os.chown(dirCh, uid,gid)
|
|
|
|
|
# Меняем владельца файлов
|
|
|
|
|
for fileCh in scanObjs[0].files:
|
|
|
|
|
os.chown(fileCh, uid,gid)
|
|
|
|
|
# Меняем владельца ссылок
|
|
|
|
|
for linkCh in scanObjs[0].links:
|
|
|
|
|
os.lchown(linkCh[1], uid, gid)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def modAttrsDN(self, relDN, modAttrs):
|
|
|
|
|
"""Модифицирует аттрибуты DN"""
|
|
|
|
|
DN = self.addDN(relDN,self.baseDN)
|
|
|
|
|
if modAttrs:
|
|
|
|
|
try:
|
|
|
|
|
self.conLdap.modify_s(DN, modAttrs)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def modifyElemDN(self, relDN, newFirstDn):
|
|
|
|
|
"""Изменяет основной элемент DN (uid, cn и др.)"""
|
|
|
|
|
DN = self.addDN(relDN,self.baseDN)
|
|
|
|
|
try:
|
|
|
|
|
self.conLdap.modrdn_s(DN, newFirstDn)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def delDN(self, relDN):
|
|
|
|
|
DN = self.addDN(relDN,self.baseDN)
|
|
|
|
|
try:
|
|
|
|
|
self.conLdap.delete_s(DN)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getMaxAttrDN(self, relDN, name, attr, numMin, numMax, attrSearch):
|
|
|
|
|
"""Находит максимальный добавленный аттрибут в LDAP DN"""
|
|
|
|
|
resSearch = self.searchLdapDN(name, relDN, attr, [attrSearch])
|
|
|
|
|
lst = []
|
|
|
|
|
lst.append(0)
|
|
|
|
|
if resSearch:
|
|
|
|
|
for scope in resSearch:
|
|
|
|
|
if scope[0][1].has_key(attrSearch):
|
|
|
|
|
uid = int(scope[0][1][attrSearch][0])
|
|
|
|
|
if uid<=numMax and uid>=numMin:
|
|
|
|
|
lst.append(uid)
|
|
|
|
|
return max(lst)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def fullElementDNtoText(self, relDN):
|
|
|
|
|
"""Выводит все внутренние элементы DN виде текста"""
|
|
|
|
|
DN = self.addDN(relDN, self.baseDN)
|
|
|
|
|
listDN=[]
|
|
|
|
|
try:
|
|
|
|
|
dnList = self.conLdap.search_s(DN,
|
|
|
|
|
ldap.SCOPE_SUBTREE,
|
|
|
|
|
'(objectclass=*)',None)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR("fullElementDN: "+e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
FDOUT = StringIO.StringIO("")
|
|
|
|
|
writer = LDIFWriter(FDOUT)
|
|
|
|
|
for dn, f in dnList:
|
|
|
|
|
writer.unparse(dn, f)
|
|
|
|
|
FDOUT.seek(0)
|
|
|
|
|
return FDOUT.read()
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def deleteDN(self, relDelDN):
|
|
|
|
|
"""Удаляет DN и все внутренние элементы"""
|
|
|
|
|
delDN = self.addDN(relDelDN, self.baseDN)
|
|
|
|
|
delListDN=[]
|
|
|
|
|
try:
|
|
|
|
|
dnList = self.conLdap.search_s(delDN,
|
|
|
|
|
ldap.SCOPE_SUBTREE,
|
|
|
|
|
'(objectclass=*)',
|
|
|
|
|
[''])
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR("deleteDN: "+e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
for dn, f in dnList:
|
|
|
|
|
delListDN.append(dn)
|
|
|
|
|
delListDN.sort(lambda x, y: cmp(len(y), len(x)))
|
|
|
|
|
for dn in delListDN:
|
|
|
|
|
try:
|
|
|
|
|
self.conLdap.delete_s(dn)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR("deleteDN: "+e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def execProg(self, cmdStrProg, inStr=False, retFull=True):
|
|
|
|
|
"""Выполняет внешнюю программу
|
|
|
|
|
|
|
|
|
|
Параметры:
|
|
|
|
|
cmdStrProg внешняя программа
|
|
|
|
|
inStr данные передаваемые программе на страндартный вход.
|
|
|
|
|
Возвращаемые параметры:
|
|
|
|
|
строка которую выведет внешняя программа
|
|
|
|
|
"""
|
|
|
|
|
return cl_utils.runOsCommand(cmdStrProg, inStr, retFull)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def createLdif(self, ldifFile):
|
|
|
|
|
"""Cоздает ldif из ldif - профиля"""
|
|
|
|
|
if not os.access(ldifFile, os.F_OK):
|
|
|
|
|
self.setError(_("File not found") + ":\n " + ldifFile)
|
|
|
|
|
return False
|
|
|
|
|
FD = open (ldifFile)
|
|
|
|
|
ldifProfile = FD.read()
|
|
|
|
|
FD.close()
|
|
|
|
|
clProf = cl_profile.profile(self.clVars)
|
|
|
|
|
# Применяем условия к профилю
|
|
|
|
|
ldifProfile = clProf.applyTermsProfile(ldifProfile,ldifFile)
|
|
|
|
|
# Заменяем переменные
|
|
|
|
|
ldifProfile = clProf.applyVarsProfile(ldifProfile,ldifFile)
|
|
|
|
|
return ldifProfile
|
|
|
|
|
|
|
|
|
|
def searchLineInFile(self, name, fileName, numEl=0):
|
|
|
|
|
"""Ищет строку в которой есть название разделенное ':'
|
|
|
|
|
|
|
|
|
|
в файле похожем на /etc/passwd"""
|
|
|
|
|
if os.path.exists(fileName):
|
|
|
|
|
FD = open(fileName)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
lineFound = ""
|
|
|
|
|
for line in lines:
|
|
|
|
|
if name == line.split(":")[numEl]:
|
|
|
|
|
lineFound = line
|
|
|
|
|
break
|
|
|
|
|
if lineFound:
|
|
|
|
|
return lineFound
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getMaxInFile(self, fileName, numMin, numMax, numEl=2):
|
|
|
|
|
"""Получаем максимальный номер из файла похожего на /etc/group"""
|
|
|
|
|
lst = []
|
|
|
|
|
lst.append(0)
|
|
|
|
|
if os.path.exists(fileName):
|
|
|
|
|
FD = open(fileName)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
num = int(line.split(":")[numEl])
|
|
|
|
|
if num<=numMax and num>=numMin:
|
|
|
|
|
lst.append(num)
|
|
|
|
|
return max(lst)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getLdapObjInFile(self, part="admin"):
|
|
|
|
|
"""Получаем объект ldapFunction из ini файла
|
|
|
|
|
|
|
|
|
|
В выходном объекте есть соединение с LDAP сервером: self.conLdap
|
|
|
|
|
"""
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar(part,"DN")
|
|
|
|
|
adminPw = ldapParser.getVar(part,"PASS")
|
|
|
|
|
if not (adminDn or adminPw):
|
|
|
|
|
if part == "admin":
|
|
|
|
|
service = "LDAP"
|
|
|
|
|
else:
|
|
|
|
|
service = part
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Admin password for the service %s could not be found")%service+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
if ldapObj.getError():
|
|
|
|
|
self.printERROR (_("LDAP connect error") + ": " +\
|
|
|
|
|
ldapObj.getError().strip())
|
|
|
|
|
return False
|
|
|
|
|
# Устанавливаем у объекта соединение и объект LDAP функций
|
|
|
|
|
self.ldapObj = ldapObj
|
|
|
|
|
self.conLdap = ldapObj.conLdap
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def dialogYn(self, message):
|
|
|
|
|
def getChar():
|
|
|
|
|
fd = sys.stdin.fileno()
|
|
|
|
|
oldSet = termios.tcgetattr(fd)
|
|
|
|
|
tty.setraw(fd)
|
|
|
|
|
char = sys.stdin.read(1)
|
|
|
|
|
termios.tcsetattr(fd, termios.TCSADRAIN, oldSet)
|
|
|
|
|
return char
|
|
|
|
|
def term(char):
|
|
|
|
|
if ord(char) == 3:
|
|
|
|
|
return None
|
|
|
|
|
if char == "Y":
|
|
|
|
|
return True
|
|
|
|
|
elif char == "n":
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
char = getChar()
|
|
|
|
|
return term(char)
|
|
|
|
|
sys.stdout.write(message + ":")
|
|
|
|
|
char = getChar()
|
|
|
|
|
res = term(char)
|
|
|
|
|
sys.stdout.write("\n")
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def dialogYesNo(self, message):
|
|
|
|
|
sys.stdout.write(message + ": ")
|
|
|
|
|
strIn=sys.stdin.readline().lower().strip()
|
|
|
|
|
sys.stdout.write("\n")
|
|
|
|
|
if "yes" == strIn:
|
|
|
|
|
return True
|
|
|
|
|
elif "no" == strIn:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return self.dialogYesNo(message)
|
|
|
|
|
|
|
|
|
|
def createClVars(self, clVars=False):
|
|
|
|
|
"""Создает объект Vars"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
# Устанавливаем у объекта объект Vars
|
|
|
|
|
self.clVars = clVars
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def searchLdapDN(self, name, relDN, attr, retAttr=None):
|
|
|
|
|
"""Находит DN в LDAP"""
|
|
|
|
|
DN = self.addDN(relDN,self.baseDN)
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "%s=%s" %(attr,name)
|
|
|
|
|
retrieveAttributes = retAttr
|
|
|
|
|
resSearch = self.ldapObj.ldapSearch(DN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
class servUnix(shareLdap):
|
|
|
|
|
"""Методы севисa Unix"""
|
|
|
|
|
def __init__(self, smbObj=False):
|
|
|
|
|
shareLdap.__init__(self)
|
|
|
|
|
# минимальное и максимальное значение gid-ов системных групп
|
|
|
|
|
#(Computers, и.т. д)
|
|
|
|
|
self.maxSysGid = 999
|
|
|
|
|
self.minSysGid = 900
|
|
|
|
|
# максимальный и минимальный uid
|
|
|
|
|
self.maxUid = self.getUidMax()
|
|
|
|
|
self.minUid = self.getUidMin()
|
|
|
|
|
# максимальный и минимальный gid
|
|
|
|
|
self.maxGid = self.maxUid
|
|
|
|
|
self.minGid = self.minUid
|
|
|
|
|
self.relGrDN = 'ou=Groups'
|
|
|
|
|
self.relUsDN = 'ou=Users'
|
|
|
|
|
self.relServDN = 'ou=Unix'
|
|
|
|
|
self.relDN = self.addDN(self.relServDN,self.ServicesDN)
|
|
|
|
|
# DN пользователей, относительно базового DN
|
|
|
|
|
self.relUsersDN = self.addDN(self.relUsDN, self.relDN)
|
|
|
|
|
# DN групп пользователей, относительно базового DN
|
|
|
|
|
self.relGroupsDN = self.addDN(self.relGrDN, self.relDN)
|
|
|
|
|
# Коментарий к группе по умолчанию
|
|
|
|
|
self.groupGecos = "Calculate group"
|
|
|
|
|
# Базовая директория пользователей
|
|
|
|
|
self.baseDir = "/home"
|
|
|
|
|
# Название пользователя по умолчанию
|
|
|
|
|
self.fullNameUser = "Calculate user"
|
|
|
|
|
# Оболочка пользователя по умолчанию
|
|
|
|
|
self.userShell = "/bin/bash"
|
|
|
|
|
# Скелетная директория для создания пользователя
|
|
|
|
|
self.skelDir = "/etc/skel"
|
|
|
|
|
# Алгоритм шифрования пароля для LDAP пользователя
|
|
|
|
|
self.userCrypt = "{SSHA}"
|
|
|
|
|
# Используемые ldif файлы
|
|
|
|
|
self.ldifFileMachine =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/samba_machine.ldif"
|
|
|
|
|
self.ldifFileUser =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/unix_user.ldif"
|
|
|
|
|
self.ldifFileGroup =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/unix_group.ldif"
|
|
|
|
|
self.ldifFileBase =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/unix_base.ldif"
|
|
|
|
|
if smbObj:
|
|
|
|
|
# получаем объект сервиса Samba
|
|
|
|
|
self.servSambaObj = smbObj
|
|
|
|
|
else:
|
|
|
|
|
# создаем объект сервиса Samba
|
|
|
|
|
self.servSambaObj = servSamba(self)
|
|
|
|
|
# создаем объект сервиса Mail
|
|
|
|
|
self.servMailObj = servMail(self)
|
|
|
|
|
# DN, компьютеров относительно базового DN
|
|
|
|
|
self.relComputersDN = self.servSambaObj.relComputersDN
|
|
|
|
|
|
|
|
|
|
def getLdapObjInFile(self):
|
|
|
|
|
"""Cоединение с LDAP администратором Samba сервиса"""
|
|
|
|
|
return shareLdap.getLdapObjInFile(self, "unix")
|
|
|
|
|
|
|
|
|
|
def createHomeDir(self, userName, homeDir, skelDir):
|
|
|
|
|
"""Создаем домашнюю директорию пользователя
|
|
|
|
|
|
|
|
|
|
создание происходит после создания пользователя
|
|
|
|
|
"""
|
|
|
|
|
resLdap = self.searchUnixUser(userName)
|
|
|
|
|
if resLdap:
|
|
|
|
|
uid = int(resLdap[0][0][1]['uidNumber'][0])
|
|
|
|
|
gid = int(resLdap[0][0][1]['gidNumber'][0])
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
if not os.path.exists(homeDir):
|
|
|
|
|
# Создаем домашнюю директорию
|
|
|
|
|
os.makedirs(homeDir)
|
|
|
|
|
# Файловый объект
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
# Сканируем скелетную директорию
|
|
|
|
|
scanObjs = fileObj.scanDirs([skelDir])
|
|
|
|
|
if not scanObjs:
|
|
|
|
|
return True
|
|
|
|
|
for dirCreate in scanObjs[0].dirs:
|
|
|
|
|
#создаем в домашней директории директории из /etc/skel
|
|
|
|
|
fileObj.createDir(skelDir, dirCreate, homeDir)
|
|
|
|
|
dirName = homeDir + dirCreate.split(skelDir)[1]
|
|
|
|
|
os.chown(dirName, uid,gid)
|
|
|
|
|
for fileCopy in scanObjs[0].files:
|
|
|
|
|
oldFile = homeDir + fileCopy.split(skelDir)[1]
|
|
|
|
|
#копируем файлы
|
|
|
|
|
fileObj.openFiles(fileCopy, oldFile)
|
|
|
|
|
fileObj.saveOldFile()
|
|
|
|
|
fileObj.oldProfile = False
|
|
|
|
|
fileObj.closeFiles()
|
|
|
|
|
os.chown(oldFile, uid,gid)
|
|
|
|
|
for linkCreate in scanObjs[0].links:
|
|
|
|
|
#копируем ссылки
|
|
|
|
|
dst = homeDir + linkCreate[1].split(skelDir)[1]
|
|
|
|
|
srcHomeList = linkCreate[0].split(skelDir)
|
|
|
|
|
if len(srcHomeList)>1:
|
|
|
|
|
src = homeDir + srcHomeList[1]
|
|
|
|
|
else:
|
|
|
|
|
src = linkCreate[0]
|
|
|
|
|
os.symlink(src,dst)
|
|
|
|
|
#Изменение прав на ссылки
|
|
|
|
|
os.lchown(dst, uid, gid)
|
|
|
|
|
os.chmod(homeDir, 0700)
|
|
|
|
|
os.chown(homeDir, uid,gid)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def searchPasswdUser(self, userName):
|
|
|
|
|
"""Ищет пользователей в /etc/passwd"""
|
|
|
|
|
filePasswd = "/etc/passwd"
|
|
|
|
|
return self.searchLineInFile(userName, filePasswd)
|
|
|
|
|
|
|
|
|
|
def searchGroupGid(self, groupId):
|
|
|
|
|
"""Ищет gid в /etc/group"""
|
|
|
|
|
gid = str(groupId)
|
|
|
|
|
fileGroup = "/etc/group"
|
|
|
|
|
return self.searchLineInFile(gid, fileGroup, 2)
|
|
|
|
|
|
|
|
|
|
def searchGroupGroupName(self, groupName):
|
|
|
|
|
"""Ищет имя группы в /etc/group"""
|
|
|
|
|
fileGroup = "/etc/group"
|
|
|
|
|
return self.searchLineInFile(groupName, fileGroup)
|
|
|
|
|
|
|
|
|
|
def searchUnixGroupName(self, groupName):
|
|
|
|
|
"""Находит группу сервиса Unix по её имени"""
|
|
|
|
|
resSearch = self.searchLdapDN(groupName, self.relGroupsDN, "cn")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUnixUser(self, userName):
|
|
|
|
|
"""Находит пользователя сервиса Unix"""
|
|
|
|
|
resSearch = self.searchLdapDN(userName, self.relUsersDN, "uid")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUnixUserPrimGroup(self, groupId):
|
|
|
|
|
"""Находит пользователей с первичной группой groupId"""
|
|
|
|
|
resSearch = self.searchLdapDN(str(groupId), self.relUsersDN,
|
|
|
|
|
"gidNumber")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUnixGid(self, groupId):
|
|
|
|
|
"""Находит группу сервиса Unix по ёе id"""
|
|
|
|
|
resSearch = self.searchLdapDN(str(groupId), self.relGroupsDN,
|
|
|
|
|
"gidNumber")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUnixMemberGid(self, userName):
|
|
|
|
|
"""Ищет группы сервиса Unix в котрых есть данный пользователь"""
|
|
|
|
|
resSearch = self.searchLdapDN(userName, self.relGroupsDN,
|
|
|
|
|
"memberUid")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUidPasswd(self, userId):
|
|
|
|
|
"""Находит пользователя по его идентефикатору из /etc/passwd"""
|
|
|
|
|
filePasswd = "/etc/passwd"
|
|
|
|
|
return self.searchLineInFile(str(userId), filePasswd, 2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def searchUidUnix(self, userId):
|
|
|
|
|
"""Находит пользователя по его идентефикатору из LDAP"""
|
|
|
|
|
resSearch = self.searchLdapDN(str(userId), self.relUsersDN,
|
|
|
|
|
"uidNumber")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchGroupsUnix(self, userGroups, printError=True):
|
|
|
|
|
"""Ищет список групп из списка userGroups в LDAP
|
|
|
|
|
|
|
|
|
|
Список групп может состоять из чисел или названий групп
|
|
|
|
|
Возвращает список имен групп
|
|
|
|
|
"""
|
|
|
|
|
userGroupNames = []
|
|
|
|
|
flagInt = True
|
|
|
|
|
for gid in userGroups:
|
|
|
|
|
try:
|
|
|
|
|
int(gid)
|
|
|
|
|
except:
|
|
|
|
|
flagInt = False
|
|
|
|
|
break
|
|
|
|
|
flagError = False
|
|
|
|
|
if flagInt:
|
|
|
|
|
for gidNumber in userGroups:
|
|
|
|
|
res = self.searchUnixGid(gidNumber)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
userGroupNames.append(res[0][0][1]['cn'][0])
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Group number %s is not found in Unix service") %\
|
|
|
|
|
str(gidNumber) + "...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
for groupName in userGroups:
|
|
|
|
|
res = self.searchUnixGroupName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Group name %s is not found in Unix service") %\
|
|
|
|
|
str(groupName) + "...")
|
|
|
|
|
return False
|
|
|
|
|
userGroupNames = userGroups
|
|
|
|
|
return userGroupNames
|
|
|
|
|
|
|
|
|
|
def searchGroupsGroups(self, userGroups, printError=True):
|
|
|
|
|
"""Ищет список групп из списка userGroups в /etc/group
|
|
|
|
|
|
|
|
|
|
Список групп может состоять из чисел или названий групп
|
|
|
|
|
Возвращает список имен групп
|
|
|
|
|
"""
|
|
|
|
|
userGroupNames = []
|
|
|
|
|
flagInt = True
|
|
|
|
|
for gid in userGroups:
|
|
|
|
|
try:
|
|
|
|
|
int(gid)
|
|
|
|
|
except:
|
|
|
|
|
flagInt = False
|
|
|
|
|
break
|
|
|
|
|
flagError = False
|
|
|
|
|
if flagInt:
|
|
|
|
|
for gidNumber in userGroups:
|
|
|
|
|
res = self.searchGroupGid(gidNumber)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
userGroupNames.append(res.split(':')[0])
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group number %s is not found in") %\
|
|
|
|
|
str(gidNumber) + " /etc/group ...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
for groupName in userGroups:
|
|
|
|
|
res = self.searchGroupGroupName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group name %s is not found in") %\
|
|
|
|
|
str(groupName) + " /etc/group ...")
|
|
|
|
|
return False
|
|
|
|
|
userGroupNames = userGroups
|
|
|
|
|
return userGroupNames
|
|
|
|
|
|
|
|
|
|
def searchUsersInGroupUnix(self, usersNames, groupName):
|
|
|
|
|
"""Ищет спиcок пользователей в группе, ищет в Unix
|
|
|
|
|
|
|
|
|
|
В случае успеха выводит список найденных пользователей
|
|
|
|
|
если нет группы False
|
|
|
|
|
если ничего не найдено пустой список
|
|
|
|
|
"""
|
|
|
|
|
res = self.searchUnixGroupName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
findUsers = []
|
|
|
|
|
if res[0][0][1].has_key('memberUid'):
|
|
|
|
|
usersInGroup = res[0][0][1]['memberUid']
|
|
|
|
|
for userName in usersNames:
|
|
|
|
|
if userName in usersInGroup:
|
|
|
|
|
findUsers.append(userName)
|
|
|
|
|
return findUsers
|
|
|
|
|
|
|
|
|
|
def searchUsersInGroupGroup(self, usersNames, groupName):
|
|
|
|
|
"""Ищет спиcок пользователей в группе, ищет в /etc/groups
|
|
|
|
|
|
|
|
|
|
В случае успеха выводит список найденных пользователей
|
|
|
|
|
если нет группы False
|
|
|
|
|
если ничего не найдено пустой список
|
|
|
|
|
"""
|
|
|
|
|
res = self.searchGroupGroupName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
findUsers = []
|
|
|
|
|
res = res.rstrip()
|
|
|
|
|
usersInGroup = res.split(':')[3]
|
|
|
|
|
if not usersInGroup:
|
|
|
|
|
return findUsers
|
|
|
|
|
usersInGroup = usersInGroup.split(',')
|
|
|
|
|
for userName in usersNames:
|
|
|
|
|
if userName in usersInGroup:
|
|
|
|
|
findUsers.append(userName)
|
|
|
|
|
return findUsers
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def addGroupUnixServer(self, groupName, options, printSuccess=True):
|
|
|
|
|
"""Добавляет группу пользователей Unix"""
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix"):
|
|
|
|
|
return False
|
|
|
|
|
# Если группа существует выходим без ошибки
|
|
|
|
|
flagSearchGroups = True
|
|
|
|
|
if options.has_key('f'):
|
|
|
|
|
flagSearchGroups = False
|
|
|
|
|
if flagSearchGroups and self.searchGroupGroupName(groupName):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("group name %s is found in") % str(groupName) +\
|
|
|
|
|
" /etc/group ...")
|
|
|
|
|
return False
|
|
|
|
|
if self.searchUnixGroupName(groupName):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("group name %s is found in Unix service") %\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Set("ur_group",groupName)
|
|
|
|
|
# номер группы
|
|
|
|
|
gid = str(self.getMaxGid())
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
gid = options['g']
|
|
|
|
|
try:
|
|
|
|
|
int(gid)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("GID must be is number") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if flagSearchGroups and self.searchGroupGid(gid):
|
|
|
|
|
self.printERROR(_("GID is found in") + " /etc/group ...")
|
|
|
|
|
return False
|
|
|
|
|
if self.searchUnixGid(gid):
|
|
|
|
|
self.printERROR(_("GID is found in Unix service") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Set("ur_group_id", gid)
|
|
|
|
|
# Коментарий к группе
|
|
|
|
|
gecos = self.groupGecos
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
gecos = options['c']
|
|
|
|
|
self.clVars.Set("ur_group_comment",gecos)
|
|
|
|
|
ldifFile = self.ldifFileGroup
|
|
|
|
|
groupLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not groupLdif:
|
|
|
|
|
print self.getError()
|
|
|
|
|
return False
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
self.ldapObj.ldapAdd(groupLdif)
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('p'):
|
|
|
|
|
sys.stdout.write(gid)
|
|
|
|
|
else:
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Added group in Unix service") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def addMachineLdapServer(self, machineName, options):
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix"):
|
|
|
|
|
return False
|
|
|
|
|
"""Добавляет Unix машину в LDAP-сервер"""
|
|
|
|
|
machineLogin = machineName.replace('$','') + "$"
|
|
|
|
|
groupName = self.clVars.Get('sr_samba_machine_group')
|
|
|
|
|
resSearch = self.searchUnixGroupName(groupName)
|
|
|
|
|
if resSearch:
|
|
|
|
|
groupId = resSearch[0][0][1]['gidNumber'][0]
|
|
|
|
|
else:
|
|
|
|
|
gr = self.staticGroups["Computers"]
|
|
|
|
|
groupId = gr.gid
|
|
|
|
|
options = {'g':gr.gid,'c':gr.comment}
|
|
|
|
|
if not self.addGroupUnixServer(groupName, options):
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Set('sr_samba_machine_login', machineLogin)
|
|
|
|
|
# Находим последний добавленный id
|
|
|
|
|
userIdNumber = str(self.getMaxUid())
|
|
|
|
|
self.clVars.Set('sr_samba_machine_id',userIdNumber)
|
|
|
|
|
self.clVars.Set('sr_samba_machine_gid',groupId)
|
|
|
|
|
ldifFile = self.ldifFileMachine
|
|
|
|
|
userLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
#Добавляем пользователя в LDAP
|
|
|
|
|
self.ldapObj.ldapAdd(userLdif)
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Added machine") + "...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def addUserUnixServer(self,userName,options,printSuccess=True,pwd=False):
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix"):
|
|
|
|
|
return False
|
|
|
|
|
"""Добавляет Unix пользователя в LDAP-сервер"""
|
|
|
|
|
if self.searchUnixUser(userName):
|
|
|
|
|
self.printERROR(_("User exists in Unix service"))
|
|
|
|
|
return False
|
|
|
|
|
elif self.searchPasswdUser(userName):
|
|
|
|
|
self.printERROR(_("User exists in") + " /etc/passwd")
|
|
|
|
|
return False
|
|
|
|
|
# id нового пользователя
|
|
|
|
|
userId = str(self.getMaxUid())
|
|
|
|
|
self.clVars.Set("ur_name", userName)
|
|
|
|
|
baseDir = self.baseDir
|
|
|
|
|
# Базовая домашняя директория
|
|
|
|
|
if options.has_key('b'):
|
|
|
|
|
baseDir = options['b']
|
|
|
|
|
# Устанавливаем скелетную директорию
|
|
|
|
|
if options.has_key('k'):
|
|
|
|
|
skelDir = options['k']
|
|
|
|
|
else:
|
|
|
|
|
skelDir = self.skelDir
|
|
|
|
|
# Устанавливаем домашнюю директорию
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
homeDir = options['d']
|
|
|
|
|
else:
|
|
|
|
|
homeDir = os.path.join(baseDir, userName)
|
|
|
|
|
self.clVars.Set("ur_home_path",homeDir)
|
|
|
|
|
|
|
|
|
|
fullNameUser = self.fullNameUser
|
|
|
|
|
# Полное имя пользователя
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
fullNameUser = options['c']
|
|
|
|
|
self.clVars.Set("ur_fio",fullNameUser)
|
|
|
|
|
# По умолчанию пользователя не видно
|
|
|
|
|
visible = '0'
|
|
|
|
|
if options.has_key('v'):
|
|
|
|
|
visible = '1'
|
|
|
|
|
self.clVars.Set("ur_visible",visible)
|
|
|
|
|
# Оболочка пользователя
|
|
|
|
|
userShell = self.userShell
|
|
|
|
|
if options.has_key('s'):
|
|
|
|
|
userShell = options['s']
|
|
|
|
|
self.clVars.Set("ur_shell", userShell)
|
|
|
|
|
|
|
|
|
|
# id пользователя
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
userId = options['u']
|
|
|
|
|
try:
|
|
|
|
|
int(userId)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("UID is not number") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if self.searchUidUnix(userId):
|
|
|
|
|
self.printERROR("UID %s "%userId + \
|
|
|
|
|
_("exists in Unix service") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if self.searchUidPasswd(userId):
|
|
|
|
|
self.printERROR("UID %s "%userId+_("exists in") + \
|
|
|
|
|
" /etc/passwd"+ " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
self.clVars.Set("ur_id",userId)
|
|
|
|
|
|
|
|
|
|
# Добавляем пользователя в группы (находим имена групп)
|
|
|
|
|
if options.has_key('G'):
|
|
|
|
|
userGroups = options['G'].split(',')
|
|
|
|
|
#список имен добавляемых групп
|
|
|
|
|
userGroupNames = self.searchGroupsUnix(userGroups)
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
userGid = str(self.getMaxGid())
|
|
|
|
|
# Группа пользователя
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
userGid = options['g']
|
|
|
|
|
userGidNamesLdap = self.searchGroupsUnix([userGid], False)
|
|
|
|
|
userGidNamesPasswd = self.searchGroupsGroups([userGid], False)
|
|
|
|
|
if userGidNamesPasswd:
|
|
|
|
|
#Имя группы пользователя
|
|
|
|
|
groupName = userGidNamesPasswd[0]
|
|
|
|
|
elif userGidNamesLdap:
|
|
|
|
|
#Имя группы пользователя
|
|
|
|
|
groupName = userGidNamesLdap[0]
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group %s is not found") % str(userGid) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
if self.searchGroupGroupName(userName):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group name %s is found in")%str(userName) +\
|
|
|
|
|
" /etc/group ...")
|
|
|
|
|
return False
|
|
|
|
|
if self.searchUnixGroupName(userName):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group name %s is found in Unix serivce")%str(userName)+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
if pwd:
|
|
|
|
|
userPwd = pwd
|
|
|
|
|
else:
|
|
|
|
|
userPwd = self.getUserPassword(options, "p", "P")
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
if not userPwd:
|
|
|
|
|
userPwdHash = "crypt{xxx}"
|
|
|
|
|
else:
|
|
|
|
|
userPwdHash =\
|
|
|
|
|
self.execProg("slappasswd -s %s -h %s" %(userPwd,self.userCrypt))
|
|
|
|
|
if not userPwdHash:
|
|
|
|
|
self.printERROR(_("ERROR") + ": " +\
|
|
|
|
|
_("create crypto password"))
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Set("ur_hash",userPwdHash)
|
|
|
|
|
# флаги добавления
|
|
|
|
|
flagAdd = {}
|
|
|
|
|
# Добавление основной группы пользователя
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
resLdap = self.searchUnixGroupName(groupName)
|
|
|
|
|
resGroup = self.searchGroupGroupName(groupName)
|
|
|
|
|
if not (resLdap or resGroup):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
"gid=" + userGid + " " + _("is not found"))
|
|
|
|
|
return False
|
|
|
|
|
if resGroup:
|
|
|
|
|
userGid = resGroup.split(":")[2]
|
|
|
|
|
if resLdap:
|
|
|
|
|
userGid = resLdap[0][0][1]['gidNumber'][0]
|
|
|
|
|
else:
|
|
|
|
|
flagAddGroup = self.addGroupUnixServer(userName,{},False)
|
|
|
|
|
flagAdd['group'] = flagAddGroup
|
|
|
|
|
if not flagAddGroup:
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Set("ur_gid", userGid)
|
|
|
|
|
|
|
|
|
|
ldifFile = self.ldifFileUser
|
|
|
|
|
userLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
#Добавляем пользователя в LDAP
|
|
|
|
|
self.ldapObj.ldapAdd(userLdif)
|
|
|
|
|
#ldapObj.ldapAdd(userLdif1)
|
|
|
|
|
#Добавляем его в другие группы (опция G)
|
|
|
|
|
if options.has_key('G') and userGroupNames:
|
|
|
|
|
for group in userGroupNames:
|
|
|
|
|
self.addUsersGroupUnix([userName],group)
|
|
|
|
|
# не переделывать на else
|
|
|
|
|
flagError = False
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
flagError = True
|
|
|
|
|
removeHomeBack = False
|
|
|
|
|
if not flagError:
|
|
|
|
|
# Востановим (home на сервере) удаленного пользователя
|
|
|
|
|
message = _("Restored deleted user %s")% userName + "\n" +\
|
|
|
|
|
_("'yes', 'no'")
|
|
|
|
|
resHomeDir = self.restorePathDelUser(userName, homeDir,
|
|
|
|
|
"unix/home", message, self)
|
|
|
|
|
if not resHomeDir:
|
|
|
|
|
flagError = True
|
|
|
|
|
createDirHome = False
|
|
|
|
|
else:
|
|
|
|
|
term, createDirHome, removeHomeBack = resHomeDir
|
|
|
|
|
# Удаляем бекап домашней директории на сервере (удаленного польз..)
|
|
|
|
|
if not flagError and removeHomeBack and\
|
|
|
|
|
os.path.exists(removeHomeBack):
|
|
|
|
|
self.removeDir(removeHomeBack)
|
|
|
|
|
self.removeEmptyDir(os.path.split(removeHomeBack)[0])
|
|
|
|
|
# Изменим время последнего измения пароля пользователя
|
|
|
|
|
if not flagError and not self.setShadowLastChange(userName):
|
|
|
|
|
flagError = True
|
|
|
|
|
# Добавим домашнюю директорию
|
|
|
|
|
if not flagError and createDirHome and options.has_key('m'):
|
|
|
|
|
if not os.path.exists(homeDir):
|
|
|
|
|
if not self.createHomeDir(userName, homeDir, skelDir):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("cannot create HOME dir"))
|
|
|
|
|
flagError = True
|
|
|
|
|
#загружаем картинку
|
|
|
|
|
if not flagError and options.has_key('i'):
|
|
|
|
|
photoFile = options['i']
|
|
|
|
|
if not self.setJpegPhotoUser(userName, photoFile):
|
|
|
|
|
self.printERROR(_("Not added jpeg photo for user") + " " +\
|
|
|
|
|
str(userName))
|
|
|
|
|
flagError = True
|
|
|
|
|
if flagError:
|
|
|
|
|
self.delUserUnixServer(userName, {}, False, False)
|
|
|
|
|
self.printERROR (_("Can not added user")+ " " + str(userName))
|
|
|
|
|
return False
|
|
|
|
|
if printSuccess:
|
|
|
|
|
if flagAdd.has_key('group'):
|
|
|
|
|
self.printSUCCESS(_("Added group in Unix service") + " ...")
|
|
|
|
|
if createDirHome and options.has_key('m'):
|
|
|
|
|
self.printSUCCESS(_("Created home dir %s")% homeDir+\
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('i'):
|
|
|
|
|
self.printSUCCESS(_("Added jpeg photo %s")% photoFile+\
|
|
|
|
|
" ...")
|
|
|
|
|
self.printSUCCESS(_("Added user in Unix service") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def setUserMail(self, userName, mail):
|
|
|
|
|
"""Устанавливает для пользователя основной почтовый адрес"""
|
|
|
|
|
searchUser = self.searchUnixUser(userName)
|
|
|
|
|
if not searchUser:
|
|
|
|
|
self.printERROR(_("User %s not found in Unix service")\
|
|
|
|
|
%str(userName))
|
|
|
|
|
return False
|
|
|
|
|
modAttrs = []
|
|
|
|
|
if searchUser[0][0][1].has_key('mail'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'mail', mail))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'mail', mail))
|
|
|
|
|
userDN = self.addDN('uid='+userName,self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(userDN, modAttrs):
|
|
|
|
|
self.printERROR(_("Can not modify mail attribute in Unix service"))
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def getUserMail(self, userName):
|
|
|
|
|
"""Выдаем основной почтовый адрес"""
|
|
|
|
|
searchUser = self.searchUnixUser(userName)
|
|
|
|
|
if not searchUser:
|
|
|
|
|
self.printERROR(_("User %s not found in Unix service")\
|
|
|
|
|
%str(userName))
|
|
|
|
|
return False
|
|
|
|
|
if searchUser[0][0][1].has_key('mail'):
|
|
|
|
|
return searchUser[0][0][1]['mail'][0]
|
|
|
|
|
else:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
def deleteUserMail(self, userName):
|
|
|
|
|
if self.getUserMail(userName):
|
|
|
|
|
modAttrs =[(ldap.MOD_DELETE, 'mail', None)]
|
|
|
|
|
userDN = self.addDN('uid='+userName,self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(userDN, modAttrs):
|
|
|
|
|
self.printERROR(_("Can not delete mail attribute in Unix \
|
|
|
|
|
service"))
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def addUsersGroupUnix(self, users, groupName):
|
|
|
|
|
"""Добавляет пользователей из списка в Unix группу"""
|
|
|
|
|
if not self.searchUnixGroupName(groupName):
|
|
|
|
|
self.printERROR(_("group name is not found in Unix service") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
flagFalse = False
|
|
|
|
|
for userName in users:
|
|
|
|
|
if not (self.searchUnixUser(userName) or\
|
|
|
|
|
self.searchPasswdUser(userName)):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("User %s is not found")%str(userName) + " ..." )
|
|
|
|
|
flagFalse = True
|
|
|
|
|
break
|
|
|
|
|
if flagFalse:
|
|
|
|
|
return False
|
|
|
|
|
foundUsersLdap = self.searchUsersInGroupUnix(users, groupName)
|
|
|
|
|
foundUsersGroup = self.searchUsersInGroupGroup(users, groupName)
|
|
|
|
|
foundUsers = []
|
|
|
|
|
if foundUsersLdap and foundUsersGroup:
|
|
|
|
|
foundUsers = self.unicList(foundUsersLdap + foundUsersGroup)
|
|
|
|
|
elif foundUsersLdap:
|
|
|
|
|
foundUsers = foundUsersLdap
|
|
|
|
|
elif foundUsersGroup:
|
|
|
|
|
foundUsers = foundUsersGroup
|
|
|
|
|
addUsers = []
|
|
|
|
|
for user in users:
|
|
|
|
|
if not(user in foundUsers):
|
|
|
|
|
addUsers.append(user)
|
|
|
|
|
modAttrs = []
|
|
|
|
|
for userName in addUsers:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'memberUid', userName))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
groupDN = self.addDN("cn="+groupName, self.relGroupsDN)
|
|
|
|
|
return self.modAttrsDN(groupDN, modAttrs)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def getMaxGidUnix(self):
|
|
|
|
|
"""Находит максимальный добавленный gid в Unix"""
|
|
|
|
|
return self.getMaxAttrDN(self.relGroupsDN, "*", "cn",
|
|
|
|
|
self.minGid, self.maxGid, "gidNumber")
|
|
|
|
|
|
|
|
|
|
def getMaxGidUnixSystem(self):
|
|
|
|
|
"""Находит максимальный добавленный gid в LDAP системной группы"""
|
|
|
|
|
return self.getMaxAttrDN(self.relGroupsDN, "*", "cn",
|
|
|
|
|
self.minSysGid, self.maxSysGid, "gidNumber")
|
|
|
|
|
|
|
|
|
|
def getMaxGid(self):
|
|
|
|
|
"""Находит максимальный gid +1"""
|
|
|
|
|
maxGidLdap = self.getMaxGidUnix()
|
|
|
|
|
maxGidGroup = self.getMaxGidGroup()
|
|
|
|
|
if maxGidLdap > maxGidGroup:
|
|
|
|
|
maxGid = maxGidLdap
|
|
|
|
|
else:
|
|
|
|
|
maxGid = maxGidGroup
|
|
|
|
|
if maxGid == 0:
|
|
|
|
|
return self.minGid
|
|
|
|
|
else:
|
|
|
|
|
return maxGid+1
|
|
|
|
|
|
|
|
|
|
def getMaxGidGroupSystem(self):
|
|
|
|
|
"""Получаем максимальный добавленный gid из /etc/group
|
|
|
|
|
|
|
|
|
|
системной группы
|
|
|
|
|
"""
|
|
|
|
|
fileGroup = "/etc/group"
|
|
|
|
|
return self.getMaxInFile(fileGroup, self.minSysGid, self.maxSysGid)
|
|
|
|
|
|
|
|
|
|
def getMaxGidGroup(self):
|
|
|
|
|
"""Получаем максимальный добавленный gid из /etc/group"""
|
|
|
|
|
fileGroup = "/etc/group"
|
|
|
|
|
return self.getMaxInFile(fileGroup, self.minGid, self.maxGid)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getMaxGidSystem(self):
|
|
|
|
|
"""Находит максимальный gid +1 системной группы"""
|
|
|
|
|
maxGidLdap = self.getMaxGidUnixSystem()
|
|
|
|
|
maxGidGroup = self.getMaxGidGroupSystem()
|
|
|
|
|
if maxGidLdap > maxGidGroup:
|
|
|
|
|
maxGid = maxGidLdap
|
|
|
|
|
else:
|
|
|
|
|
maxGid = maxGidGroup
|
|
|
|
|
if maxGid == 0:
|
|
|
|
|
return self.minSysGid
|
|
|
|
|
else:
|
|
|
|
|
return maxGid+1
|
|
|
|
|
|
|
|
|
|
def getUidMin(self):
|
|
|
|
|
"""Получаем начальный UID пользователя"""
|
|
|
|
|
fileLogin = "/etc/login.defs"
|
|
|
|
|
fileAdduser = "/etc/adduser.conf"
|
|
|
|
|
minUid = 1000
|
|
|
|
|
if os.path.exists(fileLogin):
|
|
|
|
|
FD = open(fileLogin)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if "UID_MIN" in line and not "#" in line:
|
|
|
|
|
s = re.compile("\s+")
|
|
|
|
|
minUid = int(s.split(line)[1])
|
|
|
|
|
break
|
|
|
|
|
elif os.path.exists(fileAdduser):
|
|
|
|
|
FD = open(fileLogin)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if "FIRST_UID" in line and not "#" in line:
|
|
|
|
|
minUid = int(line.split('=')[1])
|
|
|
|
|
break
|
|
|
|
|
return minUid
|
|
|
|
|
|
|
|
|
|
def getUidMax(self):
|
|
|
|
|
"""Получаем конечный UID пользователя"""
|
|
|
|
|
fileLogin = "/etc/login.defs"
|
|
|
|
|
fileAdduser = "/etc/adduser.conf"
|
|
|
|
|
maxUid = 29999
|
|
|
|
|
if os.path.exists(fileLogin):
|
|
|
|
|
FD = open(fileLogin)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if "UID_MAX" in line and not "#" in line:
|
|
|
|
|
s = re.compile("\s+")
|
|
|
|
|
maxUid = int(s.split(line)[1])
|
|
|
|
|
break
|
|
|
|
|
elif os.path.exists(fileAdduser):
|
|
|
|
|
FD = open(fileLogin)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if "LAST_UID" in line and not "#" in line:
|
|
|
|
|
maxUid = int(line.split('=')[1])
|
|
|
|
|
break
|
|
|
|
|
return maxUid
|
|
|
|
|
|
|
|
|
|
def getMaxUidPasswd(self):
|
|
|
|
|
"""Получаем максимальный добавленный id из /etc/passwd"""
|
|
|
|
|
filePasswd = "/etc/passwd"
|
|
|
|
|
return self.getMaxInFile(filePasswd, self.minUid, self.maxUid)
|
|
|
|
|
|
|
|
|
|
def getMaxUidUnix(self, relDn=False):
|
|
|
|
|
"""Находит максимальный добавленный id в сервисе Unix"""
|
|
|
|
|
if relDn:
|
|
|
|
|
return self.getMaxAttrDN(relDn, "*", "uid",
|
|
|
|
|
self.minUid, self.maxUid, "uidNumber")
|
|
|
|
|
else:
|
|
|
|
|
return self.getMaxAttrDN(self.relUsersDN, "*", "uid",
|
|
|
|
|
self.minUid, self.maxUid, "uidNumber")
|
|
|
|
|
|
|
|
|
|
def getMaxUid(self):
|
|
|
|
|
"""Находит максимальный id +1"""
|
|
|
|
|
# Ветка компьютеры
|
|
|
|
|
maxUidLdapComp = self.getMaxUidUnix(self.relComputersDN)
|
|
|
|
|
maxUidLdap = self.getMaxUidUnix()
|
|
|
|
|
maxUidPasswd = self.getMaxUidPasswd()
|
|
|
|
|
listUid = [maxUidLdapComp, maxUidLdap, maxUidPasswd]
|
|
|
|
|
maxUid = max(listUid)
|
|
|
|
|
if maxUid == 0:
|
|
|
|
|
return self.minUid
|
|
|
|
|
else:
|
|
|
|
|
return maxUid+1
|
|
|
|
|
|
|
|
|
|
def delUserUnixServer(self, userName, options, printSuccess=True,
|
|
|
|
|
backup=True):
|
|
|
|
|
"""Удаляем Unix пользователя"""
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix"):
|
|
|
|
|
return False
|
|
|
|
|
# Ищем пользователя в Samba
|
|
|
|
|
if self.servSambaObj.searchSambaUser(userName):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("User %s is found in Samba service") %\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
self.printWARNING(\
|
|
|
|
|
_("At first, need remove user from Samba service")
|
|
|
|
|
)
|
|
|
|
|
return False
|
|
|
|
|
# Ищем пользователя в Mail
|
|
|
|
|
if self.servMailObj.searchMailUserToName(userName):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("User %s is found in Mail service") %\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
self.printWARNING(\
|
|
|
|
|
_("At first, need remove user from Mail service")
|
|
|
|
|
)
|
|
|
|
|
return False
|
|
|
|
|
# Ищем пользователя в Unix
|
|
|
|
|
resLdap = self.searchUnixUser(userName)
|
|
|
|
|
if not resLdap:
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("User %s is not found in Unix service") % str(userName) +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('r'):
|
|
|
|
|
backup = False
|
|
|
|
|
homeDir = False
|
|
|
|
|
if resLdap[0][0][1].has_key('homeDirectory'):
|
|
|
|
|
#Домашняя директория пользователя
|
|
|
|
|
homeDir = resLdap[0][0][1]['homeDirectory'][0]
|
|
|
|
|
if backup and os.path.exists(homeDir) and os.listdir(homeDir):
|
|
|
|
|
# Делаем сохранение домашней директории
|
|
|
|
|
if not self.backupDelUser(userName, 'unix/home',
|
|
|
|
|
homeDir, self):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем пользователя
|
|
|
|
|
delDN = self.addDN("uid=" + userName, self.relUsersDN)
|
|
|
|
|
if not self.delDN(delDN):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем пользователя из групп
|
|
|
|
|
if not self.delUserInGroup(userName):
|
|
|
|
|
return False
|
|
|
|
|
if resLdap[0][0][1].has_key('gidNumber'):
|
|
|
|
|
gid = resLdap[0][0][1]['gidNumber'][0]
|
|
|
|
|
else:
|
|
|
|
|
resPasswd = self.searchPasswdUser(userName)
|
|
|
|
|
if resPasswd:
|
|
|
|
|
gid = resPasswd.split(":")[3]
|
|
|
|
|
#Находим основную группу пользователя
|
|
|
|
|
resGroup = False
|
|
|
|
|
if gid:
|
|
|
|
|
resGroup = self.searchUnixGid(gid)
|
|
|
|
|
if resGroup:
|
|
|
|
|
# В случае отсутствия других пользователей удаляем основную группу
|
|
|
|
|
if not resGroup[0][0][1].has_key('memberUid'):
|
|
|
|
|
groupName = resGroup[0][0][1]['cn'][0]
|
|
|
|
|
if not self.delGroupUnixServer(groupName, {}, False):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем домашнюю директорию
|
|
|
|
|
if homeDir and os.path.exists(homeDir) and self.removeDir(homeDir):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(
|
|
|
|
|
_("Home directory %s is removed")% str(homeDir) + " ...")
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("User %s is deleted")%userName + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delGroupUnixServer(self, groupName, options, printSuccess=True):
|
|
|
|
|
"""Удаляет группу пользователей Unix"""
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix"):
|
|
|
|
|
return False
|
|
|
|
|
res = self.searchUnixGroupName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group %s is not found in Unix service")%groupName +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
groupId = res[0][0][1]['gidNumber'][0]
|
|
|
|
|
if self.searchUnixUserPrimGroup(groupId):
|
|
|
|
|
self.printWARNING(_("cannot remove user's primary group") + ".")
|
|
|
|
|
return True
|
|
|
|
|
delDN = self.addDN("cn="+groupName, self.relGroupsDN)
|
|
|
|
|
res = self.delDN(delDN)
|
|
|
|
|
if res:
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS( _("Group %s is deleted")%groupName+" ...")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not delete group") + " " + groupName+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def modUserUnixServer(self,userName, options, printSuccess=True):
|
|
|
|
|
"""Модифицирует настройки пользователя Unix в LDAP"""
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix"):
|
|
|
|
|
return False
|
|
|
|
|
res = self.searchUnixUser(userName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("User %s is not found in Unix service")%str(userName)+\
|
|
|
|
|
"...")
|
|
|
|
|
return False
|
|
|
|
|
# Новые группы в которые входит пользователь
|
|
|
|
|
if options.has_key('G'):
|
|
|
|
|
userGroups = options['G'].split(',')
|
|
|
|
|
#список имен добавляемых групп
|
|
|
|
|
userGroupNames = self.searchGroupsUnix(userGroups)
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем пользователя из групп в которые он входит
|
|
|
|
|
if not self.delUserInGroup(userName):
|
|
|
|
|
return False
|
|
|
|
|
flagError = False
|
|
|
|
|
for group in userGroupNames:
|
|
|
|
|
if not self.addUsersGroupUnix([userName], group):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Replaced list of supplementary group")+\
|
|
|
|
|
" ...")
|
|
|
|
|
# Добавляем группы в которые входит пользователь
|
|
|
|
|
elif options.has_key('a'):
|
|
|
|
|
userGroups = options['a'].split(',')
|
|
|
|
|
#список имен добавляемых групп
|
|
|
|
|
userGroupNames = self.searchGroupsUnix(userGroups)
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
flagError = False
|
|
|
|
|
for group in userGroupNames:
|
|
|
|
|
if not self.addUsersGroupUnix([userName], group):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(\
|
|
|
|
|
_("Appended the user to the supplemental groups") + " ...")
|
|
|
|
|
# Изменяемые аттрибуты пользователя
|
|
|
|
|
modAttrs = []
|
|
|
|
|
# Изменяем первичную группу пользователя
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
newFirstGroup = options['g']
|
|
|
|
|
userGroupNames = self.searchGroupsUnix([newFirstGroup])
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
groupName = userGroupNames[0]
|
|
|
|
|
resLdap = self.searchUnixGroupName(groupName)
|
|
|
|
|
resGroup = self.searchGroupGroupName(groupName)
|
|
|
|
|
if not (resLdap or resGroup):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("not found gid=") + userGid)
|
|
|
|
|
return False
|
|
|
|
|
if resGroup:
|
|
|
|
|
userGid = resGroup.split(":")[2]
|
|
|
|
|
if resLdap:
|
|
|
|
|
userGid = resLdap[0][0][1]['gidNumber'][0]
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'gidNumber', userGid)]
|
|
|
|
|
visible = False
|
|
|
|
|
# пользователя видно
|
|
|
|
|
if options.has_key('V'):
|
|
|
|
|
visible = '1'
|
|
|
|
|
# пользователя не видно
|
|
|
|
|
if options.has_key('I'):
|
|
|
|
|
visible = '0'
|
|
|
|
|
if visible:
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'shadowFlag', visible)]
|
|
|
|
|
# Изменяем домашнюю директорию
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
homeDir = options['d']
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'homeDirectory', homeDir)]
|
|
|
|
|
# Включаем пользователя
|
|
|
|
|
if options.has_key('U'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "-1")]
|
|
|
|
|
# Выключаем пользователя
|
|
|
|
|
if options.has_key('L'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "1")]
|
|
|
|
|
# Изменяем коментарий к пользователю
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
comment = options['c']
|
|
|
|
|
if res[0][0][1].has_key('displayName'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'displayName', comment),
|
|
|
|
|
(ldap.MOD_REPLACE, 'cn', comment)]
|
|
|
|
|
else:
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'cn', comment)]
|
|
|
|
|
# Изменяем оболочку пользователя
|
|
|
|
|
if options.has_key('s'):
|
|
|
|
|
shell = options['s']
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'loginShell', shell))
|
|
|
|
|
# Изменяем пароль пользователя
|
|
|
|
|
userPwd = self.getUserPassword(options, "p", "P")
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
if userPwd:
|
|
|
|
|
userPwdHash = self.execProg("slappasswd -s %s -h %s"\
|
|
|
|
|
%(userPwd, self.userCrypt))
|
|
|
|
|
if res[0][0][1].has_key('userPassword'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
DN = self.addDN("uid="+userName, self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
return False
|
|
|
|
|
# Переносим домашнюю директорию пользователя
|
|
|
|
|
if options.has_key('d') and options.has_key('m'):
|
|
|
|
|
homeDirOld = res[0][0][1]['homeDirectory'][0]
|
|
|
|
|
homeDirNew = homeDir
|
|
|
|
|
textLine = self.execProg("mv %s %s" %(homeDirOld, homeDirNew))
|
|
|
|
|
if not (textLine == None):
|
|
|
|
|
self.printERROR(_("Can not move home directory") + " ...")
|
|
|
|
|
modAttrs = [(ldap.MOD_REPLACE, 'homeDirectory',
|
|
|
|
|
homeDirOld)]
|
|
|
|
|
self.modAttrsDN(DN, modAttrs)
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Moved home directory") + " ...")
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Modified comment") + " ...")
|
|
|
|
|
if options.has_key('s'):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Modified shell") + " ...")
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Modified home directory") + " ...")
|
|
|
|
|
if options.has_key('P') or options.has_key('p'):
|
|
|
|
|
# Изменим время последнего измения пароля пользователя
|
|
|
|
|
if not self.setShadowLastChange(userName):
|
|
|
|
|
return False
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(\
|
|
|
|
|
_("Modified user password of Unix service")+\
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('U'):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Unlocked user %s")% str(userName) +\
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('I'):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(\
|
|
|
|
|
_("User %s is invisible")% str(userName) + " ...")
|
|
|
|
|
if options.has_key('V'):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("User %s is visible")% str(userName)+\
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('L'):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Locked user %s")% str(userName) +\
|
|
|
|
|
" ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modUserUnixPasswd(self, userName, options, pwd=False):
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix"):
|
|
|
|
|
return False
|
|
|
|
|
"""Устанавливает пароль LDAP пользователя и меняет его опции"""
|
|
|
|
|
res = self.searchUnixUser(userName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("User %s is not found in Unix service")%str(userName) +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
# Изменяемые аттрибуты пользователя
|
|
|
|
|
modAttrs = []
|
|
|
|
|
# Удаляем пароль пользователя
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
if res[0][0][1].has_key('userPassword'):
|
|
|
|
|
modAttrs += [(ldap.MOD_DELETE, 'userPassword', None)]
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("User %s has not password for Unix service")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
# Включаем пользователя
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "-1")]
|
|
|
|
|
# Выключаем пользователя
|
|
|
|
|
elif options.has_key('l'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'shadowExpire', "1")]
|
|
|
|
|
if not options:
|
|
|
|
|
optPasswd = {"p":""}
|
|
|
|
|
if pwd:
|
|
|
|
|
userPwd = pwd
|
|
|
|
|
else:
|
|
|
|
|
userPwd = self.getUserPassword(optPasswd, "p", False)
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
userPwdHash =\
|
|
|
|
|
self.execProg("slappasswd -s %s -h %s"\
|
|
|
|
|
%(userPwd, self.userCrypt))
|
|
|
|
|
if res[0][0][1].has_key('userPassword'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
|
|
|
|
|
if modAttrs:
|
|
|
|
|
DN = self.addDN("uid="+userName, self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
self.printSUCCESS(
|
|
|
|
|
_("Deleted password of Unix service for user") +\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
if options.has_key('l'):
|
|
|
|
|
self.printSUCCESS(_("Locked user") + " " + str(userName) +\
|
|
|
|
|
" " +_("of Unix service") + " ...")
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
self.printSUCCESS(_("Unlocked user") + " " + str(userName) +\
|
|
|
|
|
" " +_("of Unix service") + " ...")
|
|
|
|
|
if not options:
|
|
|
|
|
self.printSUCCESS(_("User password of Unix service changed")+\
|
|
|
|
|
" ...")
|
|
|
|
|
# Изменим время последнего измения пароля пользователя
|
|
|
|
|
if not self.setShadowLastChange(userName):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def modGroupUnixServer(self, groupName, options):
|
|
|
|
|
# Проверим установлен ли сервис unix
|
|
|
|
|
if not self.isServiceSetup("unix"):
|
|
|
|
|
return False
|
|
|
|
|
"""Модифицирует настройки группы пользователей LDAP"""
|
|
|
|
|
if not self.searchUnixGroupName(groupName):
|
|
|
|
|
self.printERROR(_("group name not found in Unix service") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем список пользователей в группу
|
|
|
|
|
if options.has_key('a'):
|
|
|
|
|
# добавляемые пользователи в группу
|
|
|
|
|
users = options['a'].split(',')
|
|
|
|
|
res = self.addUsersGroupUnix(users, groupName)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Appended list of users to group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not append list of users to group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем список пользователей из группы
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
# удаляемые пользователи из группы
|
|
|
|
|
users = options['d'].split(',')
|
|
|
|
|
res = self.delUsersGroupUnix(users, groupName)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Deleted list users from group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not delete list users from group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
modGroupName = groupName
|
|
|
|
|
# Изменяем имя группы
|
|
|
|
|
if options.has_key('n'):
|
|
|
|
|
newGroupName = options['n']
|
|
|
|
|
if self.searchUnixGroupName(newGroupName):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("group name %s is found in Unix service")%\
|
|
|
|
|
str(newGroupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
newFirstDn = "cn=" + newGroupName
|
|
|
|
|
oldDN = self.addDN("cn=" + groupName, self.relGroupsDN)
|
|
|
|
|
res = self.modifyElemDN(oldDN, newFirstDn)
|
|
|
|
|
if res:
|
|
|
|
|
modGroupName = newGroupName
|
|
|
|
|
self.printSUCCESS(_("Group renamed") + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not rename group") + "...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs = []
|
|
|
|
|
# Изменяем коментарий к группе
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
gecos = options['c']
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'description', gecos))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
groupDN = self.addDN("cn=" + modGroupName, self.relGroupsDN)
|
|
|
|
|
res = self.modAttrsDN(groupDN, modAttrs)
|
|
|
|
|
if res:
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
self.printSUCCESS(_("Modified group comment") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
self.printSUCCESS(_("Can not modify group comment") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUserInGroup(self, userName):
|
|
|
|
|
"""Удаление из групп в которые входит пользователь"""
|
|
|
|
|
userInGroups = self.searchUnixMemberGid(userName)
|
|
|
|
|
modAttrs = [(ldap.MOD_DELETE, 'memberUid', userName)]
|
|
|
|
|
flagError = False
|
|
|
|
|
for group in userInGroups:
|
|
|
|
|
groupName = group[0][1]['cn'][0]
|
|
|
|
|
groupDN = self.addDN("cn=" + groupName, self.relGroupsDN)
|
|
|
|
|
if not self.modAttrsDN(groupDN, modAttrs):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def delUsersGroupUnix(self, users, groupName):
|
|
|
|
|
"""Удаление пользователей из списка из группы Unix"""
|
|
|
|
|
res = self.searchUnixGroupName(groupName)
|
|
|
|
|
if not res :
|
|
|
|
|
self.printERROR(_("group name is not found in Unix service") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
if not res[0][0][1].has_key("memberUid"):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Member list of group %s is empty")%str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
memberUsers = res[0][0][1]["memberUid"]
|
|
|
|
|
flagError =False
|
|
|
|
|
for user in users:
|
|
|
|
|
if not user in memberUsers:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("User %s is not found in group")%str(user)+" "+\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs = []
|
|
|
|
|
for userName in users:
|
|
|
|
|
modAttrs.append((ldap.MOD_DELETE, 'memberUid', userName))
|
|
|
|
|
groupDN = self.addDN("cn="+groupName, self.relGroupsDN)
|
|
|
|
|
return self.modAttrsDN(groupDN, modAttrs)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setupUnixServer(self, options):
|
|
|
|
|
"""Начальная настройка Unix сервиса"""
|
|
|
|
|
# Принудительная установка
|
|
|
|
|
forceOptions = False
|
|
|
|
|
# Cоздаем объект переменные
|
|
|
|
|
self.createClVars()
|
|
|
|
|
if options.has_key("f"):
|
|
|
|
|
forceOptions = True
|
|
|
|
|
# В случае если сервер установлен
|
|
|
|
|
if self.clVars.Get("sr_unix_set") == "on" and\
|
|
|
|
|
not forceOptions:
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("Unix service already configured")+ ".")
|
|
|
|
|
return True
|
|
|
|
|
if not self.clVars.Get("sr_ldap_set") == "on":
|
|
|
|
|
self.printERROR(_("LDAP service not setuped") +" ...")
|
|
|
|
|
self.printWARNING(_("Setup LDAP service"))
|
|
|
|
|
self.printWARNING(" cl-setup ldap")
|
|
|
|
|
return False
|
|
|
|
|
if not forceOptions:
|
|
|
|
|
# предупреждение при выполнении этой программы будут изменены
|
|
|
|
|
# конфигурационные файлы и база данных сервиса 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 self.dialogYesNo(messDialog):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
# делаем backup
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
bakupObj = servLdap()
|
|
|
|
|
bakupObj.backupServer()
|
|
|
|
|
# Имя устанавливаемого сервиса
|
|
|
|
|
self.clVars.Set("cl_pass_service","unix")
|
|
|
|
|
self.clVars.Write("sr_unix_set","off")
|
|
|
|
|
# Cоздаем объект профиль устанавливая директорию ldap для
|
|
|
|
|
# файлов профилей
|
|
|
|
|
if not self.applyProfilesFromService('unix'):
|
|
|
|
|
return False
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
if not self.restartLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
#Cоединение с Ldap (администратор)
|
|
|
|
|
shareLdap.getLdapObjInFile(self)
|
|
|
|
|
# Удаляем предыдущую ветку сервиса Unix
|
|
|
|
|
servicesDN = self.relDN
|
|
|
|
|
resSearch = self.searchService()
|
|
|
|
|
ret = True
|
|
|
|
|
if resSearch:
|
|
|
|
|
delDN = self.relDN
|
|
|
|
|
ret = self.deleteDN(delDN)
|
|
|
|
|
if ret:
|
|
|
|
|
self.printOK(_("Removed Unix DN from LDAP database") + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not remove Unix DN from LDAP database") + " ...")
|
|
|
|
|
if not ret:
|
|
|
|
|
return False
|
|
|
|
|
ldifFile = self.ldifFileBase
|
|
|
|
|
baseLdif = self.createLdif(ldifFile)
|
|
|
|
|
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") +" ...")
|
|
|
|
|
# Записываем данные администратора сервиса Unix
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
ldapParser.setVar("unix",
|
|
|
|
|
{"DN":self.clVars.Get("ld_unix_dn"),
|
|
|
|
|
"PASS":self.clVars.Get("ld_unix_pw")})
|
|
|
|
|
self.printOK(_("Unix service configured") +" ...")
|
|
|
|
|
self.clVars.Write("sr_unix_set","on")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def setShadowLastChange(self, userName):
|
|
|
|
|
"""Изменим последнюю дату измениня пароля на текущую"""
|
|
|
|
|
# число дней от 1970 года
|
|
|
|
|
date = int(time.time()/86400)
|
|
|
|
|
modAttrs = [(ldap.MOD_REPLACE, 'shadowLastChange', str(date))]
|
|
|
|
|
userDN = self.addDN('uid='+userName,self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(userDN, modAttrs):
|
|
|
|
|
self.printERROR(_("Can not modify shadowLastChange attribute"))
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class servMail(shareLdap):
|
|
|
|
|
"""Методы сервиса Mail"""
|
|
|
|
|
def __init__(self, unixObj=False):
|
|
|
|
|
shareLdap.__init__(self)
|
|
|
|
|
self.relGrDN = 'ou=Groups'
|
|
|
|
|
self.relUsDN = 'ou=Users'
|
|
|
|
|
self.relServDN = 'ou=Mail'
|
|
|
|
|
# DN сервиса
|
|
|
|
|
self.relDN = self.addDN(self.relServDN,self.ServicesDN)
|
|
|
|
|
# DN пользователей, относительно базового DN
|
|
|
|
|
self.relUsersDN = self.addDN(self.relUsDN, self.relDN)
|
|
|
|
|
# DN групп пользователей, относительно базового DN
|
|
|
|
|
self.relGroupsDN = self.addDN(self.relGrDN, self.relDN)
|
|
|
|
|
self.ldifFileBase =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/mail_base.ldif"
|
|
|
|
|
self.ldifFileUser =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/mail_user.ldif"
|
|
|
|
|
self.ldifFileGroup =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/mail_group.ldif"
|
|
|
|
|
# Алгоритм шифрования пароля для Mail пользователя
|
|
|
|
|
self.userCrypt = "{SSHA}"
|
|
|
|
|
# Директория хранения писем
|
|
|
|
|
if unixObj:
|
|
|
|
|
# получаем объект сервиса Unix
|
|
|
|
|
self.servUnixObj = unixObj
|
|
|
|
|
else:
|
|
|
|
|
# создаем объект сервиса Unix
|
|
|
|
|
self.servUnixObj = servUnix()
|
|
|
|
|
|
|
|
|
|
def searchGroupsMail(self, userGroups, printError=True):
|
|
|
|
|
"""Ищет список групп из списка userGroups в Mail сервисе
|
|
|
|
|
|
|
|
|
|
Список групп может состоять из названий групп или их почтовых адресов
|
|
|
|
|
Возвращает список названий групп
|
|
|
|
|
"""
|
|
|
|
|
userGroupNames = []
|
|
|
|
|
flagError = False
|
|
|
|
|
searchEmailGroup = True
|
|
|
|
|
searchNameGroup = True
|
|
|
|
|
for userGroup in userGroups:
|
|
|
|
|
if "@" in userGroup:
|
|
|
|
|
searchEmailGroup = self.searchGroupToMail(userGroup)
|
|
|
|
|
if not searchEmailGroup:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
userGroupNames.append(searchEmailGroup[0][0][1]['cn'][0])
|
|
|
|
|
else:
|
|
|
|
|
searchNameGroup = self.searchMailGroupToName(userGroup)
|
|
|
|
|
if not searchNameGroup:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
userGroupNames.append(userGroup)
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
if not searchEmailGroup:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Email address %s is not found in Mail service")%\
|
|
|
|
|
str(userGroup) + " ...")
|
|
|
|
|
elif not searchNameGroup:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group name %s is not found in Mail service")%\
|
|
|
|
|
str(userGroup) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
return userGroupNames
|
|
|
|
|
|
|
|
|
|
def delUserMailServer(self,userName,options,printSuccess=True,backup=True):
|
|
|
|
|
"""Удаляем Mail пользователя"""
|
|
|
|
|
# Проверим установлен ли сервис mail
|
|
|
|
|
if not self.isServiceSetup("mail"):
|
|
|
|
|
return False
|
|
|
|
|
# Ищем Mail пользователя
|
|
|
|
|
resSearch = self.searchMailUserToName(userName)
|
|
|
|
|
if not resSearch:
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("User %s is not found in Mail service") % str(userName) +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
#почтовая директория пользователя
|
|
|
|
|
mailDir = os.path.join(self.clVars.Get("sr_mail_path"),
|
|
|
|
|
userName)
|
|
|
|
|
if options.has_key('r'):
|
|
|
|
|
backup = False
|
|
|
|
|
# Делаем сохранение данных удаляемого пользователя
|
|
|
|
|
if backup and os.path.exists(mailDir) and os.listdir(mailDir):
|
|
|
|
|
if not self.backupDelUser(userName, 'mail/imap', mailDir):
|
|
|
|
|
return False
|
|
|
|
|
#удаляем почту из Unix сервиса
|
|
|
|
|
if not self.servUnixObj.deleteUserMail(userName):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем пользователя из групп
|
|
|
|
|
if not self.delUserInGroup(userName):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем пользователя
|
|
|
|
|
delDN = self.addDN("uid=" + userName, self.relUsersDN)
|
|
|
|
|
if not self.delDN(delDN):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем почтовую папку
|
|
|
|
|
if self.removeDir(mailDir):
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(\
|
|
|
|
|
_("Mail user directory %s is removed")% str(mailDir) +\
|
|
|
|
|
" ...")
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Mail user %s is deleted")%userName +\
|
|
|
|
|
" ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def searchMailGroupToName(self, groupName):
|
|
|
|
|
"""Находит группу сервиса Unix по её имени"""
|
|
|
|
|
resSearch = self.searchLdapDN(groupName, self.relGroupsDN, "cn")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchMailGroup(self, nameOrMali):
|
|
|
|
|
"""Находит группу сервиса Mail по имени или email"""
|
|
|
|
|
if "@" in nameOrMali:
|
|
|
|
|
resSearch = self.searchGroupToMail(nameOrMali)
|
|
|
|
|
else:
|
|
|
|
|
resSearch = self.searchMailGroupToName(nameOrMali)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchMailMember(self, nameOrMail, printError=True):
|
|
|
|
|
"""Ищет группы сервиса Unix в котрых есть данный пользователь
|
|
|
|
|
|
|
|
|
|
Поиск происходит по email или имени пользователя
|
|
|
|
|
"""
|
|
|
|
|
resSearchUser = self.searchMailUser(nameOrMail)
|
|
|
|
|
if not resSearchUser:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Mail user or email %s are not found in Mail service")%\
|
|
|
|
|
str(nameOrMail) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
userMail = resSearchUser[0][0][1]['mail'][0]
|
|
|
|
|
resSearchGroup = self.searchLdapDN(userMail, self.relGroupsDN,
|
|
|
|
|
"rfc822member")
|
|
|
|
|
return (userMail, resSearchGroup)
|
|
|
|
|
|
|
|
|
|
def delUserInGroup(self, userName):
|
|
|
|
|
"""Удаление из групп в которые входит пользователь"""
|
|
|
|
|
resSearch = self.searchMailMember(userName)
|
|
|
|
|
if not resSearch:
|
|
|
|
|
return False
|
|
|
|
|
userMail = resSearch[0]
|
|
|
|
|
userInGroups = resSearch[1]
|
|
|
|
|
modAttrs = [(ldap.MOD_DELETE, 'rfc822member', userMail)]
|
|
|
|
|
flagError = False
|
|
|
|
|
for group in userInGroups:
|
|
|
|
|
groupName = group[0][1]['cn'][0]
|
|
|
|
|
groupDN = self.addDN("cn=" + groupName, self.relGroupsDN)
|
|
|
|
|
if not self.modAttrsDN(groupDN, modAttrs):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUsersGroupMail(self, users, groupName):
|
|
|
|
|
"""Удаление пользователей из списка из группы Mail"""
|
|
|
|
|
res = self.searchMailGroupToName(groupName)
|
|
|
|
|
if not res :
|
|
|
|
|
self.printERROR(_("group name is not found in Mail service") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
if not res[0][0][1].has_key("rfc822member"):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Member list of group %s is empty")%str(groupName)+" ...")
|
|
|
|
|
return False
|
|
|
|
|
memberMailUsers = res[0][0][1]["rfc822member"]
|
|
|
|
|
flagError = False
|
|
|
|
|
memberUsers = {}
|
|
|
|
|
for mailUser in memberMailUsers:
|
|
|
|
|
userName = mailUser.split("@")[0]
|
|
|
|
|
memberUsers[userName] = mailUser
|
|
|
|
|
for user in users:
|
|
|
|
|
if not user in memberUsers.keys():
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("User %s is not found in group")%str(user)+" "+\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs = []
|
|
|
|
|
for user in users:
|
|
|
|
|
mailUser = memberUsers[user]
|
|
|
|
|
modAttrs.append((ldap.MOD_DELETE, 'rfc822member', mailUser))
|
|
|
|
|
groupDN = self.addDN("cn="+groupName, self.relGroupsDN)
|
|
|
|
|
return self.modAttrsDN(groupDN, modAttrs)
|
|
|
|
|
|
|
|
|
|
def delGroupMailServer(self, groupName, options):
|
|
|
|
|
"""Удаляет группу пользователей Mail"""
|
|
|
|
|
# Проверим установлен ли сервис mail
|
|
|
|
|
if not self.isServiceSetup("mail"):
|
|
|
|
|
return False
|
|
|
|
|
res = self.searchMailGroupToName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group %s is not found in Mail service")%groupName +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
delDN = self.addDN("cn="+groupName, self.relGroupsDN)
|
|
|
|
|
res = self.delDN(delDN)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS( _("Mail group %s is deleted")%groupName + \
|
|
|
|
|
" ...")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not delete Mail group") +\
|
|
|
|
|
" " + groupName + " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def delAlternateAddress(self, userName):
|
|
|
|
|
"""Удаление альтернативных адресов пользователя"""
|
|
|
|
|
res = self.searchMailUserToName(userName)
|
|
|
|
|
if not res:
|
|
|
|
|
return False
|
|
|
|
|
if not res[0][0][1].has_key('mailAlternateAddress'):
|
|
|
|
|
return True
|
|
|
|
|
modAttrs = [(ldap.MOD_DELETE, 'mailAlternateAddress', None)]
|
|
|
|
|
userDN = self.addDN("uid=" + userName, self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(userDN, modAttrs):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modGroupMailServer(self, groupName, options):
|
|
|
|
|
"""Модифицирует настройки группы пользователей Mail"""
|
|
|
|
|
# Проверим установлен ли сервис mail
|
|
|
|
|
if not self.isServiceSetup("mail"):
|
|
|
|
|
return False
|
|
|
|
|
searchGroup = self.searchMailGroupToName(groupName)
|
|
|
|
|
if not searchGroup:
|
|
|
|
|
self.printERROR(_("group name not found in Mail service") +" ...")
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем список пользователей в группу
|
|
|
|
|
if options.has_key('a'):
|
|
|
|
|
# добавляемые пользователи в группу
|
|
|
|
|
users = options['a'].split(',')
|
|
|
|
|
res = self.addUsersGroupMail(users, groupName)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Appended list users to group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not append list users to group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем список пользователей из группы
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
# удаляемые пользователи из группы
|
|
|
|
|
users = options['d'].split(',')
|
|
|
|
|
res = self.delUsersGroupMail(users, groupName)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Deleted list users from group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not delete list users from group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Изменяем имя группы
|
|
|
|
|
attrDelete = []
|
|
|
|
|
attrAppend = []
|
|
|
|
|
modGroupName = groupName
|
|
|
|
|
if options.has_key('n'):
|
|
|
|
|
newGroupName = options['n']
|
|
|
|
|
if self.searchMailGroupToName(newGroupName):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("group name %s is found in Mail service")%\
|
|
|
|
|
str(newGroupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# изменяем адрес и альтернативный адрес
|
|
|
|
|
altEmails = searchGroup[0][0][1]["mailAlternateAddress"]
|
|
|
|
|
for altEmail in altEmails:
|
|
|
|
|
splAltEmail = altEmail.split("@")
|
|
|
|
|
grName = splAltEmail[0]
|
|
|
|
|
if groupName == grName:
|
|
|
|
|
altEmailDomen = ""
|
|
|
|
|
if len(splAltEmail)==2:
|
|
|
|
|
altEmailDomen = splAltEmail[1]
|
|
|
|
|
newAltEmail = "%s@%s" %(newGroupName,altEmailDomen)
|
|
|
|
|
attrDelete.append(
|
|
|
|
|
(ldap.MOD_DELETE, 'mailAlternateAddress',
|
|
|
|
|
altEmail))
|
|
|
|
|
attrAppend.append(
|
|
|
|
|
(ldap.MOD_ADD, 'mailAlternateAddress',
|
|
|
|
|
newAltEmail))
|
|
|
|
|
break
|
|
|
|
|
email = searchGroup[0][0][1]["mail"][0]
|
|
|
|
|
splEmail = email.split("@")
|
|
|
|
|
emailDomen = ""
|
|
|
|
|
if len(splEmail)==2:
|
|
|
|
|
emailDomen = splEmail[1]
|
|
|
|
|
newEmail = "%s@%s" %(newGroupName,emailDomen)
|
|
|
|
|
attrAppend.append((ldap.MOD_REPLACE, 'mail', newEmail))
|
|
|
|
|
attrAppend.append((ldap.MOD_REPLACE, 'mailMessageStore',
|
|
|
|
|
newGroupName + "/"))
|
|
|
|
|
|
|
|
|
|
newFirstDn = "cn=" + newGroupName
|
|
|
|
|
oldDN = self.addDN("cn=" + groupName, self.relGroupsDN)
|
|
|
|
|
res = self.modifyElemDN(oldDN, newFirstDn)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Group renamed") + " ...")
|
|
|
|
|
modGroupName = newGroupName
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not rename group") + "...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs = attrAppend + attrDelete
|
|
|
|
|
# Изменяем коментарий к группе
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
gecos = options['c']
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'description', gecos))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
groupDN = self.addDN("cn=" + modGroupName, self.relGroupsDN)
|
|
|
|
|
res = self.modAttrsDN(groupDN, modAttrs)
|
|
|
|
|
if res:
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
self.printSUCCESS(_("Modified group comment") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
self.printSUCCESS(_("Can not modify group comment") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def modUserMailServer(self, userName, options):
|
|
|
|
|
"""Модифицирует настройки пользователя Mail в LDAP"""
|
|
|
|
|
# Проверим установлен ли сервис mail
|
|
|
|
|
if not self.isServiceSetup("mail"):
|
|
|
|
|
return False
|
|
|
|
|
res = self.searchMailUserToName(userName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("User %s is not found in Mail service")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Новые группы в которые входит пользователь
|
|
|
|
|
if options.has_key('G'):
|
|
|
|
|
userGroups = options['G'].split(',')
|
|
|
|
|
#список имен добавляемых групп
|
|
|
|
|
userGroupNames = self.searchGroupsMail(userGroups)
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем пользователя из групп в которые он входит
|
|
|
|
|
if not self.delUserInGroup(userName):
|
|
|
|
|
return False
|
|
|
|
|
flagError = False
|
|
|
|
|
for group in userGroupNames:
|
|
|
|
|
if not self.addUsersGroupMail([userName], group):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Replaced list of supplementary group") +\
|
|
|
|
|
" ...")
|
|
|
|
|
# Добавляем группы в которые входит пользователь
|
|
|
|
|
elif options.has_key('a'):
|
|
|
|
|
userGroups = options['a'].split(',')
|
|
|
|
|
#список имен добавляемых групп
|
|
|
|
|
userGroupNames = self.searchGroupsMail(userGroups)
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
flagError = False
|
|
|
|
|
for group in userGroupNames:
|
|
|
|
|
if not self.addUsersGroupMail([userName], group):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Appended list of supplementary group") +\
|
|
|
|
|
" ...")
|
|
|
|
|
# Изменяемые аттрибуты пользователя
|
|
|
|
|
modAttrs = []
|
|
|
|
|
# Включаем пользователя
|
|
|
|
|
if options.has_key('U'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "active")]
|
|
|
|
|
# Выключаем пользователя
|
|
|
|
|
elif options.has_key('L'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "passive")]
|
|
|
|
|
|
|
|
|
|
# Изменяем коментарий к пользователю
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
comment = options['c']
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'sn', comment),
|
|
|
|
|
(ldap.MOD_REPLACE, 'cn', comment)]
|
|
|
|
|
# Изменяем пароль пользователя
|
|
|
|
|
userPwd = self.getUserPassword(options, "p", "P")
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
if userPwd:
|
|
|
|
|
userPwdHash = self.execProg("slappasswd -s %s -h %s"\
|
|
|
|
|
%(userPwd, self.userCrypt))
|
|
|
|
|
if res[0][0][1].has_key('userPassword'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
# Заменяем альтернативные почтовые адреса
|
|
|
|
|
# Первичный почтовый адрес
|
|
|
|
|
primaryMail = ""
|
|
|
|
|
if options.has_key('e'):
|
|
|
|
|
# Удаляем предыдущие адреса
|
|
|
|
|
self.delAlternateAddress(userName)
|
|
|
|
|
altMails = options['e'].split(",")
|
|
|
|
|
for altMail in altMails:
|
|
|
|
|
if "@" in altMail:
|
|
|
|
|
mail = altMail
|
|
|
|
|
else:
|
|
|
|
|
mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host"))
|
|
|
|
|
if not primaryMail:
|
|
|
|
|
primaryMail = mail
|
|
|
|
|
if self.searchUserToMail(mail) or\
|
|
|
|
|
self.searchGroupToMail(mail):
|
|
|
|
|
self.printERROR(_("Alternate email address") + ": " +\
|
|
|
|
|
str(mail) + " " + _("is found in Mail service") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'mailAlternateAddress', mail))
|
|
|
|
|
# Изменяем основной почтовый адрес
|
|
|
|
|
if primaryMail:
|
|
|
|
|
if not self.servUnixObj.setUserMail(userName, primaryMail):
|
|
|
|
|
self.printERROR(_("Failed set primary email for user %s \
|
|
|
|
|
in Unix service ...") %str(primaryMail))
|
|
|
|
|
return False
|
|
|
|
|
if modAttrs:
|
|
|
|
|
DN = self.addDN("uid="+userName, self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
self.printSUCCESS(_("Modified comment") + " ...")
|
|
|
|
|
if options.has_key('L'):
|
|
|
|
|
self.printSUCCESS(_("Locked Mail user %s")%str(userName) +
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('U'):
|
|
|
|
|
self.printSUCCESS(_("Unlocked Mail user %s")%str(userName) +
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('e'):
|
|
|
|
|
self.printSUCCESS(_("Modified Mail alternate addresses") +\
|
|
|
|
|
"...")
|
|
|
|
|
if options.has_key('P') or options.has_key('p'):
|
|
|
|
|
self.printSUCCESS(_("Modified Mail user password") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def addGroupMailServer(self, groupName, options):
|
|
|
|
|
"""Добавляет группу пользователей Mail"""
|
|
|
|
|
# Проверим установлен ли сервис mail
|
|
|
|
|
if not self.isServiceSetup("mail"):
|
|
|
|
|
return False
|
|
|
|
|
#Проверяем альтернативные почтовые адреса
|
|
|
|
|
modAttrs = []
|
|
|
|
|
if options.has_key('e'):
|
|
|
|
|
altMails = options['e'].split(",")
|
|
|
|
|
for altMail in altMails:
|
|
|
|
|
if "@" in altMail:
|
|
|
|
|
mail = altMail
|
|
|
|
|
else:
|
|
|
|
|
mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host"))
|
|
|
|
|
if self.searchUserToMail(mail) or\
|
|
|
|
|
self.searchGroupToMail(mail):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Alternate email address %s is found in Mail service")%\
|
|
|
|
|
str(mail) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs.append('mailAlternateAddress: %s' %mail)
|
|
|
|
|
if self.searchMailGroupToName(groupName):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("group name %s is found in Mail service")%\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
mail = "%s@%s" %(groupName,self.clVars.Get("sr_mail_host"))
|
|
|
|
|
if self.searchUserToMail(mail) or\
|
|
|
|
|
self.searchGroupToMail(mail):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Email address %s is found in Mail service")%\
|
|
|
|
|
str(mail) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Set("ur_group",groupName)
|
|
|
|
|
# Комментарий к группе
|
|
|
|
|
groupGecos = self.servUnixObj.groupGecos
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
groupGecos = options['c']
|
|
|
|
|
self.clVars.Set("ur_group_comment",groupGecos)
|
|
|
|
|
ldifFile = self.ldifFileGroup
|
|
|
|
|
groupRawLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not groupRawLdif:
|
|
|
|
|
print self.getError()
|
|
|
|
|
return False
|
|
|
|
|
groupLdif = groupRawLdif.rstrip() + "\n" + "\n".join(modAttrs)
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
self.ldapObj.ldapAdd(groupLdif)
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Added group in Mail service") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def modUserMailPasswd(self, userName, options):
|
|
|
|
|
"""Устанавливает пароль Mail пользователя и меняет его опции"""
|
|
|
|
|
# Проверим установлен ли сервис mail
|
|
|
|
|
if not self.isServiceSetup("mail"):
|
|
|
|
|
return False
|
|
|
|
|
res = self.searchMailUserToName(userName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("User %s is not found in Mail service") % str(userName) +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
# Изменяемые аттрибуты пользователя
|
|
|
|
|
modAttrs = []
|
|
|
|
|
# Включаем пользователя
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "active")]
|
|
|
|
|
# Выключаем пользователя
|
|
|
|
|
elif options.has_key('l'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'accountStatus', "passive")]
|
|
|
|
|
if not options:
|
|
|
|
|
optPasswd = {"p":""}
|
|
|
|
|
userPwd = self.getUserPassword(optPasswd, "p", False)
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
userPwdHash =\
|
|
|
|
|
self.execProg("slappasswd -s %s -h %s"\
|
|
|
|
|
%(userPwd, self.userCrypt))
|
|
|
|
|
if res[0][0][1].has_key('userPassword'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
DN = self.addDN("uid="+userName, self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('l'):
|
|
|
|
|
self.printSUCCESS(_("Locked Mail user %s")% str(userName)+\
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
self.printSUCCESS(_("Unlocked Mail user %s")% str(userName)+\
|
|
|
|
|
" ...")
|
|
|
|
|
if not options:
|
|
|
|
|
self.printSUCCESS(_("Changed Mail user password") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def searchUsersInGroupMail(self, usersNames, groupName):
|
|
|
|
|
"""Ищет спиcок пользователей в группе, ищет в LDAP
|
|
|
|
|
|
|
|
|
|
В случае успеха выводит список найденных пользователей
|
|
|
|
|
если нет группы False
|
|
|
|
|
если ничего не найдено пустой список
|
|
|
|
|
"""
|
|
|
|
|
res = self.searchMailGroupToName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
findUsers = []
|
|
|
|
|
if res[0][0][1].has_key('rfc822member'):
|
|
|
|
|
usersInGroup = res[0][0][1]['rfc822member']
|
|
|
|
|
for userName in usersNames:
|
|
|
|
|
userMail = "%s@%s" %(userName,
|
|
|
|
|
self.clVars.Get("sr_mail_host"))
|
|
|
|
|
if userMail in usersInGroup:
|
|
|
|
|
findUsers.append(userName)
|
|
|
|
|
return findUsers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def searchMailUserToName(self, userName):
|
|
|
|
|
"""Находит пользователя сервиса Mail по имени"""
|
|
|
|
|
resSearch = self.searchLdapDN(userName, self.relUsersDN, "uid")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUserToMail(self, mail):
|
|
|
|
|
"""Находит пользователя по почтовому адресу в сервисе Mail"""
|
|
|
|
|
resSearch = self.searchLdapDN(mail, self.relUsersDN, "mail")
|
|
|
|
|
if not resSearch:
|
|
|
|
|
resSearch = self.searchLdapDN(mail, self.relUsersDN,
|
|
|
|
|
"mailAlternateAddress")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchMailUser(self, nameOrMali):
|
|
|
|
|
"""Находит пользователя сервиса Mail по имени или email"""
|
|
|
|
|
if "@" in nameOrMali:
|
|
|
|
|
resSearch = self.searchUserToMail(nameOrMali)
|
|
|
|
|
else:
|
|
|
|
|
resSearch = self.searchMailUserToName(nameOrMali)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchGroupToMail(self, mail):
|
|
|
|
|
"""Находит группу по ее почтовому адресу"""
|
|
|
|
|
resSearch = self.searchLdapDN(mail, self.relGroupsDN, "mail")
|
|
|
|
|
if not resSearch:
|
|
|
|
|
resSearch = self.searchLdapDN(mail, self.relGroupsDN,
|
|
|
|
|
"mailAlternateAddress")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def createMailDir(self, userName, uid, gid):
|
|
|
|
|
"""Создание пользовательской директории для почты"""
|
|
|
|
|
def createCNT(mailDir, uid, gid):
|
|
|
|
|
"""создание cur, new, tmp в текущей директории"""
|
|
|
|
|
appendDirs = ["cur","new","tmp"]
|
|
|
|
|
flagError = False
|
|
|
|
|
for appDir in appendDirs:
|
|
|
|
|
createDir = os.path.join(mailDir, appDir)
|
|
|
|
|
if not self.createUserDir(uid, gid, createDir, False):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
mailDir = os.path.join(self.clVars.Get("sr_mail_path"),
|
|
|
|
|
userName)
|
|
|
|
|
flagError = False
|
|
|
|
|
if not self.createUserDir(uid, gid, mailDir):
|
|
|
|
|
flagError = True
|
|
|
|
|
if not flagError and not createCNT(mailDir, uid, gid):
|
|
|
|
|
flagError = True
|
|
|
|
|
if not flagError:
|
|
|
|
|
mailDirs = [os.path.join(mailDir,".Drafts"),
|
|
|
|
|
os.path.join(mailDir,".Sent"),
|
|
|
|
|
os.path.join(mailDir,".Spam"),
|
|
|
|
|
os.path.join(mailDir,".Trash")]
|
|
|
|
|
for createDir in mailDirs:
|
|
|
|
|
if not self.createUserDir(uid, gid, createDir, False):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if not createCNT(createDir, uid, gid):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def addUsersGroupMail(self, users, groupName):
|
|
|
|
|
"""Добавляет пользователей из списка в Mail группу"""
|
|
|
|
|
# Проверим установлен ли сервис mail
|
|
|
|
|
if not self.isServiceSetup("mail"):
|
|
|
|
|
return False
|
|
|
|
|
if not self.searchMailGroupToName(groupName):
|
|
|
|
|
self.printERROR(_("Group name is not found in Mail service") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
flagFalse = False
|
|
|
|
|
for userName in users:
|
|
|
|
|
if not self.searchMailUserToName(userName):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("User %s is not found in Mail service")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
flagFalse = True
|
|
|
|
|
break
|
|
|
|
|
if flagFalse:
|
|
|
|
|
return False
|
|
|
|
|
foundUsersMail = self.searchUsersInGroupMail(users, groupName)
|
|
|
|
|
foundUsers = []
|
|
|
|
|
if foundUsersMail:
|
|
|
|
|
foundUsers = foundUsersMail
|
|
|
|
|
addUsers = []
|
|
|
|
|
for user in users:
|
|
|
|
|
if not(user in foundUsers):
|
|
|
|
|
addUsers.append(user)
|
|
|
|
|
modAttrs = []
|
|
|
|
|
for userName in addUsers:
|
|
|
|
|
userMail = "%s@%s" %(userName,self.clVars.Get("sr_mail_host"))
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'rfc822member', userMail))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
groupDN = self.addDN("cn="+groupName, self.relGroupsDN)
|
|
|
|
|
return self.modAttrsDN(groupDN, modAttrs)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUserInMailAndUnix(self, userName, flagDelUnixUser):
|
|
|
|
|
"""Удаляет пользователя без бекапа
|
|
|
|
|
|
|
|
|
|
Удаляет из Mail и если установлен флаг из Unix
|
|
|
|
|
"""
|
|
|
|
|
if not self.delUserMailServer(userName, {}, False,False):
|
|
|
|
|
return False
|
|
|
|
|
if flagDelUnixUser:
|
|
|
|
|
if not self.servUnixObj.delUserUnixServer(userName, {}, False,
|
|
|
|
|
False):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def addUserMailServer(self, userName, options):
|
|
|
|
|
"""Добавляет почтового пользователя в LDAP-сервер"""
|
|
|
|
|
# Проверим установлен ли сервис mail
|
|
|
|
|
if not self.isServiceSetup("mail"):
|
|
|
|
|
return False
|
|
|
|
|
#Проверяем альтернативные почтовые адреса
|
|
|
|
|
modAttrs = []
|
|
|
|
|
primaryMail = ""
|
|
|
|
|
if options.has_key('e'):
|
|
|
|
|
altMails = options['e'].split(",")
|
|
|
|
|
for altMail in altMails:
|
|
|
|
|
if "@" in altMail:
|
|
|
|
|
mail = altMail
|
|
|
|
|
else:
|
|
|
|
|
mail = "%s@%s" %(altMail,self.clVars.Get("sr_mail_host"))
|
|
|
|
|
if not primaryMail:
|
|
|
|
|
primaryMail = mail
|
|
|
|
|
if self.searchUserToMail(mail) or\
|
|
|
|
|
self.searchGroupToMail(mail):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Alternate email address %s is found in Mail service")%\
|
|
|
|
|
str(mail) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs.append("mailAlternateAddress: %s" %mail)
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Must be added one or more alternative addresses"))
|
|
|
|
|
self.printWARNING("cl-useradd -e gst@calculate.org guest mail")
|
|
|
|
|
return False
|
|
|
|
|
if self.searchMailUserToName(userName):
|
|
|
|
|
self.printERROR(_("User exists in Mail service"))
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
mail = "%s@%s" %(userName,self.clVars.Get("sr_mail_host"))
|
|
|
|
|
if self.searchUserToMail(mail) or\
|
|
|
|
|
self.searchGroupToMail(mail):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Email address %s is found in Mail service")%\
|
|
|
|
|
str(mail) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
resUnix = self.servUnixObj.searchUnixUser(userName)
|
|
|
|
|
resPwd = self.servUnixObj.searchPasswdUser(userName)
|
|
|
|
|
# Пароль пользователя почты
|
|
|
|
|
userPwd = self.getUserPassword(options, "p", "P")
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
flagCreateUnixUser = False
|
|
|
|
|
if not (resUnix or resPwd):
|
|
|
|
|
flagCreateUnixUser = True
|
|
|
|
|
# Добавим пользователя LDAP
|
|
|
|
|
optUnix = {}
|
|
|
|
|
# Группа пользователя
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
optUnix['g'] = options['g']
|
|
|
|
|
# Полное имя пользователя
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
optUnix['c'] = options['c']
|
|
|
|
|
if not self.servUnixObj.addUserUnixServer(userName, optUnix,
|
|
|
|
|
False):
|
|
|
|
|
self.printERROR (_("Can not added user")+ " " +\
|
|
|
|
|
str(userName) + _(" in Unix service"))
|
|
|
|
|
return False
|
|
|
|
|
resUnix = self.servUnixObj.searchUnixUser(userName)
|
|
|
|
|
self.clVars.Set("ur_name", userName)
|
|
|
|
|
#Полное имя пользователя
|
|
|
|
|
fullNameUser = self.servUnixObj.fullNameUser
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
fullNameUser = options['c']
|
|
|
|
|
else:
|
|
|
|
|
if resUnix and resUnix[0][0][1].has_key('cn'):
|
|
|
|
|
fullNameUser = resUnix[0][0][1]['cn'][0]
|
|
|
|
|
self.clVars.Set("ur_fio",fullNameUser)
|
|
|
|
|
if not userPwd:
|
|
|
|
|
userPwdHash = "crypt{xxx}"
|
|
|
|
|
else:
|
|
|
|
|
userPwdHash =\
|
|
|
|
|
self.execProg("slappasswd -s %s -h %s" %(userPwd,self.userCrypt))
|
|
|
|
|
if not userPwdHash:
|
|
|
|
|
self.printERROR(_("ERROR") + ": " +\
|
|
|
|
|
_("create crypto password"))
|
|
|
|
|
if flagCreateUnixUser:
|
|
|
|
|
self.servUnixObj.delUserUnixServer(userName, {}, False, False)
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Set("ur_hash",userPwdHash)
|
|
|
|
|
ldifFile = self.ldifFileUser
|
|
|
|
|
userRawLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not userRawLdif:
|
|
|
|
|
print self.getError()
|
|
|
|
|
if flagCreateUnixUser:
|
|
|
|
|
self.servUnixObj.delUserUnixServer(userName, {}, False, False)
|
|
|
|
|
return False
|
|
|
|
|
userLdif = userRawLdif.rstrip() + "\n" + "\n".join(modAttrs)
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
#Добавляем пользователя в LDAP
|
|
|
|
|
self.ldapObj.ldapAdd(userLdif)
|
|
|
|
|
#ldapObj.ldapAdd(userLdif1)
|
|
|
|
|
# не переделывать на else
|
|
|
|
|
flagError = False
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
flagError = True
|
|
|
|
|
if not flagError:
|
|
|
|
|
if resUnix:
|
|
|
|
|
uid = int(resUnix[0][0][1]['uidNumber'][0])
|
|
|
|
|
gid = int(resUnix[0][0][1]['gidNumber'][0])
|
|
|
|
|
elif resPwd:
|
|
|
|
|
uid = int(resPwd.split(":")[2])
|
|
|
|
|
gid = int(resPwd.split(":")[3])
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("user are not found"))
|
|
|
|
|
flagError = True
|
|
|
|
|
if not flagError:
|
|
|
|
|
# Востановим удаленного пользователя
|
|
|
|
|
# Почтовая директория пользователя
|
|
|
|
|
mailDir = os.path.join(self.clVars.Get("sr_mail_path"),
|
|
|
|
|
userName)
|
|
|
|
|
message = _("Restored deleted user %s data")% userName + "\n" +\
|
|
|
|
|
_("'yes', 'no'")
|
|
|
|
|
|
|
|
|
|
resMailDir = self.restorePathDelUser(userName, mailDir,
|
|
|
|
|
"mail/imap", message)
|
|
|
|
|
removeMailDirBack = False
|
|
|
|
|
if not resMailDir:
|
|
|
|
|
flagError = True
|
|
|
|
|
createDirMail = False
|
|
|
|
|
else:
|
|
|
|
|
term, createDirMail, removeMailDirBack = resMailDir
|
|
|
|
|
# Создаем почтовую директорию
|
|
|
|
|
if not flagError and createDirMail:
|
|
|
|
|
if not self.createMailDir(userName, uid, gid):
|
|
|
|
|
flagError = True
|
|
|
|
|
# Записываем основной почтовый адрес
|
|
|
|
|
if not flagError and primaryMail:
|
|
|
|
|
if not self.servUnixObj.setUserMail(userName, primaryMail):
|
|
|
|
|
self.printERROR(_("Failed set primary email for user %s in\
|
|
|
|
|
Unix service ...") %str(primaryMail))
|
|
|
|
|
flagError = True
|
|
|
|
|
if not flagError and removeMailDirBack\
|
|
|
|
|
and os.path.exists(removeMailDirBack):
|
|
|
|
|
self.removeDir(removeMailDirBack)
|
|
|
|
|
self.removeEmptyDir(os.path.split(removeMailDirBack)[0])
|
|
|
|
|
if flagError:
|
|
|
|
|
self.delUserInMailAndUnix(userName, flagCreateUnixUser)
|
|
|
|
|
self.printERROR(_("Can not add user") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if flagCreateUnixUser:
|
|
|
|
|
self.printSUCCESS(_("Added user in Unix service") + " ...")
|
|
|
|
|
self.printSUCCESS(_("Added user in Mail service") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def setupMailServer(self, options):
|
|
|
|
|
"""Начальная настройка Mail сервиса"""
|
|
|
|
|
# Принудительная установка
|
|
|
|
|
forceOptions = False
|
|
|
|
|
if options.has_key("f"):
|
|
|
|
|
forceOptions = True
|
|
|
|
|
# Создаем объект переменных
|
|
|
|
|
self.createClVars()
|
|
|
|
|
#self.clVars.printVars()
|
|
|
|
|
#return True
|
|
|
|
|
if self.clVars.Get("sr_unix_set") != "on":
|
|
|
|
|
self.printERROR(_("Unix service is not setuped"))
|
|
|
|
|
self.printWARNING(_("Setup Unix service"))
|
|
|
|
|
self.printWARNING(" cl-setup unix")
|
|
|
|
|
return False
|
|
|
|
|
# В случае если сервер установлен
|
|
|
|
|
if self.clVars.Get("sr_mail_set") == "on" and\
|
|
|
|
|
not forceOptions:
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("Mail server is configured")+ ".")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
if not forceOptions:
|
|
|
|
|
# предупреждение при выполнении этой программы будут изменены
|
|
|
|
|
# конфигурационные файлы сервиса Mail (программы Postfix и Dovecot)
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +
|
|
|
|
|
_("Executing of the program will change") + " " +
|
|
|
|
|
_("the configuration files of Mail service") +" ("+
|
|
|
|
|
_("programs Postfix and Dovecot") + ")." )
|
|
|
|
|
# если вы готовы продолжить работу программы нажмите Y если нет n
|
|
|
|
|
messDialog = \
|
|
|
|
|
_("If you are ready to continue executing the program") + ", "+\
|
|
|
|
|
_("input 'yes'") +", "+ _("if not 'no'")
|
|
|
|
|
if not self.dialogYesNo(messDialog):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
# делаем backup
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
bakupObj = servLdap()
|
|
|
|
|
bakupObj.backupServer()
|
|
|
|
|
# Удаляем из автозапуска демона
|
|
|
|
|
if not self.delDaemonAutostart("postfix"):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем из автозапуска демона
|
|
|
|
|
if not self.delDaemonAutostart("dovecot"):
|
|
|
|
|
return False
|
|
|
|
|
# останавливаем сервис Mail
|
|
|
|
|
if not self.stopServices(["mail"]):
|
|
|
|
|
return False
|
|
|
|
|
# Имя устанавливаемого сервиса
|
|
|
|
|
self.clVars.Set("cl_pass_service","mail")
|
|
|
|
|
self.clVars.Write("sr_mail_set","off")
|
|
|
|
|
# Почтовый ност
|
|
|
|
|
if options.has_key("host"):
|
|
|
|
|
fullHostName = options['host']
|
|
|
|
|
else:
|
|
|
|
|
fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'),
|
|
|
|
|
self.clVars.Get('os_net_domain'))
|
|
|
|
|
self.clVars.Set("sr_mail_host",fullHostName,True)
|
|
|
|
|
if not self.applyProfilesFromService('mail'):
|
|
|
|
|
return False
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
if not self.restartLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
# Подключаемся к LDAP cерверу
|
|
|
|
|
if not shareLdap.getLdapObjInFile(self):
|
|
|
|
|
return False
|
|
|
|
|
# Находим в LDAP Mail сервис
|
|
|
|
|
resSearch = self.searchService()
|
|
|
|
|
ret = True
|
|
|
|
|
if resSearch:
|
|
|
|
|
delDN = self.relDN
|
|
|
|
|
ret = self.deleteDN(delDN)
|
|
|
|
|
if ret:
|
|
|
|
|
self.printOK(_("Remove Mail DN from LDAP Database") +" ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not remove Mail DN from LDAP Database")+\
|
|
|
|
|
" ...")
|
|
|
|
|
if not ret:
|
|
|
|
|
return False
|
|
|
|
|
ldifFile = self.ldifFileBase
|
|
|
|
|
baseLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
self.ldapObj.ldapAdd(baseLdif)
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
# Записываем данные администратора сервиса Mail
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
ldapParser.setVar("mail",
|
|
|
|
|
{"DN":self.clVars.Get("ld_mail_dn"),
|
|
|
|
|
"PASS":self.clVars.Get("ld_mail_pw")})
|
|
|
|
|
self.printOK(_("Added ldif file") +" ...")
|
|
|
|
|
textLine = self.execProg("newaliases")
|
|
|
|
|
if not (textLine == None):
|
|
|
|
|
self.printERROR(_("Can not create Postfix aliases") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("/etc/init.d/postfix start")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
self.printOK(_("Starting") + " " + "Postfix" + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("Starting") + " " + "Postfix" + " ...")
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("/etc/init.d/dovecot start")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
self.printOK(_("Starting") + " " + "Dovecot" + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("Starting") + " " + "Dovecot" + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.setDaemonAutostart("postfix"):
|
|
|
|
|
return False
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.setDaemonAutostart("dovecot"):
|
|
|
|
|
return False
|
|
|
|
|
#запишем переменные для сервера
|
|
|
|
|
mailHost = self.clVars.Get("sr_mail_host")
|
|
|
|
|
self.clVars.Write("sr_mail_host",mailHost,True,"local")
|
|
|
|
|
#запишем переменные для клиента
|
|
|
|
|
self.clVars.Set("sr_mail_send_host",fullHostName)
|
|
|
|
|
clientVars = ["sr_mail_host","sr_mail_crypt", "sr_mail_port",
|
|
|
|
|
"sr_mail_type","sr_mail_send_crypt","sr_mail_send_port",
|
|
|
|
|
"sr_mail_send_host"]
|
|
|
|
|
if not self.saveVarsClient(clientVars):
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Write("sr_mail_set","on")
|
|
|
|
|
self.printOK(_("Mail service configured") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class servJabber(shareLdap):
|
|
|
|
|
"""Методы сервиса Jabber"""
|
|
|
|
|
def __init__(self, unixObj=False):
|
|
|
|
|
shareLdap.__init__(self)
|
|
|
|
|
self.relGrDN = 'ou=Groups'
|
|
|
|
|
self.relUsDN = 'ou=Users'
|
|
|
|
|
self.relServDN = 'ou=Jabber'
|
|
|
|
|
# DN сервиса
|
|
|
|
|
self.relDN = self.addDN(self.relServDN,self.ServicesDN)
|
|
|
|
|
# DN пользователей, относительно базового DN
|
|
|
|
|
self.relUsersDN = self.addDN(self.relUsDN, self.relDN)
|
|
|
|
|
# DN групп пользователей, относительно базового DN
|
|
|
|
|
self.relGroupsDN = self.addDN(self.relGrDN, self.relDN)
|
|
|
|
|
self.ldifFileBase =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/jabber_base.ldif"
|
|
|
|
|
self.ldifFileUser =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/jabber_user.ldif"
|
|
|
|
|
self.ldifFileGroup =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/jabber_group.ldif"
|
|
|
|
|
if unixObj:
|
|
|
|
|
# получаем объект сервиса Unix
|
|
|
|
|
self.servUnixObj = unixObj
|
|
|
|
|
else:
|
|
|
|
|
# создаем объект сервиса Unix
|
|
|
|
|
self.servUnixObj = servUnix()
|
|
|
|
|
|
|
|
|
|
def searchGroupToName(self, groupName):
|
|
|
|
|
"""Находит группу сервиса Jabber по её имени"""
|
|
|
|
|
resSearch = self.searchLdapDN(groupName, self.relGroupsDN, "cn")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUserToId(self, jabberId):
|
|
|
|
|
"""Находит пользователя по Jabber ID в сервисе Jabber"""
|
|
|
|
|
resSearch = self.searchLdapDN(jabberId, self.relUsersDN, "mail")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUserToName(self, name):
|
|
|
|
|
"""Находит пользователя по имени в сервисе Jabber"""
|
|
|
|
|
resSearch = self.searchLdapDN(name, self.relUsersDN, "uid")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUsersToGroup(self, descr):
|
|
|
|
|
"""Находит пользователей по description"""
|
|
|
|
|
resSearch = self.searchLdapDN(descr, self.relUsersDN,
|
|
|
|
|
"departmentNumber")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUserToNameOrId(self, nameOrId):
|
|
|
|
|
"""Находит пользователя сервиса Jabber по имени или id"""
|
|
|
|
|
resSearch = self.searchUserToName(nameOrId)
|
|
|
|
|
if resSearch:
|
|
|
|
|
return resSearch
|
|
|
|
|
resSearch = self.searchUserToId(nameOrId)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def setUserGroup(self, userName, groupName, userS=False, groupS=False):
|
|
|
|
|
"""Устанавливает Jabber группу для пользователя"""
|
|
|
|
|
if groupS:
|
|
|
|
|
groupSearch = groupS
|
|
|
|
|
else:
|
|
|
|
|
groupSearch = self.searchGroupToName(groupName)
|
|
|
|
|
if not groupSearch:
|
|
|
|
|
self.printERROR(_("Group name is not found in Jabber service") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
if userS:
|
|
|
|
|
userSearch = userS
|
|
|
|
|
else:
|
|
|
|
|
userSearch = self.searchUserToNameOrId(userName)
|
|
|
|
|
if not userSearch:
|
|
|
|
|
self.printERROR(_("User %s is not found in Jabber service")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs = []
|
|
|
|
|
descr = groupSearch[0][0][1]["cn"][0]
|
|
|
|
|
uid = userSearch[0][0][1]["uid"][0]
|
|
|
|
|
if userSearch[0][0][1].has_key('departmentNumber'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'departmentNumber', descr))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'departmentNumber', descr))
|
|
|
|
|
userDN = self.addDN("uid="+uid, self.relUsersDN)
|
|
|
|
|
return self.modAttrsDN(userDN, modAttrs)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def addUsersGroupJabber(self, users, groupName, replaceFlag=False):
|
|
|
|
|
"""Добавляет пользователей из списка в Jabber группу"""
|
|
|
|
|
groupSearch = self.searchGroupToName(groupName)
|
|
|
|
|
if not groupSearch:
|
|
|
|
|
self.printERROR(_("Group name is not found in Jabber service") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
flagFalse = False
|
|
|
|
|
for userName in users:
|
|
|
|
|
userSearch = self.searchUserToNameOrId(userName)
|
|
|
|
|
if not userSearch:
|
|
|
|
|
self.printERROR(_("User %s is not found in Jabber service")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
flagFalse = True
|
|
|
|
|
break
|
|
|
|
|
if not replaceFlag and\
|
|
|
|
|
userSearch[0][0][1].has_key('departmentNumber'):
|
|
|
|
|
self.printERROR(_("User %s is found in group")%\
|
|
|
|
|
str(userName) + " " + str(groupName) + " ...")
|
|
|
|
|
flagFalse = True
|
|
|
|
|
break
|
|
|
|
|
if flagFalse:
|
|
|
|
|
return False
|
|
|
|
|
for userName in users:
|
|
|
|
|
if not self.setUserGroup(userName, groupName):
|
|
|
|
|
flagFalse = True
|
|
|
|
|
break
|
|
|
|
|
if flagFalse:
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUsersGroupJabber(self, users, groupName):
|
|
|
|
|
"""Удаляет пользователей из списка в Jabber группе"""
|
|
|
|
|
groupSearch = self.searchGroupToName(groupName)
|
|
|
|
|
if not groupSearch:
|
|
|
|
|
self.printERROR(_("Group name is not found in Jabber service") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
flagFalse = False
|
|
|
|
|
res = True
|
|
|
|
|
for userName in users:
|
|
|
|
|
userSearch = self.searchUserToNameOrId(userName)
|
|
|
|
|
if userSearch[0][0][1].has_key('departmentNumber'):
|
|
|
|
|
if not userSearch[0][0][1]['departmentNumber'][0] == \
|
|
|
|
|
groupSearch[0][0][1]['cn'][0]:
|
|
|
|
|
self.printERROR(_("User %s is not found in group")%\
|
|
|
|
|
str(userName) + " " + str(groupName) + " ...")
|
|
|
|
|
res = False
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("User %s is not a member of any group")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
res = False
|
|
|
|
|
break
|
|
|
|
|
if not res:
|
|
|
|
|
return False
|
|
|
|
|
for userName in users:
|
|
|
|
|
userSearch = self.searchUserToNameOrId(userName)
|
|
|
|
|
uid = userSearch[0][0][1]['uid'][0]
|
|
|
|
|
modAttrs = [(ldap.MOD_DELETE, 'departmentNumber', None)]
|
|
|
|
|
userDN = self.addDN("uid="+uid, self.relUsersDN)
|
|
|
|
|
res = self.modAttrsDN(userDN, modAttrs)
|
|
|
|
|
if not res:
|
|
|
|
|
break
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def renameGroup(self, oldName, newName):
|
|
|
|
|
"""Изменяет имя группы"""
|
|
|
|
|
searchOldGroup = self.searchGroupToName(oldName)
|
|
|
|
|
if not searchOldGroup:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Old group name %s not found in Jabber service")%str(oldName)+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
searchNewGroup = self.searchGroupToName(newName)
|
|
|
|
|
if searchNewGroup:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("New group name %s found in Jabber service")%str(newName)+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
groupDN = self.addDN("cn="+oldName, self.relGroupsDN)
|
|
|
|
|
searchUsers = self.searchUsersToGroup(oldName)
|
|
|
|
|
if searchUsers:
|
|
|
|
|
flagError = False
|
|
|
|
|
for data in searchUsers:
|
|
|
|
|
uid = data[0][1]['uid'][0]
|
|
|
|
|
userDN = self.addDN("uid="+uid, self.relUsersDN)
|
|
|
|
|
modAttrs = [(ldap.MOD_REPLACE,
|
|
|
|
|
'departmentNumber',
|
|
|
|
|
newName)]
|
|
|
|
|
res = self.modAttrsDN(userDN, modAttrs)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
newFirstDn = "cn=" + newName
|
|
|
|
|
oldDN = groupDN
|
|
|
|
|
res = self.modifyElemDN(oldDN, newFirstDn)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def modUserJabberPasswd(self, userName, options):
|
|
|
|
|
"""Устанавливает пароль Jabber пользователя и меняет его опции"""
|
|
|
|
|
# Проверим установлен ли сервис jabber
|
|
|
|
|
if not self.isServiceSetup("jabber"):
|
|
|
|
|
return False
|
|
|
|
|
resSearch = self.searchUserToNameOrId(userName)
|
|
|
|
|
if not resSearch:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("User %s is not found in Jabber service") % str(userName) +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
# Изменяемые аттрибуты пользователя
|
|
|
|
|
modAttrs = []
|
|
|
|
|
# Включаем пользователя
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")]
|
|
|
|
|
# Выключаем пользователя
|
|
|
|
|
elif options.has_key('l'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")]
|
|
|
|
|
if not options:
|
|
|
|
|
optPasswd = {"p":""}
|
|
|
|
|
userPwd = self.getUserPassword(optPasswd, "p", False)
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
userPwdHash = userPwd
|
|
|
|
|
if resSearch[0][0][1].has_key('userPassword'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
uid = resSearch[0][0][1]['uid'][0]
|
|
|
|
|
DN = self.addDN("uid="+userName, self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('l'):
|
|
|
|
|
self.printSUCCESS(_("Locked Jabber user %s")% str(userName)+\
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
self.printSUCCESS(_("Unlocked Jabber user %s")%\
|
|
|
|
|
str(userName)+ " ...")
|
|
|
|
|
if not options:
|
|
|
|
|
self.printSUCCESS(_("Changed Jabber user password") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def modUserJabberServer(self, userName, options):
|
|
|
|
|
"""Модифицирует настройки пользователя Jabber в LDAP"""
|
|
|
|
|
# Проверим установлен ли сервис jabber
|
|
|
|
|
if not self.isServiceSetup("jabber"):
|
|
|
|
|
return False
|
|
|
|
|
res = self.searchUserToNameOrId(userName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("User %s is not found in Jabber service")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Изменяет группу в которую входит пользователь
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
userGroup = options['g']
|
|
|
|
|
if self.setUserGroup(userName, userGroup, res):
|
|
|
|
|
self.printSUCCESS(_("Replaced user group") + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Not replaced user group") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
#загружаем картинку
|
|
|
|
|
if options.has_key('i'):
|
|
|
|
|
photoFile = options['i']
|
|
|
|
|
if not self.setJpegPhotoUser(userName, photoFile):
|
|
|
|
|
self.printERROR(_("Not added jpeg photo for user") + " " +\
|
|
|
|
|
str(userName))
|
|
|
|
|
return False
|
|
|
|
|
# Изменяемые аттрибуты пользователя
|
|
|
|
|
modAttrs = []
|
|
|
|
|
# Включаем пользователя
|
|
|
|
|
if options.has_key('U'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'initials', "Yes")]
|
|
|
|
|
# Выключаем пользователя
|
|
|
|
|
elif options.has_key('L'):
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'initials', "No")]
|
|
|
|
|
# Изменяем коментарий к пользователю
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
comment = options['c']
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'sn', comment),
|
|
|
|
|
(ldap.MOD_REPLACE, 'cn', comment)]
|
|
|
|
|
# Изменяем пароль пользователя
|
|
|
|
|
userPwd = self.getUserPassword(options, "p", "P")
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
if userPwd:
|
|
|
|
|
userPwdHash = userPwd
|
|
|
|
|
if res[0][0][1].has_key('userPassword'):
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
else:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
uid = res[0][0][1]['uid'][0]
|
|
|
|
|
DN = self.addDN("uid="+uid, self.relUsersDN)
|
|
|
|
|
if not self.modAttrsDN(DN, modAttrs):
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
self.printSUCCESS(_("Modified comment (full name)") + " ...")
|
|
|
|
|
if options.has_key('L'):
|
|
|
|
|
self.printSUCCESS(_("Locked Jabber user %s")%str(userName) +
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('U'):
|
|
|
|
|
self.printSUCCESS(_("Unlocked Jabber user %s")%str(userName) +
|
|
|
|
|
" ...")
|
|
|
|
|
if options.has_key('P') or options.has_key('p'):
|
|
|
|
|
self.printSUCCESS(_("Modified Jabber user password") + " ...")
|
|
|
|
|
if options.has_key('i'):
|
|
|
|
|
self.printSUCCESS(_("Set image %s for Jabber user")%\
|
|
|
|
|
str(options['i']) + " " + str(userName) + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modGroupJabberServer(self, groupName, options):
|
|
|
|
|
"""Модифицирует настройки группы пользователей Jabber"""
|
|
|
|
|
# Проверим установлен ли сервис jabber
|
|
|
|
|
if not self.isServiceSetup("jabber"):
|
|
|
|
|
return False
|
|
|
|
|
searchGroup = self.searchGroupToName(groupName)
|
|
|
|
|
if not searchGroup:
|
|
|
|
|
self.printERROR(_("Group name %s is not found in Jabber service")\
|
|
|
|
|
%str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем список пользователей в группу
|
|
|
|
|
if options.has_key('a'):
|
|
|
|
|
# добавляемые пользователи в группу
|
|
|
|
|
users = options['a'].split(',')
|
|
|
|
|
res = self.addUsersGroupJabber(users, groupName)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Appended list users to group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not append list users to group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем список пользователей из группы
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
# удаляемые пользователи из группы
|
|
|
|
|
users = options['d'].split(',')
|
|
|
|
|
res = self.delUsersGroupJabber(users, groupName)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Deleted list users from group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not delete list users from group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Изменяем коментарий к группе
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
gecos = options['c']
|
|
|
|
|
modAttrs = [(ldap.MOD_REPLACE, 'description', gecos)]
|
|
|
|
|
groupDN = self.addDN("cn="+groupName, self.relGroupsDN)
|
|
|
|
|
if self.modAttrsDN(groupDN, modAttrs):
|
|
|
|
|
self.printSUCCESS(_("Modified group comment") + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not modify comment group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Изменяем имя группы
|
|
|
|
|
if options.has_key('n'):
|
|
|
|
|
newGroupName = options['n']
|
|
|
|
|
oldGroupName = searchGroup[0][0][1]["cn"][0]
|
|
|
|
|
if self.renameGroup(oldGroupName, newGroupName):
|
|
|
|
|
self.printSUCCESS(_("Group renamed") + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not rename group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUserJabberServer(self, userName, options, printSuccess=True):
|
|
|
|
|
"""Удаляем Jabber пользователя"""
|
|
|
|
|
# Проверим установлен ли сервис jabber
|
|
|
|
|
if not self.isServiceSetup("jabber"):
|
|
|
|
|
return False
|
|
|
|
|
# Ищем Jabber пользователя
|
|
|
|
|
resSearch = self.searchUserToNameOrId(userName)
|
|
|
|
|
if not resSearch:
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("User %s is not found in Jabber service") % str(userName) +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
uid = resSearch[0][0][1]['uid'][0]
|
|
|
|
|
# Удаляем пользователя
|
|
|
|
|
delDN = self.addDN("uid=" + uid, self.relUsersDN)
|
|
|
|
|
if not self.delDN(delDN):
|
|
|
|
|
self.printERROR(_("Jabber user %s is not deleted")%userName +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Jabber user %s is deleted")%userName +\
|
|
|
|
|
" ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delGroupJabberServer(self, groupName, options):
|
|
|
|
|
"""Удаляет группу пользователей Jabber"""
|
|
|
|
|
# Проверим установлен ли сервис jabber
|
|
|
|
|
if not self.isServiceSetup("jabber"):
|
|
|
|
|
return False
|
|
|
|
|
res = self.searchGroupToName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Group %s is not found in Jabber service")%groupName +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
users = []
|
|
|
|
|
flagError = False
|
|
|
|
|
searchUsers = self.searchUsersToGroup(groupName)
|
|
|
|
|
if searchUsers:
|
|
|
|
|
for data in searchUsers:
|
|
|
|
|
users.append(data[0][1]['uid'][0])
|
|
|
|
|
if not self.delUsersGroupJabber(users, groupName):
|
|
|
|
|
flagError = True
|
|
|
|
|
if not flagError:
|
|
|
|
|
delDN = self.addDN("cn="+groupName, self.relGroupsDN)
|
|
|
|
|
res = self.delDN(delDN)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printERROR(_("Can not delete Jabber group") +\
|
|
|
|
|
" " + groupName + " ...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
self.printSUCCESS( _("Jabber group %s is deleted")%groupName +\
|
|
|
|
|
" ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def addGroupJabberServer(self, groupName, options):
|
|
|
|
|
"""Добавляет группу пользователей Jabber"""
|
|
|
|
|
# Проверим установлен ли сервис jabber
|
|
|
|
|
if not self.isServiceSetup("jabber"):
|
|
|
|
|
return False
|
|
|
|
|
# Если группа существует выходим без ошибки
|
|
|
|
|
if self.searchGroupToName(groupName):
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("group name %s is found in Jabber service") %\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Set("ur_group",groupName)
|
|
|
|
|
# Комментарий к группе
|
|
|
|
|
groupGecos = self.servUnixObj.groupGecos
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
groupGecos = options['c']
|
|
|
|
|
self.clVars.Set("ur_group_comment",groupGecos)
|
|
|
|
|
ldifFile = self.ldifFileGroup
|
|
|
|
|
groupLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not groupLdif:
|
|
|
|
|
print self.getError()
|
|
|
|
|
return False
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
self.ldapObj.ldapAdd(groupLdif)
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Added group in Jabber service") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def addUserJabberServer(self, userName, options, checkSetup=True):
|
|
|
|
|
"""Добавляет jabber пользователя"""
|
|
|
|
|
# Проверим установлен ли сервис jabber
|
|
|
|
|
if checkSetup and not self.isServiceSetup("jabber"):
|
|
|
|
|
return False
|
|
|
|
|
#jabber id
|
|
|
|
|
jabberId = "%s@%s" %(userName,self.clVars.Get("sr_jabber_host"))
|
|
|
|
|
if self.searchUserToId(jabberId):
|
|
|
|
|
self.printERROR(_("User exists in Jabber service"))
|
|
|
|
|
return False
|
|
|
|
|
# Пароль пользователя Jabber
|
|
|
|
|
userPwd = self.getUserPassword(options, "p", "P")
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
if not userPwd:
|
|
|
|
|
userPwd = "crypt{xxx}"
|
|
|
|
|
self.clVars.Set("ur_hash",userPwd)
|
|
|
|
|
self.clVars.Set("ur_name", userName)
|
|
|
|
|
#Полное имя пользователя
|
|
|
|
|
fullNameUser = self.servUnixObj.fullNameUser
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
fullNameUser = options['c']
|
|
|
|
|
else:
|
|
|
|
|
if self.isServiceSetup("unix"):
|
|
|
|
|
# Cоздаем обеъкт сервиса Unix
|
|
|
|
|
servUnixObj = servUnix()
|
|
|
|
|
resUnix = servUnixObj.searchUnixUser(userName)
|
|
|
|
|
# Берем комментарий для пользователя из Unix
|
|
|
|
|
if resUnix and resUnix[0][0][1].has_key('cn'):
|
|
|
|
|
fullNameUser = resUnix[0][0][1]['cn'][0]
|
|
|
|
|
self.clVars.Set("ur_fio",fullNameUser)
|
|
|
|
|
ldifFile = self.ldifFileUser
|
|
|
|
|
userLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
#Добавляем пользователя в LDAP
|
|
|
|
|
self.ldapObj.ldapAdd(userLdif)
|
|
|
|
|
#ldapObj.ldapAdd(userLdif1)
|
|
|
|
|
# не переделывать на else
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
#загружаем картинку
|
|
|
|
|
if options.has_key('i'):
|
|
|
|
|
photoFile = options['i']
|
|
|
|
|
if not self.setJpegPhotoUser(userName, photoFile):
|
|
|
|
|
self.printERROR(_("Not added jpeg photo for user") + " " +\
|
|
|
|
|
str(userName))
|
|
|
|
|
self.delUserJabberServer(userName, options, False)
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Added user in Jabber service") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def setupJabberServer(self, options):
|
|
|
|
|
"""Начальная настройка Jabber сервиса"""
|
|
|
|
|
# Принудительная установка
|
|
|
|
|
forceOptions = False
|
|
|
|
|
if options.has_key("f"):
|
|
|
|
|
forceOptions = True
|
|
|
|
|
# Создаем объект переменных
|
|
|
|
|
self.createClVars()
|
|
|
|
|
#self.clVars.printVars()
|
|
|
|
|
#return True
|
|
|
|
|
if self.clVars.Get("sr_ldap_set") != "on":
|
|
|
|
|
self.printERROR(_("LDAP service is not setuped"))
|
|
|
|
|
self.printWARNING(_("Setup LDAP service"))
|
|
|
|
|
self.printWARNING(" cl-setup ldap")
|
|
|
|
|
return False
|
|
|
|
|
# В случае если сервер установлен
|
|
|
|
|
if self.clVars.Get("sr_jabber_set") == "on" and\
|
|
|
|
|
not forceOptions:
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("Jabber server is configured")+ ".")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
if not forceOptions:
|
|
|
|
|
# предупреждение при выполнении этой программы будут изменены
|
|
|
|
|
# конфигурационные файлы сервиса Mail (программы Postfix и Dovecot)
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +
|
|
|
|
|
_("Executing of the program will change") + " " +
|
|
|
|
|
_("the configuration files of Jabber service") +" ("+
|
|
|
|
|
_("program Ejabberd") + ")." )
|
|
|
|
|
# если вы готовы продолжить работу программы нажмите Y если нет n
|
|
|
|
|
messDialog = \
|
|
|
|
|
_("If you are ready to continue executing the program") + ", "+\
|
|
|
|
|
_("input 'yes'") +", "+ _("if not 'no'")
|
|
|
|
|
if not self.dialogYesNo(messDialog):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
# делаем backup
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
bakupObj = servLdap()
|
|
|
|
|
bakupObj.backupServer()
|
|
|
|
|
# Удаляем из автозапуска демона
|
|
|
|
|
if not self.delDaemonAutostart("ejabberd"):
|
|
|
|
|
return False
|
|
|
|
|
# останавливаем сервис Jabber
|
|
|
|
|
if not self.stopServices(["jabber"]):
|
|
|
|
|
return False
|
|
|
|
|
# Имя устанавливаемого сервиса
|
|
|
|
|
self.clVars.Set("cl_pass_service","jabber")
|
|
|
|
|
self.clVars.Write("sr_jabber_set","off")
|
|
|
|
|
if options.has_key("host"):
|
|
|
|
|
fullHostName = options['host']
|
|
|
|
|
else:
|
|
|
|
|
fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'),
|
|
|
|
|
self.clVars.Get('os_net_domain'))
|
|
|
|
|
self.clVars.Set("sr_jabber_host",fullHostName,True)
|
|
|
|
|
# Cоздаем объект профиль устанавливая директорию jabber для
|
|
|
|
|
# файлов профилей
|
|
|
|
|
if not self.applyProfilesFromService('jabber'):
|
|
|
|
|
return False
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
if not self.restartLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
# Подключаемся к LDAP cерверу
|
|
|
|
|
if not shareLdap.getLdapObjInFile(self):
|
|
|
|
|
return False
|
|
|
|
|
# Находим в LDAP Jabber сервис
|
|
|
|
|
resSearch = self.searchService()
|
|
|
|
|
ret = True
|
|
|
|
|
if resSearch:
|
|
|
|
|
delDN = self.relDN
|
|
|
|
|
ret = self.deleteDN(delDN)
|
|
|
|
|
if ret:
|
|
|
|
|
self.printOK(_("Remove Jabber DN from LDAP Database") +" ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not remove Jabber DN from LDAP Database")+\
|
|
|
|
|
" ...")
|
|
|
|
|
if not ret:
|
|
|
|
|
return False
|
|
|
|
|
ldifFile = self.ldifFileBase
|
|
|
|
|
baseLdif = self.createLdif(ldifFile)
|
|
|
|
|
if not self.ldapObj.getError():
|
|
|
|
|
self.ldapObj.ldapAdd(baseLdif)
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
# Администратор сервиса
|
|
|
|
|
adminName = "admin"
|
|
|
|
|
adminFullName = "%s@%s" %(adminName, self.clVars.Get("sr_jabber_host"))
|
|
|
|
|
print _("Enter the %s password" % adminFullName)
|
|
|
|
|
if not self.addUserJabberServer(adminName,{'p':""}, False):
|
|
|
|
|
return False
|
|
|
|
|
# Записываем данные администратора сервиса Jabber
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
ldapParser.setVar("jabber",
|
|
|
|
|
{"DN":self.clVars.Get("ld_jabber_dn"),
|
|
|
|
|
"PASS":self.clVars.Get("ld_jabber_pw")})
|
|
|
|
|
self.printOK(_("Added ldif file") +" ...")
|
|
|
|
|
# создаем сертификат если есть используем прежний
|
|
|
|
|
self.execProg("/bin/bash /etc/jabber/self-cert.sh")
|
|
|
|
|
if not os.path.exists("/etc/jabber/ssl.pem"):
|
|
|
|
|
self.printERROR(_("Can not create Jabber certificate") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("/etc/init.d/ejabberd start")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
self.printOK(_("Starting") + " " + "Ejabberd" + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("Starting") + " " + "Ejabberd" + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.setDaemonAutostart("ejabberd"):
|
|
|
|
|
return False
|
|
|
|
|
#запишем переменные для сервера
|
|
|
|
|
jabberHost = self.clVars.Get("sr_jabber_host")
|
|
|
|
|
self.clVars.Write("sr_jabber_host",jabberHost,True,"local")
|
|
|
|
|
#запишем переменные для клиента
|
|
|
|
|
clientVars = ["sr_jabber_host","sr_jabber_crypt","sr_jabber_port"]
|
|
|
|
|
if not self.saveVarsClient(clientVars):
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Write("sr_jabber_set","on")
|
|
|
|
|
self.printOK(_("Jabber service configured") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class servSamba(shareLdap):
|
|
|
|
|
"""Методы севисa Samba"""
|
|
|
|
|
def __init__(self, unixObj=False):
|
|
|
|
|
shareLdap.__init__(self)
|
|
|
|
|
self.relGrDN = 'ou=Groups'
|
|
|
|
|
self.relUsDN = 'ou=Users'
|
|
|
|
|
self.relCsDN = 'ou=Computers'
|
|
|
|
|
self.relServDN = 'ou=Samba'
|
|
|
|
|
self.relDN = self.addDN(self.relServDN,self.ServicesDN)
|
|
|
|
|
# DN пользователей, относительно базового DN
|
|
|
|
|
self.relUsersDN = self.addDN(self.relUsDN, self.relDN)
|
|
|
|
|
# DN групп пользователей, относительно базового DN
|
|
|
|
|
self.relGroupsDN = self.addDN(self.relGrDN, self.relDN)
|
|
|
|
|
# DN, компьютеров относительно базового DN
|
|
|
|
|
self.relComputersDN = self.addDN(self.relCsDN, self.relDN)
|
|
|
|
|
self.ldifFileBase =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/samba_base.ldif"
|
|
|
|
|
if unixObj:
|
|
|
|
|
# получаем объект сервиса Unix
|
|
|
|
|
self.servUnixObj = unixObj
|
|
|
|
|
else:
|
|
|
|
|
# создаем объект сервиса Unix
|
|
|
|
|
self.servUnixObj = servUnix(self)
|
|
|
|
|
|
|
|
|
|
def getLdapObjInFile(self):
|
|
|
|
|
"""Cоединение с LDAP администратором Samba сервиса"""
|
|
|
|
|
return shareLdap.getLdapObjInFile(self, "samba")
|
|
|
|
|
|
|
|
|
|
def delUserSambaServer(self,userName,options,printSuccess=True,
|
|
|
|
|
backup=True, notDeletedDirs=[]):
|
|
|
|
|
"""Удаляем Samba пользователя"""
|
|
|
|
|
# Проверим установлен ли сервис samba
|
|
|
|
|
if not self.isServiceSetup("samba"):
|
|
|
|
|
return False
|
|
|
|
|
if "$" in userName:
|
|
|
|
|
# удаляемая машина
|
|
|
|
|
delUser = userName.replace('$','') + "$"
|
|
|
|
|
if not self.searchSambaMachine(delUser):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("Samba machine %s is not found in Samba service")%\
|
|
|
|
|
str(delUser))
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# удаляемый пользователь
|
|
|
|
|
delUser = userName
|
|
|
|
|
if not self.searchSambaUser(delUser):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("Samba user %s is not found in Samba service") %\
|
|
|
|
|
str(delUser))
|
|
|
|
|
return False
|
|
|
|
|
winProfDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_samba_winprof_path"),
|
|
|
|
|
userName)
|
|
|
|
|
linProfDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_samba_linprof_path"),
|
|
|
|
|
userName)
|
|
|
|
|
userHomeDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_samba_home_path"),
|
|
|
|
|
userName)
|
|
|
|
|
userNetlogonDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_samba_winlogon_path"),
|
|
|
|
|
userName)
|
|
|
|
|
if options.has_key('r'):
|
|
|
|
|
backup = False
|
|
|
|
|
# Делаем сохранение данных удаляемого пользователя
|
|
|
|
|
if backup:
|
|
|
|
|
if os.path.exists(winProfDir) and os.listdir(winProfDir):
|
|
|
|
|
if not self.backupDelUser(userName, 'samba/winprofile',
|
|
|
|
|
winProfDir):
|
|
|
|
|
return False
|
|
|
|
|
if os.path.exists(linProfDir) and os.listdir(linProfDir):
|
|
|
|
|
if not self.backupDelUser(userName, 'samba/linprofile',
|
|
|
|
|
linProfDir):
|
|
|
|
|
return False
|
|
|
|
|
if os.path.exists(userHomeDir)and os.listdir(userHomeDir):
|
|
|
|
|
if not self.backupDelUser(userName, 'samba/home',
|
|
|
|
|
userHomeDir):
|
|
|
|
|
return False
|
|
|
|
|
if os.path.exists(userNetlogonDir) and os.listdir(userNetlogonDir):
|
|
|
|
|
if not self.backupDelUser(userName, 'samba/netlogon',
|
|
|
|
|
winProfDir):
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("smbpasswd -x %s" %(delUser), False, False)
|
|
|
|
|
flagError = False
|
|
|
|
|
if textLine:
|
|
|
|
|
if type(textLine) == types.ListType:
|
|
|
|
|
listLine = []
|
|
|
|
|
for line in textLine:
|
|
|
|
|
listLine.append(line.rstrip())
|
|
|
|
|
textLine = " ".join(listLine)
|
|
|
|
|
else:
|
|
|
|
|
flagError = True
|
|
|
|
|
if not "Deleted user %s" %(delUser) in textLine:
|
|
|
|
|
flagError = True
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printERROR(_("ERROR") + ": " +\
|
|
|
|
|
_("Can not delete Samba user") + " " + str(delUser) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# Удаляем win профиль
|
|
|
|
|
if not winProfDir in notDeletedDirs and\
|
|
|
|
|
os.path.exists(winProfDir):
|
|
|
|
|
self.removeDir(winProfDir)
|
|
|
|
|
# Удаляем lin профиль
|
|
|
|
|
if not linProfDir in notDeletedDirs and\
|
|
|
|
|
os.path.exists(linProfDir):
|
|
|
|
|
self.removeDir(linProfDir)
|
|
|
|
|
# Удаляем домашнюю директорию
|
|
|
|
|
if not userHomeDir in notDeletedDirs and\
|
|
|
|
|
os.path.exists(userHomeDir):
|
|
|
|
|
self.removeDir(userHomeDir)
|
|
|
|
|
# Удаляем netlogon
|
|
|
|
|
if not userNetlogonDir in notDeletedDirs and\
|
|
|
|
|
os.path.exists(userNetlogonDir):
|
|
|
|
|
self.removeDir(userNetlogonDir)
|
|
|
|
|
if not self.servUnixObj.modUserUnixServer(userName,{"I":""},False):
|
|
|
|
|
return False
|
|
|
|
|
if printSuccess:
|
|
|
|
|
self.printSUCCESS(_("Deleted Samba user %s") % str(delUser) +\
|
|
|
|
|
" ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@adminConnectLdap
|
|
|
|
|
def addUserSambaServer(self,userName,options,pwDialog=False,
|
|
|
|
|
checkSetup=True,pwd=False):
|
|
|
|
|
"""Добавляет LDAP пользователя в LDAP-сервер"""
|
|
|
|
|
# Проверим установлен ли сервис samba
|
|
|
|
|
if checkSetup and not self.isServiceSetup("samba"):
|
|
|
|
|
return False
|
|
|
|
|
# Добавление машины samba
|
|
|
|
|
if options.has_key('w'):
|
|
|
|
|
if self.addMachineSambaServer(userName, options):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
# id пользователя Unix
|
|
|
|
|
uidUnixUser = False
|
|
|
|
|
resSearch = self.servUnixObj.searchUnixUser(userName)
|
|
|
|
|
flagFoundPasswd = False
|
|
|
|
|
if not resSearch:
|
|
|
|
|
resSearch = self.servUnixObj.searchPasswdUser(userName)
|
|
|
|
|
if resSearch:
|
|
|
|
|
flagFoundPasswd = True
|
|
|
|
|
else:
|
|
|
|
|
uidUnixUser = resSearch[0][0][1]['uidNumber'][0]
|
|
|
|
|
## создание пользователя Unix опция f
|
|
|
|
|
#if not resSearch and not options.has_key('f'):
|
|
|
|
|
#self.printERROR(
|
|
|
|
|
#_("User %s is not found in Unix service")%\
|
|
|
|
|
#str(userName) + " ...")
|
|
|
|
|
#return False
|
|
|
|
|
if self.searchSambaUser(userName):
|
|
|
|
|
self.printERROR(_("Samba user exists"))
|
|
|
|
|
return False
|
|
|
|
|
#пароль пользователя
|
|
|
|
|
userPwd = ""
|
|
|
|
|
if pwd:
|
|
|
|
|
userPwd = pwd
|
|
|
|
|
else:
|
|
|
|
|
#диалог ввода пароля
|
|
|
|
|
if not pwDialog:
|
|
|
|
|
pwDialog = [_("New SMB password"),
|
|
|
|
|
_("Retype new SMB password")]
|
|
|
|
|
userPwd = self.getUserPassword(options, "p", "P", pwDialog)
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
flagCreateUnixUser = False
|
|
|
|
|
if not resSearch:
|
|
|
|
|
# Добавим пользователя LDAP
|
|
|
|
|
optUnix = {}
|
|
|
|
|
# id пользователя
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
optUnix['u'] = options['u']
|
|
|
|
|
# Группа пользователя
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
optUnix['g'] = options['g']
|
|
|
|
|
# Группы в которые входит пользователь
|
|
|
|
|
if options.has_key('G'):
|
|
|
|
|
optUnix['G'] = options['G']
|
|
|
|
|
# Полное имя пользователя
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
optUnix['c'] = options['c']
|
|
|
|
|
# shell
|
|
|
|
|
if options.has_key('s'):
|
|
|
|
|
optUnix['s'] = options['s']
|
|
|
|
|
# Домашняя директория
|
|
|
|
|
if options.has_key('d'):
|
|
|
|
|
optUnix['d'] = options['d']
|
|
|
|
|
# Cделаем пользователя видимым
|
|
|
|
|
if optUnix.has_key('u'):
|
|
|
|
|
try:
|
|
|
|
|
int(optUnix['u'])
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("UID is not number"))
|
|
|
|
|
return False
|
|
|
|
|
if int(optUnix['u']) >= 1000:
|
|
|
|
|
optUnix['v'] = ""
|
|
|
|
|
else:
|
|
|
|
|
optUnix['v'] = ""
|
|
|
|
|
if not self.servUnixObj.addUserUnixServer(userName, optUnix,
|
|
|
|
|
False,userPwd):
|
|
|
|
|
self.printERROR (_("Can not added user")+ " " +\
|
|
|
|
|
str(userName) + _(" in Unix service"))
|
|
|
|
|
return False
|
|
|
|
|
flagCreateUnixUser = True
|
|
|
|
|
elif not flagFoundPasswd:
|
|
|
|
|
if userPwd:
|
|
|
|
|
# Меняем пароль у пользователя Unix
|
|
|
|
|
if not self.servUnixObj.modUserUnixPasswd(userName,{},userPwd):
|
|
|
|
|
return False
|
|
|
|
|
# Делаем пользователя видимым
|
|
|
|
|
if uidUnixUser==False or int(uidUnixUser) >=1000:
|
|
|
|
|
if not self.servUnixObj.modUserUnixServer(userName,
|
|
|
|
|
{"V":""},False):
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
if userPwd:
|
|
|
|
|
textLine = self.execProg("smbpasswd -a -s %s" %(userName),
|
|
|
|
|
"%s\n%s\n" %(userPwd,userPwd))
|
|
|
|
|
else:
|
|
|
|
|
textLine = self.execProg("smbpasswd -a -n %s" %(userName))
|
|
|
|
|
if "Added" in str(textLine):
|
|
|
|
|
flagError = False
|
|
|
|
|
winProfDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_samba_winprof_path"),
|
|
|
|
|
userName)
|
|
|
|
|
linProfDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_samba_linprof_path"),
|
|
|
|
|
userName)
|
|
|
|
|
userHomeDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_samba_home_path"),
|
|
|
|
|
userName)
|
|
|
|
|
userNetlogonDir =\
|
|
|
|
|
os.path.join(self.clVars.Get("sr_samba_winlogon_path"),
|
|
|
|
|
userName)
|
|
|
|
|
message = _("Restored deleted user %s")% userName + "\n" +\
|
|
|
|
|
_("'yes', 'no'")
|
|
|
|
|
|
|
|
|
|
resWinProf = self.restorePathDelUser(userName, winProfDir,
|
|
|
|
|
"samba/winprofile", message)
|
|
|
|
|
removeProfileBack = False
|
|
|
|
|
if not resWinProf:
|
|
|
|
|
flagError = True
|
|
|
|
|
createDirWinProfile = False
|
|
|
|
|
else:
|
|
|
|
|
term, createDirWinProfile, removeProfileBack = resWinProf
|
|
|
|
|
|
|
|
|
|
removeHomeBack = False
|
|
|
|
|
if not flagError:
|
|
|
|
|
resHome = self.restorePathDelUser(userName, userHomeDir,
|
|
|
|
|
"samba/home", term)
|
|
|
|
|
if not resHome:
|
|
|
|
|
flagError = True
|
|
|
|
|
createDirLogon = False
|
|
|
|
|
else:
|
|
|
|
|
term, createDirHome, removeHomeBack = resHome
|
|
|
|
|
|
|
|
|
|
removeLogonBack = False
|
|
|
|
|
if not flagError:
|
|
|
|
|
resLogon = self.restorePathDelUser(userName, userNetlogonDir,
|
|
|
|
|
"samba/netlogon", term)
|
|
|
|
|
if not resLogon:
|
|
|
|
|
flagError = True
|
|
|
|
|
createDirHome = False
|
|
|
|
|
else:
|
|
|
|
|
term, createDirLogon, removeLogonBack = resLogon
|
|
|
|
|
|
|
|
|
|
removeLinProfileBack = False
|
|
|
|
|
if not flagError:
|
|
|
|
|
resLinProf = self.restorePathDelUser(userName, linProfDir,
|
|
|
|
|
"samba/linprofile", term)
|
|
|
|
|
if not resLinProf:
|
|
|
|
|
flagError = True
|
|
|
|
|
createDirLinProfile = False
|
|
|
|
|
else:
|
|
|
|
|
term,createDirLinProfile,removeLinProfileBack = resLinProf
|
|
|
|
|
# Cоздадим нужные директории
|
|
|
|
|
if not flagError:
|
|
|
|
|
resSearchUnix = self.servUnixObj.searchUnixUser(userName)
|
|
|
|
|
resPasswd = False
|
|
|
|
|
if resSearchUnix:
|
|
|
|
|
uid = int(resSearchUnix[0][0][1]['uidNumber'][0])
|
|
|
|
|
gid = int(resSearchUnix[0][0][1]['gidNumber'][0])
|
|
|
|
|
else:
|
|
|
|
|
resPasswd = self.servUnixObj.searchPasswdUser(userName)
|
|
|
|
|
if resPasswd:
|
|
|
|
|
uid = int(resPasswd.split(":")[2])
|
|
|
|
|
gid = int(resPasswd.split(":")[3])
|
|
|
|
|
# Не удаляемые директории
|
|
|
|
|
notDeletedDirs = []
|
|
|
|
|
if os.path.exists(createDirHome):
|
|
|
|
|
notDeletedDirs.append(createDirHome)
|
|
|
|
|
if os.path.exists(createDirLogon):
|
|
|
|
|
notDeletedDirs.append(createDirLogon)
|
|
|
|
|
if os.path.exists(createDirWinProfile):
|
|
|
|
|
notDeletedDirs.append(createDirWinProfile)
|
|
|
|
|
if os.path.exists(createDirLinProfile):
|
|
|
|
|
notDeletedDirs.append(createDirLinProfile)
|
|
|
|
|
if (resPasswd or resSearchUnix) and\
|
|
|
|
|
(options.has_key('n') or int(uid) >=1000):
|
|
|
|
|
# Cоздаем домашнюю директорию
|
|
|
|
|
if createDirHome:
|
|
|
|
|
if not self.createUserDir(uid, gid, createDirHome):
|
|
|
|
|
flagError = True
|
|
|
|
|
# Cоздаем иконку на домашеней директории
|
|
|
|
|
if not flagError:
|
|
|
|
|
fileTxt = "[Desktop Entry]\nIcon=user-home"
|
|
|
|
|
fileDirectory = os.path.join(createDirHome,
|
|
|
|
|
".directory")
|
|
|
|
|
if not self.createUserFile(fileDirectory,
|
|
|
|
|
fileTxt, uid, gid):
|
|
|
|
|
flagError = True
|
|
|
|
|
# Cоздаем директорию netlogon
|
|
|
|
|
if not flagError and createDirLogon:
|
|
|
|
|
if not self.createUserDir(uid, gid, createDirLogon):
|
|
|
|
|
flagError = True
|
|
|
|
|
# cоздадим cmd файл для монтирования ресурсов в windows
|
|
|
|
|
if not flagError:
|
|
|
|
|
netbios = self.clVars.Get("sr_samba_netbios")
|
|
|
|
|
netbios = netbios.upper()
|
|
|
|
|
fileTxt="NET USE R: /D\r\nNET USE R: \\\\%s\share"\
|
|
|
|
|
%netbios
|
|
|
|
|
fileDirectory = os.path.join(createDirLogon,
|
|
|
|
|
"start.cmd")
|
|
|
|
|
if not self.createUserFile(fileDirectory,
|
|
|
|
|
fileTxt, uid, gid):
|
|
|
|
|
flagError = True
|
|
|
|
|
# Cоздаем директорию профиля win
|
|
|
|
|
if not flagError and createDirWinProfile:
|
|
|
|
|
if not self.createUserDir(uid,gid,createDirWinProfile):
|
|
|
|
|
flagError = True
|
|
|
|
|
# Создаем директорию профиля lin
|
|
|
|
|
if not flagError and createDirLinProfile:
|
|
|
|
|
if not self.createUserDir(uid,gid,createDirLinProfile):
|
|
|
|
|
flagError = True
|
|
|
|
|
if not flagError:
|
|
|
|
|
# Удаляем директорию бекапа профиля win
|
|
|
|
|
if removeProfileBack and\
|
|
|
|
|
os.path.exists(removeProfileBack):
|
|
|
|
|
self.removeDir(removeProfileBack)
|
|
|
|
|
self.removeEmptyDir(os.path.split(removeProfileBack)[0])
|
|
|
|
|
# Удаляем директорию бекапа профиля lin
|
|
|
|
|
if removeLinProfileBack and\
|
|
|
|
|
os.path.exists(removeLinProfileBack):
|
|
|
|
|
self.removeDir(removeLinProfileBack)
|
|
|
|
|
self.removeEmptyDir(os.path.split(removeLinProfileBack)[0])
|
|
|
|
|
# Удаляем бекап домашней директории
|
|
|
|
|
if removeHomeBack and\
|
|
|
|
|
os.path.exists(removeHomeBack):
|
|
|
|
|
self.removeDir(removeHomeBack)
|
|
|
|
|
self.removeEmptyDir(os.path.split(removeHomeBack)[0])
|
|
|
|
|
# Удалим директорию logon пользователя
|
|
|
|
|
if removeLogonBack and\
|
|
|
|
|
os.path.exists(removeLogonBack):
|
|
|
|
|
self.removeDir(removeLogonBack)
|
|
|
|
|
self.removeEmptyDir(os.path.split(removeLogonBack)[0])
|
|
|
|
|
if flagError:
|
|
|
|
|
self.delUserSambaServer(userName,{},False,False,notDeletedDirs)
|
|
|
|
|
if flagCreateUnixUser:
|
|
|
|
|
self.servUnixObj.delUserUnixServer(userName, {},
|
|
|
|
|
False, False)
|
|
|
|
|
self.printERROR(_("Can not add user") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if flagCreateUnixUser:
|
|
|
|
|
self.printSUCCESS(_("Added user in Unix service") + " ...")
|
|
|
|
|
self.printSUCCESS(_("Added user in Samba service") +" ...")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
if flagCreateUnixUser:
|
|
|
|
|
self.servUnixObj.delUserUnixServer(userName, {}, False, False)
|
|
|
|
|
self.printERROR(_("Can not add user") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def searchSambaUser(self, userName):
|
|
|
|
|
"""Находит пользователя сервиса Samba"""
|
|
|
|
|
resSearch = self.searchLdapDN(userName, self.relUsersDN, "uid")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchSambaMachine(self, machineName):
|
|
|
|
|
"""Находит машину (компьютер) сервиса Samba"""
|
|
|
|
|
resSearch = self.searchLdapDN(machineName, self.relComputersDN, "uid")
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def addMachineSambaServer(self, machineName, options):
|
|
|
|
|
"""Добавляет Samba машину в LDAP-сервер"""
|
|
|
|
|
machineLogin = machineName.replace('$','') + "$"
|
|
|
|
|
res = self.searchSambaMachine(machineLogin)
|
|
|
|
|
if res:
|
|
|
|
|
if res[0][0][1].has_key('sambaSID'):
|
|
|
|
|
self.printERROR(_("machine")+" "+machineLogin+" "+\
|
|
|
|
|
"is found in Samba service")
|
|
|
|
|
return True
|
|
|
|
|
# добавляем Samba машину
|
|
|
|
|
textLine = self.execProg("smbpasswd -a -m %s" %machineLogin)
|
|
|
|
|
if "Added" in str(textLine):
|
|
|
|
|
self.printSUCCESS(_("Added machine in Samba service") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not add machine") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# добавляем LDAP машину
|
|
|
|
|
if not self.servUnixObj.addMachineLdapServer(machineLogin,
|
|
|
|
|
options):
|
|
|
|
|
return False
|
|
|
|
|
# добавляем Samba машину
|
|
|
|
|
textLine = self.execProg("smbpasswd -a -m %s" %machineLogin)
|
|
|
|
|
if "Added" in str(textLine):
|
|
|
|
|
self.printSUCCESS(_("Added machine in Samba service") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not add machine")+ " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def setupSambaServer(self, options):
|
|
|
|
|
"""Начальная настройка Samba сервиса"""
|
|
|
|
|
# Принудительная установка
|
|
|
|
|
forceOptions = False
|
|
|
|
|
# Cоздаем объект переменные
|
|
|
|
|
self.createClVars()
|
|
|
|
|
if options.has_key("f"):
|
|
|
|
|
forceOptions = True
|
|
|
|
|
if self.clVars.Get("sr_unix_set") != "on":
|
|
|
|
|
self.printERROR(_("Unix service is not setuped"))
|
|
|
|
|
self.printWARNING (_("Setup Unix service"))
|
|
|
|
|
self.printWARNING(" cl-setup unix")
|
|
|
|
|
return False
|
|
|
|
|
# В случае если сервер установлен
|
|
|
|
|
if self.clVars.Get("sr_samba_set") == "on" and\
|
|
|
|
|
not forceOptions:
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("Samba server is configured")+ ".")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
if not forceOptions:
|
|
|
|
|
# предупреждение при выполнении этой программы будут изменены
|
|
|
|
|
# конфигурационные файлы сервиса Samba
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +
|
|
|
|
|
_("Executing of the program will change") + " " +
|
|
|
|
|
_("the configuration files of Samba service") + ".")
|
|
|
|
|
# если вы готовы продолжить работу программы нажмите Y если нет n
|
|
|
|
|
messDialog = \
|
|
|
|
|
_("If you are ready to continue executing the program")+", "+\
|
|
|
|
|
_("input 'yes'") +", "+ _("if not 'no'")
|
|
|
|
|
if not self.dialogYesNo(messDialog):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
# делаем backup
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
bakupObj = servLdap()
|
|
|
|
|
bakupObj.backupServer()
|
|
|
|
|
# Удаляем из автозапуска демона
|
|
|
|
|
if not self.delDaemonAutostart("samba"):
|
|
|
|
|
return False
|
|
|
|
|
# останавливаем сервис Samba
|
|
|
|
|
if not self.stopServices(["samba"]):
|
|
|
|
|
return False
|
|
|
|
|
# Имя устанавливаемого сервиса
|
|
|
|
|
self.clVars.Set("cl_pass_service","samba")
|
|
|
|
|
self.clVars.Write("sr_samba_set","off")
|
|
|
|
|
# Задаем рабочую группу
|
|
|
|
|
if options.has_key("w"):
|
|
|
|
|
workgroup = options['w'].strip()
|
|
|
|
|
self.clVars.Set("sr_samba_domain",workgroup)
|
|
|
|
|
# Задаем netbios имя
|
|
|
|
|
if options.has_key("n"):
|
|
|
|
|
netbios = options['n'].strip()
|
|
|
|
|
self.clVars.Set("sr_samba_netbios",netbios)
|
|
|
|
|
|
|
|
|
|
# Cоздаем объект профиль устанавливая директорию samba для
|
|
|
|
|
# файлов профилей
|
|
|
|
|
if not self.applyProfilesFromService('samba'):
|
|
|
|
|
return False
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
if not self.restartLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
# Записываем данные администратора сервиса Samba
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
ldapParser.setVar("samba",
|
|
|
|
|
{"DN":self.clVars.Get("ld_samba_dn"),
|
|
|
|
|
"PASS":self.clVars.Get("ld_samba_pw")})
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
pswd = ldapParser.getVar("samba","PASS")
|
|
|
|
|
if not pswd:
|
|
|
|
|
self.printERROR(_("ERROR") + ": " +\
|
|
|
|
|
_("Samba admin password is not found"))
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("smbpasswd -w %s" %(pswd))
|
|
|
|
|
if not "stored" in textLine:
|
|
|
|
|
self.printERROR(_("ERROR") + ": " +\
|
|
|
|
|
_("Can not add Samba admin password"))
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("/etc/init.d/slapd restart")
|
|
|
|
|
if not "ok" in textLine:
|
|
|
|
|
self.printNotOK(_("LDAP restart") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
#Cоединение с Ldap (администратор)
|
|
|
|
|
shareLdap.getLdapObjInFile(self)
|
|
|
|
|
resSearch = self.searchService()
|
|
|
|
|
ret = True
|
|
|
|
|
if resSearch:
|
|
|
|
|
delDN = self.relDN
|
|
|
|
|
ret = self.deleteDN(delDN)
|
|
|
|
|
if ret:
|
|
|
|
|
self.printOK(_("Removed Samba DN from LDAP Database") +" ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(\
|
|
|
|
|
_("Can not remove Samba DN from LDAP Database") +" ...")
|
|
|
|
|
if not ret:
|
|
|
|
|
return False
|
|
|
|
|
ldifFile = self.ldifFileBase
|
|
|
|
|
baseLdif = self.createLdif(ldifFile)
|
|
|
|
|
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") +" ...")
|
|
|
|
|
textLine = self.execProg("/etc/init.d/samba start")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
self.printOK(_("Starting") + " Samba ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("Starting") + " Samba ...")
|
|
|
|
|
return False
|
|
|
|
|
cl = self.staticUsers["client"]
|
|
|
|
|
clGr = self.staticGroups["client"]
|
|
|
|
|
adm = self.staticUsers["admin"]
|
|
|
|
|
admGr = self.staticGroups["admin"]
|
|
|
|
|
# Создаем клиента
|
|
|
|
|
# Проверяем на наличие группы client
|
|
|
|
|
resGroupClient = self.servUnixObj.searchUnixGroupName(clGr.name)
|
|
|
|
|
if not resGroupClient:
|
|
|
|
|
# Создаем группу для пользователя client
|
|
|
|
|
if not self.servUnixObj.addGroupUnixServer(clGr.name,
|
|
|
|
|
{'g':clGr.gid,
|
|
|
|
|
'c':clGr.comment},
|
|
|
|
|
False):
|
|
|
|
|
self.printERROR(_("not created unix group 'client'"))
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем пользователя client для smb ресурса [remote]
|
|
|
|
|
if not self.addUserSambaServer('client',{'f':'','u':cl.uid,
|
|
|
|
|
'c':'Client unix workstation','g':clGr.name,
|
|
|
|
|
's':'/bin/false','d':'/dev/null'},False,False):
|
|
|
|
|
self.printERROR(_("not created samba user 'client'"))
|
|
|
|
|
return False
|
|
|
|
|
# Создаем админа
|
|
|
|
|
# Проверяем на наличие группы admin
|
|
|
|
|
resGroupAdmin = self.servUnixObj.searchUnixGroupName(admGr.name)
|
|
|
|
|
if not resGroupAdmin:
|
|
|
|
|
# Создаем группу для пользователя admin
|
|
|
|
|
if not self.servUnixObj.addGroupUnixServer(admGr.name,
|
|
|
|
|
{'g':admGr.gid,
|
|
|
|
|
'c':admGr.comment},
|
|
|
|
|
False):
|
|
|
|
|
self.printERROR(_("not created unix group 'admin'"))
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем пользователя admin
|
|
|
|
|
if not self.addUserSambaServer('admin',{'f':'','u':adm.uid,
|
|
|
|
|
'c':'Administrator samba service','g':admGr.name,
|
|
|
|
|
's':'/bin/false','d':'/dev/null'},False,False):
|
|
|
|
|
self.printERROR(_("not created samba user 'admin'"))
|
|
|
|
|
return False
|
|
|
|
|
# Если нет то создадим директорию /var/calculate/remote
|
|
|
|
|
remoteEnvFile = self.clVars.Get("cl_env_path")[0]
|
|
|
|
|
remotePath = os.path.split(remoteEnvFile)[0]
|
|
|
|
|
if not os.path.exists(remotePath):
|
|
|
|
|
os.makedirs(remotePath)
|
|
|
|
|
# права и владелец /var/calculate/remote
|
|
|
|
|
if os.path.exists(remotePath):
|
|
|
|
|
os.chown(remotePath,0,int(cl.gid))
|
|
|
|
|
os.chmod(remotePath,02750)
|
|
|
|
|
# изменяем владельца remote на client
|
|
|
|
|
if not os.path.exists(remoteEnvFile):
|
|
|
|
|
fd = os.open(remoteEnvFile, os.O_CREAT)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
os.chmod(remoteEnvFile, 0640)
|
|
|
|
|
if os.path.exists(remoteEnvFile):
|
|
|
|
|
os.chown(remoteEnvFile,0,int(cl.gid))
|
|
|
|
|
if not self.setDaemonAutostart("slapd"):
|
|
|
|
|
return False
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.setDaemonAutostart("samba"):
|
|
|
|
|
return False
|
|
|
|
|
# если нет share то создадим
|
|
|
|
|
sharePath = self.clVars.Get("sr_samba_share_path")
|
|
|
|
|
if not os.path.exists(sharePath):
|
|
|
|
|
os.makedirs(sharePath)
|
|
|
|
|
# Создадим иконку для share
|
|
|
|
|
fileTxt = "[Desktop Entry]\nIcon=folder-bookmarks"
|
|
|
|
|
fileDirectory = os.path.join(sharePath,".directory")
|
|
|
|
|
uid = 0
|
|
|
|
|
gid = 0
|
|
|
|
|
if not self.createUserFile(fileDirectory, fileTxt, uid, gid):
|
|
|
|
|
return False
|
|
|
|
|
#запишем переменные для сервера
|
|
|
|
|
netbios = self.clVars.Get("sr_samba_netbios")
|
|
|
|
|
self.clVars.Write("sr_mail_host",netbios,True,"local")
|
|
|
|
|
#запишем переменные для клиента
|
|
|
|
|
fullHostName = "%s.%s"%(self.clVars.Get('os_net_hostname'),
|
|
|
|
|
self.clVars.Get('os_net_domain'))
|
|
|
|
|
self.clVars.Set("sr_samba_host",fullHostName,True)
|
|
|
|
|
clientVars = ["sr_samba_host","ld_services_dn", "ld_unix_dn",
|
|
|
|
|
"ld_bind_dn","ld_bind_pw","ld_base_dn"]
|
|
|
|
|
if not self.saveVarsClient(clientVars):
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Write("sr_samba_set","on")
|
|
|
|
|
self.printOK(_("Samba service configured") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modUserSambaPasswd(self, userName, options):
|
|
|
|
|
# Проверим установлен ли сервис samba
|
|
|
|
|
if not self.isServiceSetup("samba"):
|
|
|
|
|
return False
|
|
|
|
|
if not self.searchSambaUser(userName):
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Samba user %s is not found")%str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# отключаем samba account
|
|
|
|
|
if options.has_key('l'):
|
|
|
|
|
textLine = self.execProg("smbpasswd -d %s" %(userName))
|
|
|
|
|
if "Disabled user %s" %userName in textLine:
|
|
|
|
|
self.printSUCCESS(_("Disabled Samba user %s")%str(userName)+
|
|
|
|
|
" ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not disable Samba user")+ " "+\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# включаем Samba account
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
textLine = self.execProg("smbpasswd -e %s" %(userName))
|
|
|
|
|
if "Enabled user %s" %userName in textLine:
|
|
|
|
|
self.printSUCCESS(_("Enabled Samba user %s")%str(userName) +
|
|
|
|
|
" ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not enable Samba user")+ " "+\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if not options or options.has_key('s'):
|
|
|
|
|
optPasswd = {"p":""}
|
|
|
|
|
userPwd = self.getUserPassword(optPasswd, "p", False)
|
|
|
|
|
if userPwd == False:
|
|
|
|
|
return False
|
|
|
|
|
if userPwd:
|
|
|
|
|
# Опция s пароль только для Samba
|
|
|
|
|
if not options.has_key('s'):
|
|
|
|
|
if not self.servUnixObj.modUserUnixPasswd(userName,{},
|
|
|
|
|
userPwd):
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("smbpasswd -a -s %s" %(userName),
|
|
|
|
|
"%s\n%s\n" %(userPwd,userPwd))
|
|
|
|
|
if not (textLine == None):
|
|
|
|
|
self.printERROR(_("Can not change Samba user password") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
self.printSUCCESS(
|
|
|
|
|
_("Samba password of user %s is changed")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return True
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modUserSambaServer (self, userName, options):
|
|
|
|
|
"""Модифицирует настройки пользователя Samba в LDAP"""
|
|
|
|
|
# Проверим установлен ли сервис samba
|
|
|
|
|
if not self.isServiceSetup("samba"):
|
|
|
|
|
return False
|
|
|
|
|
# Находим Samba пользователя
|
|
|
|
|
res = self.searchSambaUser(userName)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(
|
|
|
|
|
_("Samba user %s is not found in Samba service")%\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# отключаем Samba account
|
|
|
|
|
if options.has_key('L'):
|
|
|
|
|
textLine = self.execProg("smbpasswd -d %s" %(userName))
|
|
|
|
|
if "Disabled user %s" %userName in textLine:
|
|
|
|
|
self.printSUCCESS(_("Disabled Samba user %s")%str(userName) +
|
|
|
|
|
" ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not disable Samba user")+ " "+\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# включаем samba account
|
|
|
|
|
elif options.has_key('U'):
|
|
|
|
|
textLine = self.execProg("smbpasswd -e %s" %(userName))
|
|
|
|
|
if "Enabled user %s" %userName in textLine:
|
|
|
|
|
self.printSUCCESS(_("Enabled Samba user %s")%str(userName) +
|
|
|
|
|
" ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not enable Samba user")+ " "+\
|
|
|
|
|
str(userName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# модифицируем пароль
|
|
|
|
|
if options.has_key('P') or options.has_key('p'):
|
|
|
|
|
pwDialog = [_("New SMB password"),
|
|
|
|
|
_("Retype new SMB password")]
|
|
|
|
|
pwdA = getpass.getpass(pwDialog[0]+":")
|
|
|
|
|
pwdB = getpass.getpass(pwDialog[1]+":")
|
|
|
|
|
if not (pwdA == pwdB):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("password incorrect")+ ": " + _("try again"))
|
|
|
|
|
return False
|
|
|
|
|
userPwd = pwdA
|
|
|
|
|
# Опция s пароль только для Samba
|
|
|
|
|
if not options.has_key('s'):
|
|
|
|
|
if not self.servUnixObj.modUserUnixPasswd(userName,{},
|
|
|
|
|
userPwd):
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("smbpasswd -s %s" %(userName),
|
|
|
|
|
"%s\n%s\n" %(userPwd,userPwd))
|
|
|
|
|
if not (textLine == None):
|
|
|
|
|
self.printERROR(_("Can not modify Samba user password") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Modified Samba user password") + " ...")
|
|
|
|
|
# изменяем Unix группы в которые включен пользователь
|
|
|
|
|
if options.has_key("G"):
|
|
|
|
|
strGroups = options["G"]
|
|
|
|
|
optUnix = {'G':strGroups}
|
|
|
|
|
if not self.servUnixObj.modUserUnixServer(userName, optUnix):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class servLdap(shareLdap):
|
|
|
|
|
"""Методы севисa Ldap"""
|
|
|
|
|
def __init__(self):
|
|
|
|
|
shareLdap.__init__(self)
|
|
|
|
|
self.ldifFileBase =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/ldap_base.ldif"
|
|
|
|
|
# Для backup
|
|
|
|
|
# Директория куда будет сохранен архив
|
|
|
|
|
self.backupDirectory = "/var/calculate/server-backup/ldap"
|
|
|
|
|
# ldif файл базы LDAP
|
|
|
|
|
self.archLdifFile = "/tmp/LDAP_DATABASE.ldif"
|
|
|
|
|
# приватная директория Samba
|
|
|
|
|
self.sambaPrivate = "/var/lib/samba/private"
|
|
|
|
|
# директория c алиасами сервиса Mail
|
|
|
|
|
self.mailPrivate = "/etc/mail"
|
|
|
|
|
# название файла где будет храниться список архивируемых файлов
|
|
|
|
|
self.tmpListFile = "/tmp/list_CDS_files.txt"
|
|
|
|
|
# Директория для хранения профилей backup
|
|
|
|
|
self.backupDir = "backup"
|
|
|
|
|
|
|
|
|
|
def savePrivateFile(self, fileName, data):
|
|
|
|
|
"""Записать файл с правами 0600"""
|
|
|
|
|
try:
|
|
|
|
|
FD = open (fileName, "w+")
|
|
|
|
|
FD.close()
|
|
|
|
|
os.chmod(fileName,0600)
|
|
|
|
|
FD = open (fileName, "w+")
|
|
|
|
|
FD.write(data)
|
|
|
|
|
FD.close()
|
|
|
|
|
except:
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def getServiceSetupPathProfiles(self):
|
|
|
|
|
"""находим пути к профилям установленных сервисов
|
|
|
|
|
|
|
|
|
|
Выдаем два списка ([пути к профилям сервисов],[установленные сервисы])
|
|
|
|
|
"""
|
|
|
|
|
servicePaths = []
|
|
|
|
|
servInstalled = []
|
|
|
|
|
# пути к директориям профилей
|
|
|
|
|
profilePaths = self.clVars.Get("cl_profile_path")
|
|
|
|
|
for profilePath in profilePaths:
|
|
|
|
|
if self.clVars.Get("sr_ldap_set") == "on":
|
|
|
|
|
serv = "ldap"
|
|
|
|
|
servPath = os.path.join(profilePath,serv)
|
|
|
|
|
if os.path.exists(servPath):
|
|
|
|
|
servicePaths.append(servPath)
|
|
|
|
|
servInstalled.append(serv)
|
|
|
|
|
if self.clVars.Get("sr_unix_set") == "on":
|
|
|
|
|
serv = "unix"
|
|
|
|
|
servPath = os.path.join(profilePath,serv)
|
|
|
|
|
if os.path.exists(servPath):
|
|
|
|
|
servicePaths.append(servPath)
|
|
|
|
|
servInstalled.append(serv)
|
|
|
|
|
if self.clVars.Get("sr_samba_set") == "on":
|
|
|
|
|
serv = "samba"
|
|
|
|
|
servPath = os.path.join(profilePath,serv)
|
|
|
|
|
if os.path.exists(servPath):
|
|
|
|
|
servicePaths.append(servPath)
|
|
|
|
|
servInstalled.append(serv)
|
|
|
|
|
if self.clVars.Get("sr_mail_set") == "on":
|
|
|
|
|
serv = "mail"
|
|
|
|
|
servPath = os.path.join(profilePath,serv)
|
|
|
|
|
if os.path.exists(servPath):
|
|
|
|
|
servicePaths.append(servPath)
|
|
|
|
|
servInstalled.append(serv)
|
|
|
|
|
if self.clVars.Get("sr_jabber_set") == "on":
|
|
|
|
|
serv = "jabber"
|
|
|
|
|
servPath = os.path.join(profilePath,serv)
|
|
|
|
|
if os.path.exists(servPath):
|
|
|
|
|
servicePaths.append(servPath)
|
|
|
|
|
servInstalled.append(serv)
|
|
|
|
|
return (servicePaths, servInstalled)
|
|
|
|
|
|
|
|
|
|
def backupServer(self):
|
|
|
|
|
"""Сохраняет настройки установленных сервисов и базу LDAP"""
|
|
|
|
|
# создаем директорию backup-а
|
|
|
|
|
if not os.path.exists(self.backupDirectory):
|
|
|
|
|
try:
|
|
|
|
|
os.makedirs(self.backupDirectory)
|
|
|
|
|
except os.IOError:
|
|
|
|
|
self.printERROR(_("Can not create directory") + ": " +\
|
|
|
|
|
str(self.backupDirectory))
|
|
|
|
|
return False
|
|
|
|
|
# Соединяемся с LDAP
|
|
|
|
|
shareLdap.getLdapObjInFile(self)
|
|
|
|
|
# получаем ldif текст всей базы LDAP
|
|
|
|
|
ldifText = self.fullElementDNtoText("")
|
|
|
|
|
if not ldifText:
|
|
|
|
|
self.printERROR( "Unix service DN is not found or empty")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# генерируем название файла архива
|
|
|
|
|
strData = time.strftime("%Y%m%d%H%M%S",time.localtime(time.time()))
|
|
|
|
|
backupFile = "%s.tar.bz2" %strData
|
|
|
|
|
# удаляем если существуют ldif файл базы LDAP и файл список
|
|
|
|
|
if os.path.exists(self.archLdifFile):
|
|
|
|
|
os.remove(self.archLdifFile)
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
# находим пути к профилям установленных сервисов
|
|
|
|
|
servicePaths, servInstalled = self.getServiceSetupPathProfiles()
|
|
|
|
|
if not servicePaths:
|
|
|
|
|
self.printERROR("Services are not installed")
|
|
|
|
|
return False
|
|
|
|
|
# Все файлы которые нужно заархивировать
|
|
|
|
|
allArchFiles = []
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
dirObjs = fileObj.scanDirs(servicePaths)
|
|
|
|
|
i = 0
|
|
|
|
|
for dirObj in dirObjs:
|
|
|
|
|
for fileProfile in dirObj.files:
|
|
|
|
|
archFile = fileProfile.split(servicePaths[i])[1]
|
|
|
|
|
allArchFiles.append(archFile)
|
|
|
|
|
i += 1
|
|
|
|
|
scanPrivDirs = []
|
|
|
|
|
if "ldap" in servInstalled:
|
|
|
|
|
# Получаем путь к ini директории
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
#iniPath = ldapParser.pathIniFile
|
|
|
|
|
#scanPrivDirs.append(iniPath)
|
|
|
|
|
dirDelUsers = self.clVars.Get("sr_deleted_path")
|
|
|
|
|
if os.path.exists(dirDelUsers):
|
|
|
|
|
scanPrivDirs.append(dirDelUsers)
|
|
|
|
|
# Добавляем calulate.ldap
|
|
|
|
|
allArchFiles.append(ldapParser.nameIniFile)
|
|
|
|
|
# Добавляем calculate.env
|
|
|
|
|
iniFile = "/" + self.clVars.Get("cl_env_path")[2]
|
|
|
|
|
allArchFiles.append(iniFile)
|
|
|
|
|
if "samba" in servInstalled:
|
|
|
|
|
scanPrivDirs.append(self.sambaPrivate)
|
|
|
|
|
if "mail" in servInstalled:
|
|
|
|
|
scanPrivDirs.append(self.mailPrivate)
|
|
|
|
|
if scanPrivDirs:
|
|
|
|
|
dirObjs = fileObj.scanDirs(scanPrivDirs)
|
|
|
|
|
for dirObj in dirObjs:
|
|
|
|
|
for archFile in dirObj.files:
|
|
|
|
|
allArchFiles.append(archFile)
|
|
|
|
|
allArchFiles.append(self.archLdifFile)
|
|
|
|
|
allArchFiles = self.unicList(allArchFiles)
|
|
|
|
|
# Сохраняем файл список архивируемых файлов
|
|
|
|
|
if not self.savePrivateFile (self.tmpListFile,
|
|
|
|
|
"\n".join(allArchFiles)):
|
|
|
|
|
self.printERROR(_("Can not create list archive files") + ": " +\
|
|
|
|
|
str(self.tmpListFile))
|
|
|
|
|
return False
|
|
|
|
|
# Сохраняем ldif-файл базы LDAP
|
|
|
|
|
if not self.savePrivateFile(self.archLdifFile, ldifText):
|
|
|
|
|
self.printERROR(_("Can not create ldif file") + ": " +\
|
|
|
|
|
str(self.archLdifFile))
|
|
|
|
|
return False
|
|
|
|
|
bFile = os.path.join(self.backupDirectory, backupFile)
|
|
|
|
|
self.execProg("tar --files-from=%s -cjf %s"\
|
|
|
|
|
%(self.tmpListFile, bFile))
|
|
|
|
|
if os.path.exists(self.archLdifFile):
|
|
|
|
|
os.remove(self.archLdifFile)
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
if os.path.exists(bFile):
|
|
|
|
|
os.chmod(bFile,0600)
|
|
|
|
|
self.printSUCCESS(_("Created archive file") + ": " +\
|
|
|
|
|
str(bFile))
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Can not create archive file") + ": " +\
|
|
|
|
|
str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def backupLdapServer(self, options):
|
|
|
|
|
if not options or (options and options.has_key("b")):
|
|
|
|
|
return self.backupServer()
|
|
|
|
|
if options.has_key("r"):
|
|
|
|
|
return self.restoreServer()
|
|
|
|
|
|
|
|
|
|
def startDaemons(self, service, daemons):
|
|
|
|
|
"""Стартует демонов"""
|
|
|
|
|
flagError = False
|
|
|
|
|
for daemon in daemons:
|
|
|
|
|
if not self.getRunDaemons([daemon]):
|
|
|
|
|
textLine = self.execProg("/etc/init.d/%s start" %(daemon))
|
|
|
|
|
if not ("ok" in textLine):
|
|
|
|
|
self.printERROR( _("Daemon %s was not started") %daemon)
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printNotOK(_("Starting") + " " + service.capitalize() + " " +\
|
|
|
|
|
_("service"))
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
self.printOK(_("Starting") + " " + service.capitalize() + " " +\
|
|
|
|
|
_("service"))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def startAllSetupServices(self):
|
|
|
|
|
"""Запускаем все работающие установленные сервисы
|
|
|
|
|
|
|
|
|
|
а также прописываем в автозапуск
|
|
|
|
|
"""
|
|
|
|
|
# находим установленные сервисы
|
|
|
|
|
servicePaths, servInstalled = self.getServiceSetupPathProfiles()
|
|
|
|
|
if 'ldap' in servInstalled:
|
|
|
|
|
if not self.startDaemons('ldap',['slapd']):
|
|
|
|
|
return False
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.setDaemonAutostart("slapd"):
|
|
|
|
|
return False
|
|
|
|
|
flagError = False
|
|
|
|
|
for service in servInstalled:
|
|
|
|
|
if service == "unix" or service == "ldap":
|
|
|
|
|
continue
|
|
|
|
|
elif service == "mail":
|
|
|
|
|
if not self.startDaemons('mail',['postfix', 'dovecot']):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
# Устанавливаем автозапуск демонов
|
|
|
|
|
if not (self.setDaemonAutostart("postfix") and\
|
|
|
|
|
self.setDaemonAutostart("dovecot")):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
elif service == "jabber":
|
|
|
|
|
if not self.startDaemons('jabber',['ejabberd']):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.setDaemonAutostart("ejabberd"):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
if not self.startDaemons(service,[service]):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.setDaemonAutostart(service):
|
|
|
|
|
return False
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def restoreServer(self):
|
|
|
|
|
"""Восстанавливает из архива все установленные сервисы
|
|
|
|
|
|
|
|
|
|
Восстановленные сервисы будут запущены
|
|
|
|
|
"""
|
|
|
|
|
if not os.path.exists(self.backupDirectory):
|
|
|
|
|
self.printERROR(_("Path for backup is not found") + ": " +\
|
|
|
|
|
str(self.backupDirectory))
|
|
|
|
|
return False
|
|
|
|
|
# Получаем номер архивного файла
|
|
|
|
|
archFiles = os.listdir(self.backupDirectory)
|
|
|
|
|
maxFileNumber = 0
|
|
|
|
|
for archFile in archFiles:
|
|
|
|
|
numbTxt = archFile.split(".")[0]
|
|
|
|
|
try:
|
|
|
|
|
numb = int(numbTxt)
|
|
|
|
|
except:
|
|
|
|
|
continue
|
|
|
|
|
if maxFileNumber<numb:
|
|
|
|
|
maxFileNumber = numb
|
|
|
|
|
if not maxFileNumber:
|
|
|
|
|
self.printERROR(_("Backup file is not found") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
archFile = str(maxFileNumber) + ".tar.bz2"
|
|
|
|
|
# Название файла с архивом
|
|
|
|
|
bFile = os.path.join(self.backupDirectory, archFile)
|
|
|
|
|
if not os.path.exists(bFile):
|
|
|
|
|
self.printERROR(_("Backup file is not found") + ": " +\
|
|
|
|
|
str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
# Создаем объект переменных clVars
|
|
|
|
|
self.createClVars()
|
|
|
|
|
# останавливаем сервисы
|
|
|
|
|
if not self.stopServices(self.getALLServices()):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем старую базу данных
|
|
|
|
|
self.removeLdapDatabase()
|
|
|
|
|
# Накладываем профили (берем из папки backup)
|
|
|
|
|
if not self.applyProfilesFromService(self.backupDir):
|
|
|
|
|
self.printERROR(_("Can not apply profile")+ ": backup")
|
|
|
|
|
return False
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
# Соединяемся с LDAP временным пользователем
|
|
|
|
|
if not self.connectLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
# Cписок разахивированных файлов (файл ldif)
|
|
|
|
|
allArchFiles = [self.archLdifFile[1:]]
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
# Сохраняем файл - список извлекаемых файлов (файл ldif)
|
|
|
|
|
if not self.savePrivateFile (self.tmpListFile,
|
|
|
|
|
"\n".join(allArchFiles)):
|
|
|
|
|
self.printERROR(_("Can not create list extract files") + ": " +\
|
|
|
|
|
str(self.tmpListFile))
|
|
|
|
|
return False
|
|
|
|
|
# Распаковываем ldif файл
|
|
|
|
|
if not (self.execProg("tar -C / --files-from=%s -xjf %s"\
|
|
|
|
|
%(self.tmpListFile, bFile)) == None):
|
|
|
|
|
self.printERROR(_("Can not extract archive") + ": " + str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
if not os.path.exists(self.archLdifFile):
|
|
|
|
|
self.printERROR(_("Ldif file is not found") + " :" +\
|
|
|
|
|
str(self.archLdifFile))
|
|
|
|
|
return False
|
|
|
|
|
# Читаем ldif файл
|
|
|
|
|
FD = open (self.archLdifFile, "r")
|
|
|
|
|
ldif = FD.read()
|
|
|
|
|
FD.close()
|
|
|
|
|
# Добавляем в базу из ldif
|
|
|
|
|
self.ldapObj.ldapAdd(ldif)
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
|
|
|
|
|
return False
|
|
|
|
|
# Останавливаем LDAP сервер
|
|
|
|
|
if not self.stopLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем временные файлы нужные для установки сервисов
|
|
|
|
|
self.removeTmpRestoreFile()
|
|
|
|
|
# Распаковываем целиком архив
|
|
|
|
|
if not (self.execProg("tar -C / -xjf %s"\
|
|
|
|
|
%(bFile)) == None):
|
|
|
|
|
self.printERROR(_("Can not extract archive") + ": " + str(bFile))
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем временные файлы
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
if os.path.exists(self.archLdifFile):
|
|
|
|
|
os.remove(self.archLdifFile)
|
|
|
|
|
# Стартуем все сервисы и прописываем в автозагрузку
|
|
|
|
|
self.clVars.flIniFile()
|
|
|
|
|
if not self.startAllSetupServices():
|
|
|
|
|
return False
|
|
|
|
|
self.printOK(_("Restored all installed services") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
|
# Удаляем временные файлы
|
|
|
|
|
if os.path.exists(self.tmpListFile):
|
|
|
|
|
os.remove(self.tmpListFile)
|
|
|
|
|
if os.path.exists(self.archLdifFile):
|
|
|
|
|
os.remove(self.archLdifFile)
|
|
|
|
|
|
|
|
|
|
def removeTmpRestoreFile(self):
|
|
|
|
|
"""Удаляем временные файлы нужные для восстановлеиня сервисов"""
|
|
|
|
|
profilePath = self.clVars.Get("cl_profile_path")[0]
|
|
|
|
|
backupDir = os.path.join(profilePath, self.backupDir)
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
scanObjs = fileObj.scanDirs([backupDir])
|
|
|
|
|
if not scanObjs:
|
|
|
|
|
return True
|
|
|
|
|
#удаляем файлы
|
|
|
|
|
for fileRemove in scanObjs[0].files:
|
|
|
|
|
rmFile = fileRemove.split(backupDir)[1]
|
|
|
|
|
if os.path.exists(rmFile):
|
|
|
|
|
os.remove(rmFile)
|
|
|
|
|
#удаляем ссылки
|
|
|
|
|
for linkRemove in scanObjs[0].links:
|
|
|
|
|
rmLink = flinkRemove.split(backupDir)[1]
|
|
|
|
|
if os.path.exists(rmLink):
|
|
|
|
|
os.unlink(rmLink)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def removeLdapDatabase(self):
|
|
|
|
|
"""Удаляем предыдущую базу данных"""
|
|
|
|
|
self.execProg("rm -rf /var/lib/openldap-data/*")
|
|
|
|
|
self.printOK(_("Erased LDAP Database") + " ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def connectLdapServer(self):
|
|
|
|
|
"""Соединяемся с LDAP сервером
|
|
|
|
|
|
|
|
|
|
используем DN и пароль временного админстратора
|
|
|
|
|
"""
|
|
|
|
|
self.ldapObj = ldapFunction(self.clVars.Get("ld_temp_dn"),
|
|
|
|
|
self.clVars.Get("ld_temp_pw"))
|
|
|
|
|
self.conLdap = self.ldapObj.conLdap
|
|
|
|
|
if self.ldapObj.getError():
|
|
|
|
|
self.printERROR(_("Can not connected to LDAP server") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setupLdapServer(self, options):
|
|
|
|
|
"""Начальная настройка LDAP сервиса"""
|
|
|
|
|
# Принудительная установка
|
|
|
|
|
forceOptions = False
|
|
|
|
|
self.createClVars()
|
|
|
|
|
if options.has_key("f"):
|
|
|
|
|
forceOptions = True
|
|
|
|
|
|
|
|
|
|
if self.clVars.Get("sr_ldap_set") == "on" and\
|
|
|
|
|
not forceOptions:
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("LDAP server is configured")+ ".")
|
|
|
|
|
return True
|
|
|
|
|
if not forceOptions:
|
|
|
|
|
# предупреждение при выполнении этой программы будут изменены
|
|
|
|
|
# конфигурационные файлы и база данных сервиса 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 self.dialogYesNo(messDialog):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
# делаем backup
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if not self.getRunService("ldap"):
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
self.backupServer()
|
|
|
|
|
# останавливаем сервисы
|
|
|
|
|
# Удаляем из автозапуска демона
|
|
|
|
|
if not self.delDaemonAutostart("slapd"):
|
|
|
|
|
return False
|
|
|
|
|
# Останавливаем все установленные сервисы
|
|
|
|
|
if not self.stopServices(self.getALLServices()):
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем из автозагрузки все установленные сервисы
|
|
|
|
|
if not self.delServicesAutostart(self.getALLServices()):
|
|
|
|
|
return False
|
|
|
|
|
# Получим путь к ini файлу
|
|
|
|
|
iniFile = "/" + self.clVars.Get("cl_env_path")[2]
|
|
|
|
|
# Удаляем ini файл
|
|
|
|
|
if os.path.exists(iniFile):
|
|
|
|
|
os.remove(iniFile)
|
|
|
|
|
# Получим путь к ldap файлу
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
ldapFile = ldapParser.nameIniFile
|
|
|
|
|
# Удаляем ldap файл
|
|
|
|
|
if os.path.exists(ldapFile):
|
|
|
|
|
os.remove(ldapFile)
|
|
|
|
|
# Имя устанавливаемого сервиса
|
|
|
|
|
self.clVars.Set("cl_pass_service","ldap")
|
|
|
|
|
self.clVars.Write("sr_ldap_set","off")
|
|
|
|
|
# Первый проход
|
|
|
|
|
self.clVars.Set("cl_pass_step","1",True)
|
|
|
|
|
if not self.applyProfilesFromService('ldap'):
|
|
|
|
|
self.printERROR(_("Can not apply profiles") +":"+ _("first pass"))
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем старую базу данных
|
|
|
|
|
self.removeLdapDatabase()
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
if not self.runLdapServer():
|
|
|
|
|
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 not self.applyProfilesFromService('ldap'):
|
|
|
|
|
self.printERROR(_("Can not apply profiles") +":"+ _("second pass"))
|
|
|
|
|
return False
|
|
|
|
|
# Перезапускаем LDAP сервер
|
|
|
|
|
if not self.restartLdapServer():
|
|
|
|
|
return False
|
|
|
|
|
# Записываем данные администратора сервера
|
|
|
|
|
ldapParser.setVar("admin",
|
|
|
|
|
{"DN":self.clVars.Get("ld_admin_dn"),
|
|
|
|
|
"PASS":self.clVars.Get("ld_admin_pw")})
|
|
|
|
|
# Устанавливаем автозапуск демона
|
|
|
|
|
if not self.setDaemonAutostart("slapd"):
|
|
|
|
|
return False
|
|
|
|
|
# Записываем переменные для пользователя
|
|
|
|
|
clientVars = ["ur_organization", "ur_signature"]
|
|
|
|
|
if not self.saveVarsClient(clientVars):
|
|
|
|
|
return False
|
|
|
|
|
self.clVars.Write("sr_ldap_set","on")
|
|
|
|
|
self.printOK(_("LDAP service configured") +" ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
class cl_ldap(shareLdap):
|
|
|
|
|
"""Основной класс для работы с LDAP"""
|
|
|
|
|
def __init__(self, cmdName):
|
|
|
|
|
shareLdap.__init__(self)
|
|
|
|
|
|
|
|
|
|
# объект для форматированного вывода
|
|
|
|
|
imp_cl_help.__init__(self, cmdName)
|
|
|
|
|
|
|
|
|
|
servName = ""
|
|
|
|
|
if "user" in cmdName:
|
|
|
|
|
servName = _("user")
|
|
|
|
|
elif "group" in cmdName:
|
|
|
|
|
servName = _("group")
|
|
|
|
|
elif "setup" in cmdName:
|
|
|
|
|
servName = _("service")
|
|
|
|
|
|
|
|
|
|
self.chapter = [\
|
|
|
|
|
# расположение разделов на странице
|
|
|
|
|
# имя раздела, видимый или невидимый, кол. "\n" после
|
|
|
|
|
# названия раздела, кол. "\n" после раздела
|
|
|
|
|
# тип раздела
|
|
|
|
|
("Copyright",False,0,2,""),
|
|
|
|
|
(_("Usage"),True,0,1,""),
|
|
|
|
|
("Function",False,0,2,""),
|
|
|
|
|
(_("Examples"),True,1,1,""),
|
|
|
|
|
(_("Common options"),True,1,1,"options"),
|
|
|
|
|
(_("LDAP service options"),True,1,1,"options"),
|
|
|
|
|
(_("Unix service options"),True,1,1,"options"),
|
|
|
|
|
(_("Samba service options"),True,1,1,"options"),
|
|
|
|
|
(_("Mail service options"),True,1,1,"options"),
|
|
|
|
|
(_("Jabber service options"),True,1,1,"options"),
|
|
|
|
|
(_("Services"),True,1,0,"")
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
# имена используемых программ и их номера для доступа к переменным
|
|
|
|
|
# self.data
|
|
|
|
|
self.progName = { 'cl-groupadd':0,
|
|
|
|
|
'cl-groupdel':1,
|
|
|
|
|
'cl-groupmod':2,
|
|
|
|
|
'cl-useradd':3,
|
|
|
|
|
'cl-userdel':4,
|
|
|
|
|
'cl-usermod':5,
|
|
|
|
|
'cl-setup':6,
|
|
|
|
|
'cl-passwd':7,
|
|
|
|
|
'cl-backup':8,
|
|
|
|
|
}
|
|
|
|
|
# Cвязь сервисов и действующих опций
|
|
|
|
|
self.relServices = {"samba":[_("Common options"),
|
|
|
|
|
_("Samba service options")],
|
|
|
|
|
"ldap":[_("Common options"),
|
|
|
|
|
_("LDAP service options")],
|
|
|
|
|
"unix":[_("Common options"),
|
|
|
|
|
_("Unix service options")],
|
|
|
|
|
"mail":[_("Common options"),
|
|
|
|
|
_("Mail service options")],
|
|
|
|
|
"jabber":[_("Common options"),
|
|
|
|
|
_("Jabber service options")],
|
|
|
|
|
}
|
|
|
|
|
# Cвязь длинных опций помощи и выводимых разделов помощи с опциями
|
|
|
|
|
self.relOptions = {"h":[_("Common options")],
|
|
|
|
|
"help-ldap":[_("Common options"),
|
|
|
|
|
_("LDAP service options")],
|
|
|
|
|
"help-unix":[_("Common options"),
|
|
|
|
|
_("Unix service options")],
|
|
|
|
|
"help-samba":[_("Common options"),
|
|
|
|
|
_("Samba service options")],
|
|
|
|
|
"help-mail": [_("Common options"),
|
|
|
|
|
_("Mail service options")],
|
|
|
|
|
"help-jabber":[_("Common options"),
|
|
|
|
|
_("Jabber service options")],
|
|
|
|
|
"help-all":[_("Common options"),
|
|
|
|
|
_("Samba service options"),
|
|
|
|
|
_("LDAP service options"),
|
|
|
|
|
_("Unix service options"),
|
|
|
|
|
_("Mail service options"),
|
|
|
|
|
_("Jabber service options")
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# список разделов, которые на наличие в ней информации
|
|
|
|
|
# используется для автоматического отображения/скрытия
|
|
|
|
|
# опций help-имя
|
|
|
|
|
# Пример: self.relOption =
|
|
|
|
|
# { "help-all":[_("Common options"], _("Unix service options"),
|
|
|
|
|
# _("Samba service options"), _("LDAP service options")}]
|
|
|
|
|
# self.relChapterPass = (_("Common options"),)
|
|
|
|
|
# это означается что опция будет активна, если только в разделах
|
|
|
|
|
# кроме Common options есть хоть одна доступная опция.
|
|
|
|
|
self.relChapterPass = (_("Common options"),)
|
|
|
|
|
|
|
|
|
|
self.data = [\
|
|
|
|
|
# Options
|
|
|
|
|
{'shortOption':"h",
|
|
|
|
|
'longOption':"help",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("display this help and exit")
|
|
|
|
|
},
|
|
|
|
|
{'longOption':"help-all",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("display help for all services options")
|
|
|
|
|
},
|
|
|
|
|
{'longOption':"help-jabber",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("display help for Jabber service options")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(6,),
|
|
|
|
|
'longOption':"help-ldap",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("display help for LDAP service options")
|
|
|
|
|
},
|
|
|
|
|
{'longOption':"help-mail",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("display help for Mail service options")
|
|
|
|
|
},
|
|
|
|
|
{'longOption':"help-samba",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("display help for Samba service options")
|
|
|
|
|
},
|
|
|
|
|
{'longOption':"help-unix",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("display help for Unix service options")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"f",
|
|
|
|
|
'longOption':"force",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("does not check system group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"gid",
|
|
|
|
|
'optVal':"GID",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("use GID for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("set the description field for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':"COMMENT",
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("set the description field for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':"COMMENT",
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("set the description field for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("print the gidNumber to stdout")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"e",
|
|
|
|
|
'longOption':"alt-emails",
|
|
|
|
|
'optVal':_("ALT_EMAILS"),
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("set alternate email addresses for the new mail group")
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"f",
|
|
|
|
|
'longOption':"force",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("does not check system group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"gid",
|
|
|
|
|
'optVal':"GID",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("use GID for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("set the description field for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("print the gidNumber to stdout")
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{'progAccess':(2,),
|
|
|
|
|
'shortOption':"a",
|
|
|
|
|
'longOption':"add",
|
|
|
|
|
'optVal':_("USERS"),
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("add members (comma delimited)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(2,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("set the description field for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(2,),
|
|
|
|
|
'shortOption':"d",
|
|
|
|
|
'longOption':"delete",
|
|
|
|
|
'optVal':_("USERS"),
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("delete members (comma delimted)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(2,),
|
|
|
|
|
'shortOption':"n",
|
|
|
|
|
'longOption':"new-name",
|
|
|
|
|
'optVal':_("NEW_GROUP"),
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("force use NEW_GROUP name by GROUP")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"b",
|
|
|
|
|
'longOption':"base-dir",
|
|
|
|
|
'optVal':_("BASE_DIR"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("base directory for the new user account home directory")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("set the COMMENT field for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("set the COMMENT field for the new unix account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"e",
|
|
|
|
|
'longOption':"alt-emails",
|
|
|
|
|
'optVal':_("ALT_EMAILS"),
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("set alternate email addresses for the new mail account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("set the COMMENT field for the new account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("set the COMMENT field for the new account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"i",
|
|
|
|
|
'longOption':"image",
|
|
|
|
|
'optVal':_("IMAGE"),
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("set the jpeg image photo for the new account (file)")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(3,),
|
|
|
|
|
#'shortOption':"i",
|
|
|
|
|
#'longOption':"image",
|
|
|
|
|
#'optVal':_("IMAGE"),
|
|
|
|
|
#'helpChapter':_("Unix service options"),
|
|
|
|
|
#'help':_("set the jpeg image photo for the new account (file)")
|
|
|
|
|
#},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"d",
|
|
|
|
|
'longOption':"home-dir",
|
|
|
|
|
'optVal':_("HOME_DIR"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("home directory for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"gid",
|
|
|
|
|
'optVal':_("GROUP"),
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("force use GROUP for the new user Unix service account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"u",
|
|
|
|
|
'longOption':"uid",
|
|
|
|
|
'optVal':_("UID"),
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("force use UID for the new user Unix service account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"gid",
|
|
|
|
|
'optVal':_("GROUP"),
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("force use GROUP for the new user Unix service account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"gid",
|
|
|
|
|
'optVal':_("GROUP"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("force use GROUP for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"G",
|
|
|
|
|
'longOption':"groups",
|
|
|
|
|
'optVal':_("GROUPS"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("list of supplementary groups for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"G",
|
|
|
|
|
'longOption':"groups",
|
|
|
|
|
'optVal':_("GROUPS"),
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("list of supplementary groups for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"k",
|
|
|
|
|
'longOption':"skel",
|
|
|
|
|
'optVal':_("SKEL_DIR"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("specify an alternative skel directory")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"m",
|
|
|
|
|
'longOption':"create-home",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("create home directory for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'longOption':"password",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("use password for the user account") +\
|
|
|
|
|
" (" + _("from dialog") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"P",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("use password for the user account") +\
|
|
|
|
|
" (" + _("from standard input") + ")"
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(3,),
|
|
|
|
|
#'shortOption':"f",
|
|
|
|
|
#'longOption':"force",
|
|
|
|
|
#'helpChapter':_("Samba service options"),
|
|
|
|
|
#'help':_("create unix user account and Samba user account")
|
|
|
|
|
#},
|
|
|
|
|
#{'progAccess':(3,),
|
|
|
|
|
#'shortOption':"f",
|
|
|
|
|
#'longOption':"force",
|
|
|
|
|
#'helpChapter':_("Mail service options"),
|
|
|
|
|
#'help':_("create unix user account and mail user account")
|
|
|
|
|
#},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"n",
|
|
|
|
|
'longOption':"create-profile",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("create a directories for storing new user account \
|
|
|
|
|
preferences and data (for users with uid<1000)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'longOption':"password",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("use password for the user account") +\
|
|
|
|
|
" (" + _("from dialog") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"P",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("use password for the user account") +\
|
|
|
|
|
" (" + _("from standard input") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'longOption':"password",
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("use password for the user account")+\
|
|
|
|
|
" (" + _("from dialog") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"P",
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("use password for the user account")+\
|
|
|
|
|
" (" + _("from standard input") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'longOption':"password",
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("use password for the user account")+\
|
|
|
|
|
" (" + _("from dialog") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"P",
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("use password for the user account")+\
|
|
|
|
|
" (" + _("from standard input") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"w",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("set the trust account")+\
|
|
|
|
|
" (" + _("Windows Workstations") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"s",
|
|
|
|
|
'longOption':"shell",
|
|
|
|
|
'optVal':_("SHELL"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("the login shell for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"u",
|
|
|
|
|
'longOption':"uid",
|
|
|
|
|
'optVal':_("UID"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("force use the UID for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"v",
|
|
|
|
|
'longOption':"visible",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("the new user account is visible (default - invisible)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(4,),
|
|
|
|
|
'shortOption':"r",
|
|
|
|
|
'longOption':"remove",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("not create backup deleted user data")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(4,),
|
|
|
|
|
'shortOption':"r",
|
|
|
|
|
'longOption':"remove",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("not create backup deleted user data")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(4,),
|
|
|
|
|
'shortOption':"r",
|
|
|
|
|
'longOption':"remove",
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("not create backup deleted user data")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"G",
|
|
|
|
|
'longOption':"groups",
|
|
|
|
|
'optVal':_("GROUPS"),
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("new list of supplementary GROUPS (used Unix groups)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"s",
|
|
|
|
|
'longOption':"smb",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("used in conjunction with the option '-p', \
|
|
|
|
|
the password will be changed only for Samba account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("new value of the COMMENT field")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("new value of the COMMENT field")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':_("COMMENT"),
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("new value of the COMMENT field (full name user)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"e",
|
|
|
|
|
'longOption':"alt-emails",
|
|
|
|
|
'optVal':"ALT_EMAILS",
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("set alternate email addresses for the mail account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"d",
|
|
|
|
|
'longOption':"home",
|
|
|
|
|
'optVal':_("HOME_DIR"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("new home directory for the user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"gid",
|
|
|
|
|
'optVal':_("GROUP"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("force use GROUP as new primary group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"group",
|
|
|
|
|
'optVal':_("GROUP"),
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("force use GROUP as new Jabber group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"G",
|
|
|
|
|
'longOption':"groups",
|
|
|
|
|
'optVal':_("GROUPS"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("new list of supplementary GROUPS")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"i",
|
|
|
|
|
'longOption':"image",
|
|
|
|
|
'optVal':_("IMAGE"),
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("set the jpeg image photo for user (file)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"G",
|
|
|
|
|
'longOption':"groups",
|
|
|
|
|
'optVal':_("GROUPS"),
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("new list of supplementary email GROUPS")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"a",
|
|
|
|
|
'longOption':"append",
|
|
|
|
|
'optVal':_("GROUPS"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("append the user to the supplemental GROUPS")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"a",
|
|
|
|
|
'longOption':"append",
|
|
|
|
|
'optVal':_("GROUPS"),
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("append the user to the supplemental email GROUPS")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"m",
|
|
|
|
|
'longOption':"move-home",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("move contents of the home directory to the new location")+\
|
|
|
|
|
" (" + _("use only with") + " -d)"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'longOption':"password",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("new password for the user account")+\
|
|
|
|
|
" (" + _("from dialog") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"P",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("new password for the user account")+\
|
|
|
|
|
" (" + _("from standard input") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"s",
|
|
|
|
|
'longOption':"shell",
|
|
|
|
|
'optVal':_("SHELL"),
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("new login shell for the user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"L",
|
|
|
|
|
'longOption':"lock",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("lock the user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"U",
|
|
|
|
|
'longOption':"unlock",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("unlock the user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"V",
|
|
|
|
|
'longOption':"visible",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("the user account is visible")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"I",
|
|
|
|
|
'longOption':"invisible",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("the user account is invisible")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(5,),
|
|
|
|
|
#'shortOption':"u",
|
|
|
|
|
#'longOption':"uid",
|
|
|
|
|
#'optVal':"UID",
|
|
|
|
|
#'helpChapter':_("Common options"),
|
|
|
|
|
#'help':_("new UID for the user account")
|
|
|
|
|
#},
|
|
|
|
|
|
|
|
|
|
{'progAccess':(6,),
|
|
|
|
|
'shortOption':"f",
|
|
|
|
|
'longOption':"force",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("forced setup service")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(6,),
|
|
|
|
|
'shortOption':"n",
|
|
|
|
|
'longOption':"netbios_name",
|
|
|
|
|
'optVal':"NETBIOS_NAME",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("netbios name, default hostname")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(6,),
|
|
|
|
|
'shortOption':"w",
|
|
|
|
|
'optVal':"WORKGROUP",
|
|
|
|
|
'longOption':"workgroup",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("workgroup, default 'Calculate'")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(6,),
|
|
|
|
|
'optVal':"HOST",
|
|
|
|
|
'longOption':"host",
|
|
|
|
|
'helpChapter':_("Mail service options"),
|
|
|
|
|
'help':_("mail host, default - hostname")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(6,),
|
|
|
|
|
'optVal':"HOST",
|
|
|
|
|
'longOption':"host",
|
|
|
|
|
'helpChapter':_("Jabber service options"),
|
|
|
|
|
'help':_("jabber host, default - hostname")
|
|
|
|
|
},
|
|
|
|
|
# Опции cl-passwd
|
|
|
|
|
# LDAP пользователь
|
|
|
|
|
{'progAccess':(7,),
|
|
|
|
|
'shortOption':"d",
|
|
|
|
|
'longOption':"delete",
|
|
|
|
|
'helpChapter':_("Unix service options"),
|
|
|
|
|
'help':_("delete the password for the named account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(7,),
|
|
|
|
|
'shortOption':"s",
|
|
|
|
|
'longOption':"smb",
|
|
|
|
|
'helpChapter':_("Samba service options"),
|
|
|
|
|
'help':_("password will be changed only for Samba account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(7,),
|
|
|
|
|
'shortOption':"l",
|
|
|
|
|
'longOption':"lock",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("lock the named account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(7,),
|
|
|
|
|
'shortOption':"u",
|
|
|
|
|
'longOption':"unlock",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("unlock the named account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(8,),
|
|
|
|
|
'shortOption':"b",
|
|
|
|
|
'longOption':"backup",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("backup services configuration files and LDAP branches")+\
|
|
|
|
|
" (" + _("default option") + ")"
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(8,),
|
|
|
|
|
'shortOption':"r",
|
|
|
|
|
'longOption':"restore",
|
|
|
|
|
'helpChapter':_("Common options"),
|
|
|
|
|
'help':_("restore services configuration files and LDAP branches")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(0,1,2,4,5,6),
|
|
|
|
|
#'shortOption':"s",
|
|
|
|
|
#'longOption':"set",
|
|
|
|
|
#'optVal':"<name>=<val>",
|
|
|
|
|
#'helpChapter':_("Common options"),
|
|
|
|
|
#'help':_("change enviroment values")
|
|
|
|
|
#},
|
|
|
|
|
#{'shortOption':"e",
|
|
|
|
|
#'longOption':"env",
|
|
|
|
|
#'optVal':"filter",
|
|
|
|
|
#'helpChapter':_("Common options"),
|
|
|
|
|
#'help':_("show enviroment values (filter for type, all - no filter)")
|
|
|
|
|
#},
|
|
|
|
|
# Services
|
|
|
|
|
{'progAccess':(6,),
|
|
|
|
|
'helpChapter':_("Services"),
|
|
|
|
|
'help':pcs(" ldap", self.column_width,
|
|
|
|
|
"ldap " + servName, self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{'progAccess':(0,1,2,3,4,5,6,7,),
|
|
|
|
|
'helpChapter':_("Services"),
|
|
|
|
|
'help':pcs(" unix", self.column_width,
|
|
|
|
|
"unix " + servName, self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,4,5,6,7,),
|
|
|
|
|
'helpChapter':_("Services"),
|
|
|
|
|
'help':pcs(" samba", self.column_width,
|
|
|
|
|
"samba " + servName, self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,1,2,),
|
|
|
|
|
'helpChapter':_("Services"),
|
|
|
|
|
'help':pcs(" samba", self.column_width,
|
|
|
|
|
_("using unix group"),
|
|
|
|
|
self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,1,2,3,4,5,6,7,),
|
|
|
|
|
'helpChapter':_("Services"),
|
|
|
|
|
'help':pcs(" mail", self.column_width,
|
|
|
|
|
"mail " + servName, self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,1,2,3,4,5,6,7,),
|
|
|
|
|
'helpChapter':_("Services"),
|
|
|
|
|
'help':pcs(" jabber", self.column_width,
|
|
|
|
|
"jabber " + servName, self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" mail \t\t\tmail " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" ftp \t\t\tftp " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" proxy \t\tproxy " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" radius \t\tradius " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" jabber \t\tjabber " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" addressbook \t\taddressbook " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" dhcp \t\t\tdhcp " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" named \t\tnamed " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" wiki \t\t\twiki " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
# Informative output
|
|
|
|
|
{
|
|
|
|
|
#'progAccess':(3,),
|
|
|
|
|
'helpChapter':"Copyright",
|
|
|
|
|
'help':Version
|
|
|
|
|
},
|
|
|
|
|
# Использование
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(1,),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " " +_("group") + " " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(0,2),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " [" + _("options") + "] " +\
|
|
|
|
|
_("group") + " " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(3,4,5,7),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " [" + _("options") + "] " + _("user") +\
|
|
|
|
|
" " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(6,),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " [" + _("options") + "] "+\
|
|
|
|
|
" " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(8,),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " [" + _("options") + "]"
|
|
|
|
|
},
|
|
|
|
|
# Function
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(0,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Add group in LDAP directory service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(1,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Delete group from LDAP directory service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(2,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Modify group profiles in LDAP directory service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(3,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Add user in LDAP directory service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(4,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Delete user from LDAP directory service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(5,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Modify user profiles in LDAP directory service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(6,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Sets service in the system")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(7,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Change user password")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(8,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Backup service")
|
|
|
|
|
},
|
|
|
|
|
# Примеры
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(0,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs( " cl-groupadd guest ldap", self.column_width,
|
|
|
|
|
"# " + _("add group guest in LDAP service"),
|
|
|
|
|
self.consolewidth-self.column_width )
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(1,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs( " cl-groupdel guest unix", self.column_width,
|
|
|
|
|
"# " + _("delete group guest from Unix service") + "."
|
|
|
|
|
, self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(2,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs( " cl-groupmod -a guest test unix", self.column_width,
|
|
|
|
|
"# " + _("add user test to group guest in Unix service"),
|
|
|
|
|
self.consolewidth-self.column_width )
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(3,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-useradd guest samba", self.column_width,
|
|
|
|
|
"# " +_("add user guest in Samba service") + ".",
|
|
|
|
|
self.consolewidth - self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(4,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-userdel guest samba", self.column_width,
|
|
|
|
|
"# " + _("delete user guest from Samba service") + ".",
|
|
|
|
|
self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(5,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-usermod -a test guest unix",
|
|
|
|
|
self.column_width,
|
|
|
|
|
"# " + _("append user guest to the supplemental group test") +\
|
|
|
|
|
".",
|
|
|
|
|
self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(6,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-setup samba", self.column_width,
|
|
|
|
|
"# "+_("set Samba service in the system") + ".",
|
|
|
|
|
self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(7,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-passwd test samba", self.column_width,
|
|
|
|
|
"# "+_("change password of user test for Samba service") + ".",
|
|
|
|
|
self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(8,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-backup -r", self.column_width,
|
|
|
|
|
"# "+_("restore all services") + ".",
|
|
|
|
|
self.consolewidth-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
#{
|
|
|
|
|
#'helpChapter':_("Examples"),
|
|
|
|
|
#'help':pcs(" " + cmdName + " --env boot", self.column_width,
|
|
|
|
|
#"# "+_("show enviroment varibles which has type")+" 'boot'" +\
|
|
|
|
|
#".",
|
|
|
|
|
#self.consolewidth-self.column_width)
|
|
|
|
|
#},
|
|
|
|
|
#{'progAccess':(0,1,2,4,5,6),
|
|
|
|
|
#'helpChapter':_("Examples"),
|
|
|
|
|
#'help':pcs(" " + cmdName + " \\\n --set setup_march=x86_64",
|
|
|
|
|
#self.column_width, "# "+ _("modify some env") + ".",
|
|
|
|
|
#self.consolewidth-self.column_width)
|
|
|
|
|
#},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
self._cl_help__setParamHelp()
|
|
|
|
|
|
|
|
|
|
# Удаляем ненужный аттрибут класса cl_profile.xmlShare
|
|
|
|
|
self._createElement = False
|
|
|
|
|
delattr(self, "_createElement")
|
|
|
|
|
|
|
|
|
|
#Название всех сервисов
|
|
|
|
|
self.allServ = []
|
|
|
|
|
self.__setAllServ()
|
|
|
|
|
|
|
|
|
|
def processOptionsForDatavars(self, options, datavars):
|
|
|
|
|
'''Обработать опции связанные с переменными окружения
|
|
|
|
|
|
|
|
|
|
Параметры:
|
|
|
|
|
options словарь опций ( <буква опции>:<значение>
|
|
|
|
|
обрабатывает буквы 's' для установки параметров
|
|
|
|
|
'e' для отображения)
|
|
|
|
|
datavars объект-хранилище переменных окружнения
|
|
|
|
|
|
|
|
|
|
Возвращаемые значения:
|
|
|
|
|
True удалось установить указанные параметры
|
|
|
|
|
False метод вызван для просмотра переменных окружения, или
|
|
|
|
|
установка переменных окружения прошла с ошибками.
|
|
|
|
|
'''
|
|
|
|
|
# если это установка параметров
|
|
|
|
|
if 's' in options:
|
|
|
|
|
# если установки параметрв не произошло
|
|
|
|
|
if not datavars.flFromCmdParam(options['s']):
|
|
|
|
|
# вывод
|
|
|
|
|
print _("Bad enviroment parameters")
|
|
|
|
|
return False
|
|
|
|
|
# если опция отображения параметров
|
|
|
|
|
if 'e' in options:
|
|
|
|
|
# вывод всех параметров
|
|
|
|
|
if options['e'] == '*':
|
|
|
|
|
datavars.printVars()
|
|
|
|
|
# вывод параметров, используюя фильтр
|
|
|
|
|
else:
|
|
|
|
|
datavars.printVars(
|
|
|
|
|
[i.strip() for i in options['e'].split(':')])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def handleCheckAccess(self,dataHash):
|
|
|
|
|
"""Дополнительная проверка опций-справок - опция доступна только если
|
|
|
|
|
в разделах этой справки есть хотябы одна опция
|
|
|
|
|
|
|
|
|
|
Входные параметры:
|
|
|
|
|
dataHash словарь из списка self.data
|
|
|
|
|
"""
|
|
|
|
|
# если эта опция для реализации справки
|
|
|
|
|
if 'longOption' in dataHash \
|
|
|
|
|
and dataHash['longOption'] in self.relOptions:
|
|
|
|
|
# составляем список разделов которые должны быть не пустые
|
|
|
|
|
# разделы из relOptions относящиеся к этой опции за исключением
|
|
|
|
|
# разделов которые надо пропустить (relChapterPass)
|
|
|
|
|
trueChapters = \
|
|
|
|
|
set(self.relOptions[dataHash['longOption']]).difference( \
|
|
|
|
|
self.relChapterPass)
|
|
|
|
|
# перебираем все опции
|
|
|
|
|
for unit in self.data:
|
|
|
|
|
# если опция не отностится к выполняемой программе, то
|
|
|
|
|
# ее пропустить
|
|
|
|
|
if 'progAccess' in unit and \
|
|
|
|
|
not self.progName[self.cmdName] in unit['progAccess']:
|
|
|
|
|
continue
|
|
|
|
|
# если опция отностится к необходмой справки
|
|
|
|
|
if unit['helpChapter'] in trueChapters:
|
|
|
|
|
# опция справки - доступна
|
|
|
|
|
return True
|
|
|
|
|
# если не оказалось не одной опция для разделов этой справки
|
|
|
|
|
return False
|
|
|
|
|
# опция доступна, так как не справочная
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def __setAllServ(self):
|
|
|
|
|
"""Записывает в аттрибут self.allServ названия всех сервисов"""
|
|
|
|
|
sServ = re.compile("\s*([^\s]+)\s*")
|
|
|
|
|
for par in self.data:
|
|
|
|
|
if par.has_key('helpChapter') and\
|
|
|
|
|
par['helpChapter'] == _("Services") and\
|
|
|
|
|
par.has_key('help') and self.access(par):
|
|
|
|
|
res = sServ.search(par['help'])
|
|
|
|
|
if res:
|
|
|
|
|
self.allServ.append(res.group(1))
|
|
|
|
|
|
|
|
|
|
class servFtp(shareLdap):
|
|
|
|
|
"""Методы севисa Ftp"""
|
|
|
|
|
def __init__(self, smbObj=False):
|
|
|
|
|
shareLdap.__init__(self)
|
|
|
|
|
self.relUsDN = 'ou=Users'
|
|
|
|
|
self.relServDN = 'ou=Ftp'
|
|
|
|
|
self.relDN = self.addDN(self.relServDN,self.ServicesDN)
|
|
|
|
|
# DN пользователей, относительно базового DN
|
|
|
|
|
self.relUsersDN = self.addDN(self.relUsDN, self.relDN)
|
|
|
|
|
# DN групп пользователей, относительно базового DN
|
|
|
|
|
self.relGroupsDN = self.addDN(self.relGrDN, self.relDN)
|
|
|
|
|
# Алгоритм шифрования пароля для LDAP пользователя
|
|
|
|
|
self.userCrypt = "{SSHA}"
|
|
|
|
|
# Используемые ldif файлы
|
|
|
|
|
self.ldifFileUser =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/ftp_user.ldif"
|
|
|
|
|
self.ldifFileBase =\
|
|
|
|
|
"/usr/lib/calculate/calculate-server/ldif/ftp_base.ldif"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class tsOpt(cl_base.opt):
|
|
|
|
|
"""Класс для обработки параметров и вывода help
|
|
|
|
|
|
|
|
|
|
Параметры:
|
|
|
|
|
helpObj объект-справка содержащий необходимые опции
|
|
|
|
|
parBeforeService дополнительные необходимые параметры перед указанным
|
|
|
|
|
сервисом. (например "group" или "user")
|
|
|
|
|
optService проверять хвост командной строки на наличие сервиса
|
|
|
|
|
notOptError выдавать ошибку при отсутствии опций командной строки
|
|
|
|
|
"""
|
|
|
|
|
def __init__(self, helpObj, parBeforeService,optService=True,
|
|
|
|
|
notOptError=False):
|
|
|
|
|
# последний параметр является сервисом
|
|
|
|
|
service = sys.argv[-1:][0].rstrip()
|
|
|
|
|
# от cl_help получаем короткие и длинные опции
|
|
|
|
|
if service in helpObj.allServ:
|
|
|
|
|
shortOpt, longOpt = helpObj.getAllOpt('all',
|
|
|
|
|
helpObj.relServices[service])
|
|
|
|
|
else:
|
|
|
|
|
shortOpt,longOpt = helpObj.getAllOpt('all',
|
|
|
|
|
helpObj.relOptions['h'])
|
|
|
|
|
# вызвать конструктор объекта, распознающего опции
|
|
|
|
|
cl_base.opt.__init__(self,shortOpt,longOpt)
|
|
|
|
|
|
|
|
|
|
self.nameParams = parBeforeService + ['service']
|
|
|
|
|
self.sysArgv = sys.argv[1:]
|
|
|
|
|
self.helpObj = helpObj
|
|
|
|
|
self.__iter = 0
|
|
|
|
|
self.opt = {}
|
|
|
|
|
self.params = {}
|
|
|
|
|
self.getopt()
|
|
|
|
|
# Обработка help
|
|
|
|
|
self.flagHelp = False
|
|
|
|
|
# определяем есть ли среди опций опции, которые влияют на показ
|
|
|
|
|
# опциональных разделов (метод пересечения множеств)
|
|
|
|
|
helpopt = \
|
|
|
|
|
tuple(set(self.opt.keys()).intersection(helpObj.relOptions.keys()))
|
|
|
|
|
#Если есть опции help
|
|
|
|
|
if len(helpopt) > 0:
|
|
|
|
|
print helpObj.getHelp(helpObj.relOptions[helpopt[0]])
|
|
|
|
|
self.flagHelp = True
|
|
|
|
|
#Если нет хвостов
|
|
|
|
|
elif not self.params:
|
|
|
|
|
if optService:
|
|
|
|
|
print helpObj.getHelp(helpObj.relOptions['h'])
|
|
|
|
|
self.flagHelp = True
|
|
|
|
|
else:
|
|
|
|
|
if self.params.has_key('service'):
|
|
|
|
|
if not (self.params['service'] in helpObj.allServ) or\
|
|
|
|
|
len(self.nameParams) != self.__iter:
|
|
|
|
|
self.handlerErrOpt()
|
|
|
|
|
else:
|
|
|
|
|
self.handlerErrOpt()
|
|
|
|
|
# В случае остсутствия опций командной строки
|
|
|
|
|
if notOptError and not self.opt and self.params.has_key('service'):
|
|
|
|
|
self.printErrorNotOpt()
|
|
|
|
|
self.flagHelp = True
|
|
|
|
|
|
|
|
|
|
def printErrorNotOpt(self):
|
|
|
|
|
"""Сообщение в случае отсутствия опций"""
|
|
|
|
|
print _("Options are absent.")
|
|
|
|
|
|
|
|
|
|
def handlerOpt(self,option,value):
|
|
|
|
|
# Обработчик (опция значение)
|
|
|
|
|
#print option, value
|
|
|
|
|
shortOpt = self.helpObj.getShortOpt(option)
|
|
|
|
|
if not shortOpt:
|
|
|
|
|
shortOpt = option
|
|
|
|
|
if not shortOpt in self.opt:
|
|
|
|
|
self.opt[shortOpt] = value
|
|
|
|
|
|
|
|
|
|
def handlerErrOpt(self):
|
|
|
|
|
# Обработчик ошибок
|
|
|
|
|
argv = " ".join(sys.argv[1:])
|
|
|
|
|
print _("Unrecognized option") + ' "' + argv + '"\n' + \
|
|
|
|
|
_("Try") + ' "' + sys.argv[0].split("/")[-1] + ' --help" ' +\
|
|
|
|
|
_("for more information.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handlerParam(self,param):
|
|
|
|
|
# Обработчик хвостов (значение)
|
|
|
|
|
self.__iter += 1
|
|
|
|
|
if self.__iter<=len(self.nameParams):
|
|
|
|
|
self.params[self.nameParams[self.__iter-1]] = param
|
|
|
|
|
|