develop
asamoukin 16 years ago
parent 0607099a9c
commit fd60d274cc

@ -0,0 +1,281 @@
#
# qmail-ldap (20030901) ldapv3 directory schema
#
# The offical qmail-ldap OID assigned by IANA is 7914
#
# Created by: David E. Storey <dave@tamos.net>
# Modified and included into qmail-ldap by Andre Oppermann <opi@nrg4u.com>
# Schema fixes by Mike Jackson <mjj@pp.fi>
# Schema fixes by Christian Zoffoli (XMerlin) <czoffoli@xmerlin.org>
#
#
# This schema depends on:
# - core.schema
# - cosine.schema
# - nis.schema
#
# Attribute Type Definitions
attributetype ( 1.3.6.1.4.1.7914.1.2.1.1 NAME 'qmailUID'
DESC 'UID of the user on the mailsystem'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.2 NAME 'qmailGID'
DESC 'GID of the user on the mailsystem'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.3 NAME 'mailMessageStore'
DESC 'Path to the maildir/mbox on the mail system'
EQUALITY caseExactIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.4 NAME 'mailAlternateAddress'
DESC 'Secondary (alias) mailaddresses for the same user'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
#
# mailQuota format is no longer supported from qmail-ldap 20030901 on,
# user mailQuotaSize and mailQuotaCount instead.
#
#attributetype ( 1.3.6.1.4.1.7914.1.2.1.5 NAME 'mailQuota'
# DESC 'The amount of space the user can use until all further messages get bounced.'
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
# Конфликтует с misc.schema
#attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'mailHost'
# DESC 'On which qmail server the messagestore of this user is located.'
# EQUALITY caseIgnoreIA5Match
# SUBSTR caseIgnoreIA5SubstringsMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE)
attributetype ( 1.3.6.1.4.1.7914.1.2.1.7 NAME 'mailForwardingAddress'
DESC 'Address(es) to forward all incoming messages to.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.8 NAME 'deliveryProgramPath'
DESC 'Program to execute for all incoming mails.'
EQUALITY caseExactIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.9 NAME 'qmailDotMode'
DESC 'Interpretation of .qmail files: both, dotonly, ldaponly, ldapwithprog'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.10 NAME 'deliveryMode'
DESC 'multi field entries of: nolocal, noforward, noprogram, reply'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.11 NAME 'mailReplyText'
DESC 'A reply text for every incoming message'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.12 NAME 'accountStatus'
DESC 'The status of a user account: active, noaccess, disabled, deleted'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.14 NAME 'qmailAccountPurge'
DESC 'The earliest date when a mailMessageStore will be purged'
EQUALITY numericStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.15 NAME 'mailQuotaSize'
DESC 'The size of space the user can have until further messages get bounced.'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.16 NAME 'mailQuotaCount'
DESC 'The number of messages the user can have until further messages get bounced.'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.17 NAME 'mailSizeMax'
DESC 'The maximum size of a single messages the user accepts.'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
#
# qmailGroup attributes
#
attributetype ( 1.3.6.1.4.1.7914.1.3.1.1 NAME 'dnmember'
DESC 'Group member specified as distinguished name.'
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.2 NAME 'rfc822member'
DESC 'Group member specified as normal rf822 email address.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.3 NAME 'filtermember'
DESC 'Group member specified as ldap search filter.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{512} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.4 NAME 'senderconfirm'
DESC 'Sender to Group has to answer confirmation email.'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.5 NAME 'membersonly'
DESC 'Sender to Group must be group member itself.'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.6 NAME 'confirmtext'
DESC 'Text that will be sent with sender confirmation email.'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.7 NAME 'dnmoderator'
DESC 'Group moderator specified as Distinguished name.'
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.8 NAME 'rfc822moderator'
DESC 'Group moderator specified as normal rfc822 email address.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.9 NAME 'moderatortext'
DESC 'Text that will be sent with request for moderation email.'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.10 NAME 'dnsender'
DESC 'Allowed sender specified as distinguished name.'
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.11 NAME 'rfc822sender'
DESC 'Allowed sender specified as normal rf822 email address.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.12 NAME 'filtersender'
DESC 'Allowed sender specified as ldap search filter.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{512} )
attributetype ( 1.3.6.1.4.1.7914.1.3.1.13 NAME 'bounceadmin'
DESC 'rfc822 email address where bounces should be sent to.'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
#
# qldapAdmin Attributes
#
attributetype ( 1.3.6.1.4.1.7914.1.4.1.1 NAME 'qladnmanager'
DESC ''
EQUALITY distinguishedNameMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.2 NAME 'qlaDomainList'
DESC ''
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.3 NAME 'qlaUidPrefix'
DESC ''
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.4 NAME 'qlaQmailUid'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.5 NAME 'qlaQmailGid'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.6 NAME 'qlaMailMStorePrefix'
DESC ''
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.7 NAME 'qlaMailQuotaSize'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.8 NAME 'qlaMailQuotaCount'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.9 NAME 'qlaMailSizeMax'
DESC ''
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.7914.1.4.1.10 NAME 'qlaMailHostList'
DESC ''
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
# Object Class Definitions
objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'qmailUser'
DESC 'QMail-LDAP User'
SUP top
AUXILIARY
MUST ( mail )
MAY ( uid $ mailMessageStore $ homeDirectory $ userPassword $
mailAlternateAddress $ qmailUID $ qmailGID $
mailHost $ mailForwardingAddress $ deliveryProgramPath $
qmailDotMode $ deliveryMode $ mailReplyText $
accountStatus $ qmailAccountPurge $
mailQuotaSize $ mailQuotaCount $ mailSizeMax ) )
objectclass ( 1.3.6.1.4.1.7914.1.3.2.1 NAME 'qmailGroup'
DESC 'QMail-LDAP Group'
SUP top
AUXILIARY
MUST ( mail $ mailAlternateAddress $ mailMessageStore )
MAY ( dnmember $ rfc822member $ filtermember $ senderconfirm $
membersonly $ confirmtext $ dnmoderator $ rfc822moderator $
moderatortext $ dnsender $ rfc822sender $ filtersender $
bounceadmin) )
objectclass ( 1.3.6.1.4.1.7914.1.4.2.1 NAME 'qldapAdmin'
DESC 'QMail-LDAP Subtree Admin'
SUP top
AUXILIARY
MUST ( qlaDnManager $ qlaDomainList $ qlaMailMStorePrefix $
qlaMailHostList )
MAY ( qlaUidPrefix $ qlaQmailUid $ qlaQmailGid $ qlaMailQuotaSize $
qlaMailQuotaCount $ qlaMailSizeMax ) )

@ -5,6 +5,7 @@ include /etc/openldap/schema/core.schema
+include /etc/openldap/schema/inetorgperson.schema
+include /etc/openldap/schema/misc.schema
+include /etc/openldap/schema/samba.schema
+include /etc/openldap/schema/qmail.schema
schemacheck on

@ -13,7 +13,7 @@ pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.arg
# Уровень отладочных сообщений
loglevel 1
loglevel 0
allow bind_v2
modulepath /usr/lib/openldap/modules

@ -20,7 +20,7 @@ daemon_directory = /usr/lib/postfix
mail_owner = postfix
#Имя хоста
#myhostname = cds.local.calculate.ru
myhostname = #-net_host-#.#-sys_domain-#
#Определяет домен данного компьютера. По умолчанию преобразуется из myhostname
#mydomain = local.calculate.ru
@ -53,8 +53,7 @@ unknown_local_recipient_reject_code = 550
#прописываем следующие сети 127.0.0.0 (для localhost, собственно сам
#сервер), 192.168.10.0 (для всех других компьютеров в нашей внешней сети),
#и 192.168.0.0 (для всех компьютеров во внутренней сети).
# Не забыть про шлюз (212.113.122.130)
mynetworks = #-net_networks-#, 10.0.10.0/24, 192.168.1.2, 10.0.50.0/24, 127.0.0.0/8, 212.113.122.130
mynetworks = #-net_networks-#, 127.0.0.0/8#-soft_ldap_mail_relay-#
#По умолчанию, Postfix пытается посылать почту в Internet напрямую. В зависимости
#от окружения, в котором функционирует Ваш почтовый сервер, это может быть
@ -109,6 +108,9 @@ local_recipient_maps = ldap:/etc/postfix/ldap-recipient.cf, ldap:/etc/postfix/ld
#нашем случае - это MAILER-DAEMON (а еще лучше послать на /dev/null)
empty_address_recipient = MAILER-DAEMON
#Удалем эту команду (директория в которой храняться письма)
!home_mailbox = .maildir/
#Эта директива запрещает принимать какие-либо сообщения, если
#пространства на жестком диске осталось менее чем 200Mb. This number
#should be 1.5 times the message_size_limit or you will get an error

@ -33,6 +33,9 @@ import getpass
import stat
import types
import time
# Для ввода символа
import tty
import termios
Version = "calculate-server 0.0.1"
@ -164,6 +167,47 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
# DN сервисов относительно базового
self.ServicesDN = "ou=Services"
def runLdapServer(self):
"""Запускает LDAP сервер"""
textLine = self.execProg("/etc/init.d/slapd start")
if "ok" in textLine:
return True
else:
self.printNotOK(_("LDAP start")+ " ...")
return False
def restartLdapServer(self):
"""Запускает LDAP сервер"""
textLine = self.execProg("/etc/init.d/slapd restart")
if "ok" in textLine:
return True
else:
self.printNotOK(_("LDAP restart")+ " ...")
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(_("LDAP stop")+ " ...")
return False
def getALLServices(self):
"""Получаем все сервисы которые описаны в профилях"""
# путь к директории профилей
profilePath = self.clVars.Get("setup_path_profinstall")[0]
data = os.listdir(profilePath)
service = []
for fileData in data:
if os.path.isdir(os.path.join(profilePath, fileData)):
service.append(fileData)
if service:
service.remove('backup')
service.remove('apache')
return service
def applyProfilesFromService(self, service):
"""Применяем профили для данного сервиса"""
@ -184,6 +228,53 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
resSearch = self.searchLdapDN(value, self.ServicesDN, name)
return resSearch
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( _("Service %s is not stopped")%\
str("Postfix"))
flagError = True
break
if self.getRunDaemons(["dovecot"]):
textLine = self.execProg("/etc/init.d/dovecot stop")
if not ("ok" in textLine):
self.printERROR( _("Service %s is not stopped")%\
str("Dovecot"))
flagError = True
break
continue
elif self.getRunService(service):
stopService = service
textLine = self.execProg("/etc/init.d/%s stop" %(stopService))
if not ("ok" in textLine):
self.printERROR( _("Service %s is not stopped")%\
str(service))
flagError = True
break
if flagLdap:
if self.getRunService('ldap'):
textLine = self.execProg("/etc/init.d/slapd stop")
if not ("ok" in textLine):
print "END ERROR"
self.printERROR(_("Service LDAP is not stopped"))
flagError = True
if flagError:
return False
else:
return True
def getUserPassword(self, options, optDialog, optStdIn, pwDialog=False):
"""Получить пароль у пользователя
@ -213,27 +304,62 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
userPwd = pwdA
return userPwd
def getRunService(self, nameService):
"""Проверка, запущен ли сервис с данным именем"""
def getRunDaemons(self, daemons, printError=False):
"""Проверка, запущены ли демоны"""
baseDir = "/var/run"
# Проверка на запуск сервиса mail
if nameService == 'mail':
listProcess = self.execProg("ps ax",False,False)
flagRun = False
for process in listProcess:
if "postfix/master" in process:
flagRun = True
break
return flagRun
addDirDict = {"ldap":("openldap","slapd.pid"),
"samba":("samba","smbd.pid"),
"dovecot":("dovecot","master.pid")}
pidDir = baseDir + "/" + addDirDict[nameService][0]
if os.access(pidDir, os.F_OK) and os.listdir(pidDir) and\
os.path.exists(os.path.join(pidDir,addDirDict[nameService][1])):
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")}
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
else:
if not self.getRunDaemons([nameService],printError):
flagError = True
if flagError:
if printError:
self.printNotOK(_("Service") + " " +\
nameService.capitalize() + " " +\
_("started")+ " ...")
return False
return True
def unicList(self, lst):
"""Список уникальных элементов из списка не уникальных"""
@ -453,6 +579,28 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
self.conLdap = ldapObj.conLdap
return True
def dialogYesNo(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 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 createClVars(self, clVars=False):
"""Создает объект Vars"""
if not clVars:
@ -526,6 +674,8 @@ class servUnix(shareLdap):
else:
# создаем объект сервиса Samba
self.servSambaObj = servSamba(self)
# создаем объект сервиса Mail
self.servMailObj = servMail(self)
# DN, компьютеров относительно базового DN
self.relComputersDN = self.servSambaObj.relComputersDN
@ -980,7 +1130,7 @@ class servUnix(shareLdap):
return False
if self.searchUnixGroupName(userName):
self.printERROR(
_("Group name %s is found in Unix serivce")%str(userName) +\
_("Group name %s is found in Unix serivce")%str(userName)+\
" ...")
return False
@ -1036,9 +1186,11 @@ class servUnix(shareLdap):
if options.has_key('m'):
if not os.path.exists(homeDir):
if not self.createHomeDir(userName, homeDir, skelDir):
self.printERROR (_("ERROR") + ": " + _("cannot create HOME dir"))
self.printERROR (_("ERROR") + ": " +\
_("cannot create HOME dir"))
return False
self.printSUCCESS(_("Created home dir")+ " " + homeDir + " ...")
self.printSUCCESS(_("Created home dir")+ " " + homeDir+\
" ...")
self.printSUCCESS(_("Added user in Unix service") + " ...")
return True
@ -1208,13 +1360,24 @@ class servUnix(shareLdap):
"""Удаляем Unix пользователя"""
# Ищем пользователя в Samba
if self.servSambaObj.searchSambaUser(userName):
self.printERROR (_("ERROR") + ": " +\
_("Samba user %s is found in Unix service") %\
self.printERROR (_("ERROR") + ": " +\
_("User %s is found in Samba service") %\
str(userName) + " ...")
self.printWARNING(\
self.printWARNING(\
_("At first, need remove user from Samba service")
)
return False
return False
# Ищем пользователя в Mail
if self.servMailObj.searchMailUserToName(userName):
#New
self.printERROR (_("ERROR") + ": " +\
_("User %s is found in Mail service") %\
str(userName) + " ...")
#New
self.printWARNING(\
_("At first, need remove user from Mail service")
)
return False
# Ищем пользователя в Unix
resLdap = self.searchUnixUser(userName)
if not resLdap:
@ -1275,7 +1438,8 @@ class servUnix(shareLdap):
self.printSUCCESS( _("Group %s is deleted")%groupName+" ...")
return True
else:
self.printERROR(_("Can not delete group") + " " + groupName + " ...")
self.printERROR(_("Can not delete group") + " " + groupName+\
" ...")
return False
def modUserUnixServer(self,userName, options):
@ -1283,7 +1447,8 @@ class servUnix(shareLdap):
res = self.searchUnixUser(userName)
if not res:
self.printERROR(
_("User %s is not found in Unix service")%str(userName) + "...")
_("User %s is not found in Unix service")%str(userName)+\
"...")
return False
# Новые группы в которые входит пользователь
if options.has_key('G'):
@ -1402,7 +1567,7 @@ class servUnix(shareLdap):
# Изменим время последнего измения пароля пользователя
if not self.setShadowLastChange(userName):
return False
self.printSUCCESS(_("Modified user password of Unix service") +\
self.printSUCCESS(_("Modified user password of Unix service")+\
" ...")
if options.has_key('U'):
self.printSUCCESS(_("Unlocked user") + " " + str(userName) +\
@ -1466,7 +1631,7 @@ class servUnix(shareLdap):
self.printSUCCESS(_("Unlocked user") + " " + str(userName) +\
" " +_("of Unix service") + " ...")
if not options:
self.printSUCCESS(_("User password of Unix service changed") +\
self.printSUCCESS(_("User password of Unix service changed")+\
" ...")
# Изменим время последнего измения пароля пользователя
if not self.setShadowLastChange(userName):
@ -1503,7 +1668,7 @@ class servUnix(shareLdap):
self.printERROR(_("Can not delete list users from group") +\
" " + str(groupName) + " ...")
return False
modGroupName = newGroupName
modGroupName = groupName
# Изменяем имя группы
if options.has_key('n'):
newGroupName = options['n']
@ -1567,7 +1732,7 @@ class servUnix(shareLdap):
return False
if not res[0][0][1].has_key("memberUid"):
self.printERROR(
_("Member list of group %s is empty")%str(groupName)+" ...")
_("Member list of group %s is empty")%str(groupName) + " ...")
return False
memberUsers = res[0][0][1]["memberUid"]
flagError =False
@ -1587,7 +1752,6 @@ class servUnix(shareLdap):
return self.modAttrsDN(groupDN, modAttrs)
def setupUnixServer(self, options):
"""Начальная настройка Unix сервиса"""
# Принудительная установка
@ -1605,13 +1769,26 @@ class servUnix(shareLdap):
if not self.clVars.Get("soft_ldap_setup") == "yes":
self.printERROR(_("LDAP service not setup ..."))
return False
if not forceOptions:
# предупреждение при выполнении этой программы будут изменены
# конфигурационные файлы и база данных сервиса LDAP
self.printWARNING (_("WARNING") + ": " +\
_("When you execute this program the configuration files and data \
service LDAP will be changed")+ ".")
# если вы ранее использовали программу cl-setup то в дальнейшем
# можете использовать cl-backup для резервного копирования
self.printWARNING (_("If previously used the program cl-setup") +\
", " + _("you can run cl-backup for backup services"))
# если вы готовы продолжить работу программы нажмите Y если нет n
messDialog = _("If you are ready to continue the program, press Y,\
if not n")
if not self.dialogYesNo(messDialog):
return True
# Проверим запущен ли ldap
if not self.getRunService("ldap"):
self.printWARNING (_("WARNING") + ": " +\
_("LDAP service is not running") + ".")
print "1. " +_("Start LDAP service")
print " /etc/init.d/slapd start"
return True
# Запускаем LDAP сервер
if not self.runLdapServer():
return False
#Cоединение с Ldap (администратор)
shareLdap.getLdapObjInFile(self)
#self.setParamIniFile("setup_LDAP","no")
@ -1630,7 +1807,7 @@ class servUnix(shareLdap):
delDN = self.relDN
ret = self.deleteDN(delDN)
if ret:
self.printOK(_("Removed Unix DN from LDAP Database") +" ...")
self.printOK(_("Removed Unix DN from LDAP Database") + " ...")
else:
self.printERROR(\
_("Can not remove Unix DN from LDAP Database") + " ...")
@ -2082,6 +2259,24 @@ class servMail(shareLdap):
@adminConnectLdap
def addGroupMailServer(self, groupName, options):
"""Добавляет группу пользователей Mail"""
#Проверяем альтернативные почтовые адреса
modAttrs = []
if options.has_key('e'):
altMails = options['e'].split(",")
for altMail in altMails:
if "@" in altMail:
mail = altMail
else:
mail = "%s@%s.%s" %(altMail,
self.clVars.Get("net_host"),
self.clVars.Get("sys_domain"))
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((ldap.MOD_ADD, 'mailAlternateAddress', mail))
if self.searchMailGroupToName(groupName):
self.printERROR(
_("group name %s is found in Mail service")%\
@ -2112,6 +2307,11 @@ class servMail(shareLdap):
if self.ldapObj.getError():
print _("LDAP Error") + ": " + self.ldapObj.getError()
return False
#Добавляем альтернативные почтовые адреса
if options.has_key('e') and modAttrs:
DN = self.addDN("cn="+groupName, self.relGroupsDN)
if not self.modAttrsDN(DN, modAttrs):
return False
self.printSUCCESS(_("Added group in Mail service") + " ...")
return True
@ -2151,7 +2351,7 @@ class servMail(shareLdap):
if not self.modAttrsDN(DN, modAttrs):
return False
if options.has_key('l'):
self.printSUCCESS(_("Locked Mail user") + " " + str(userName) +\
self.printSUCCESS(_("Locked Mail user") + " " + str(userName)+\
" ...")
if options.has_key('u'):
self.printSUCCESS(_("Unlocked Mail user") + " " +\
@ -2273,8 +2473,8 @@ class servMail(shareLdap):
if self.searchUserToMail(mail) or\
self.searchGroupToMail(mail):
self.printERROR(
_("Alternate email address %s is found in Mail service")%\
str(mail) + " ...")
_("Alternate email address %s is found in Mail service")%\
str(mail) + " ...")
return False
modAttrs.append((ldap.MOD_ADD, 'mailAlternateAddress', mail))
if self.searchMailUserToName(userName):
@ -2311,7 +2511,7 @@ class servMail(shareLdap):
resUnix = self.servUnixObj.searchUnixUser(userName)
else:
self.printERROR(
_("User %s is not found in Unix service") % str(userName) +\
_("User %s is not found in Unix service") % str(userName)+\
" ...")
return False
self.clVars.Set("soft_ldap_user_login", userName)
@ -2375,8 +2575,8 @@ class servMail(shareLdap):
self.printERROR (_("ERROR") + ": " +\
_("LDAP server is not configured")+ ".")
self.printWARNING(_("Unix service is not setuped"))
print _("Setup Unix service")
print " cl-setup unix"
self.printWARNING(_("Setup Unix service"))
self.printWARNING(" cl-setup unix")
return False
# В случае если сервер установлен
if self.clVars.Get("soft_mail_setup") == "yes" and\
@ -2384,26 +2584,25 @@ class servMail(shareLdap):
self.printWARNING (_("WARNING") + ": " +\
_("Mail server is configured")+ ".")
return True
# Проверим запущен ли сервис Mail
if self.getRunService("mail"):
self.printWARNING (_("WARNING") + ": " +\
_("Mail service is running") + ".")
print "1. " +_("Stop Mail service")
print " /etc/init.d/postfix stop"
print "2. " + _("You can save configuration files") + " " +\
_("of Postfix in backup directory")
print "3. " + _("Restart the program")
return True
# Проверим запущен ли сервис Dovecot
if self.getRunService("dovecot"):
if not forceOptions:
# предупреждение при выполнении этой программы будут изменены
# конфигурационные файлы сервиса Mail (программы Postfix и Dovecot)
self.printWARNING (_("WARNING") + ": " +\
_("Dovecot is running") + ".")
print "1. " +_("Stop Dovecot")
print " /etc/init.d/dovecot stop"
print "2. " + _("You can save configuration files") + " " +\
_("of Dovecot in backup directory")
print "3. " + _("Restart the program")
return True
_("When you execute this program the configuration files \
service Mail will be changed (programm Postfix and Dovecot)")+ ".")
# если вы ранее использовали программу cl-setup то в дальнейшем
# можете использовать cl-backup для резервного копирования
self.printWARNING (_("If previously used the program cl-setup") +\
", " + _("you can run cl-backup for backup services"))
# если вы готовы продолжить работу программы нажмите Y если нет n
messDialog = _("If you are ready to continue the program, press Y,\
if not n")
if not self.dialogYesNo(messDialog):
return True
# останавливаем сервис Mail
if not self.stopServices(["mail"]):
return False
# Подключаемся к LDAP cерверу
if not shareLdap.getLdapObjInFile(self):
return False
@ -2417,8 +2616,9 @@ class servMail(shareLdap):
if ret:
self.printOK(_("Remove Mail DN from LDAP Database") +" ...")
else:
self.printERROR(_("Can not remove Mail DN from LDAP Database")+
" ...")
self.printERROR(\
_("Can not remove Mail DN from LDAP Database")+\
" ...")
if not ret:
return False
ldifFile = self.ldifFileBase
@ -2462,6 +2662,7 @@ class servMail(shareLdap):
self.printNotOK("Dovecot" + " " + _("start")+ " ...")
return False
self.clVars.Write("soft_mail_setup","yes")
self.printOK(_("Mail service configured") + " ...")
return True
@ -2641,6 +2842,8 @@ class servSamba(shareLdap):
self.printERROR (_("ERROR") + ": " +\
_("LDAP server is not configured")+ ".")
self.printWARNING(_("Unix service is not setuped"))
self.printWARNING (_("Setup Unix service"))
self.printWARNING(" cl-setup unix")
return False
# В случае если сервер установлен
if self.clVars.Get("soft_samba_setup") == "yes" and\
@ -2649,17 +2852,24 @@ class servSamba(shareLdap):
_("Samba server is configured")+ ".")
return True
# Проверим запущен ли сервис Samba
if self.getRunService("samba"):
if not forceOptions:
# предупреждение при выполнении этой программы будут изменены
# конфигурационные файлы сервиса Samba
self.printWARNING (_("WARNING") + ": " +\
_("The Samba service is running") + ".")
print "1. " +_("Stop Samba service")
print " /etc/init.d/samba stop"
print "2. " + _("You can save configuration files") + " " +\
_("of Samba in backup directory")
print "3. " + _("Restart the program")
return True
_("When you execute this program the configuration files \
service Samba will be changed")+ ".")
# если вы ранее использовали программу cl-setup то в дальнейшем
# можете использовать cl-backup для резервного копирования
self.printWARNING (_("If previously used the program cl-setup") +\
", " + _("you can run cl-backup for backup services"))
# если вы готовы продолжить работу программы нажмите Y если нет n
messDialog = _("If you are ready to continue the program, press Y,\
if not n")
if not self.dialogYesNo(messDialog):
return True
# останавливаем сервис Samba
if not self.stopServices(["samba"]):
return False
# Установим права 777 на директории
dirs = ["/var/calculate/winnt/profiles",
"/var/calculate/share"]
@ -2844,10 +3054,12 @@ class servLdap(shareLdap):
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"
# Все сервисы ldap должен быть последним
self.allServices = ["samba","ldap"]
# Директория для хранения профилей backup
self.backupDir = "backup"
def savePrivateFile(self, fileName, data):
"""Записать файл с правами 0600"""
@ -2937,6 +3149,8 @@ class servLdap(shareLdap):
scanPrivDirs.append(iniPath)
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:
@ -2978,33 +3192,23 @@ class servLdap(shareLdap):
if options.has_key("r"):
return self.restoreServer()
def stopServices(self, servInstalled):
"""Останавливает все сервисы поданные на вход этому методу
Входные даннные - список
"""
def startDaemons(self, service, daemons):
"""Стартует демонов"""
flagError = False
flagLdap = False
for service in servInstalled:
if service == "unix" or service == "ldap":
flagLdap = True
continue
if self.getRunService(service):
stopService = service
textLine = self.execProg("/etc/init.d/%s stop" %(stopService))
if not ("ok" in textLine):
self.printERROR( _("Service %s is not stopped")%\
str(service))
flagError = True
if flagLdap:
if self.getRunService('ldap'):
textLine = self.execProg("/etc/init.d/slapd stop")
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(_("Service LDAP is not stopped"))
self.printERROR( _("Daemon %s is not started") %daemon)
flagError = True
break
if flagError:
self.printNotOK(_("Service") + " " + service.capitalize() + " " +\
_("started")+ " ...")
return False
else:
self.printOK(_("Service") + " " + service.capitalize() + " " +\
_("started")+ " ...")
return True
@ -3012,28 +3216,21 @@ class servLdap(shareLdap):
"""Запускаем все работающие установленные сервисы"""
# находим установленные сервисы
servicePaths, servInstalled = self.getServiceSetupPathProfiles()
flagError = False
if 'ldap' in servInstalled:
if not self.getRunService('ldap'):
textLine = self.execProg("/etc/init.d/slapd start")
if not ("ok" in textLine):
self.printERROR(_("Service LDAP is not started"))
flagError = True
else:
self.printOK(_("LDAP start")+ " ...")
if not self.startDaemons('ldap',['slapd']):
return False
flagError = False
for service in servInstalled:
if service == "unix" or service == "ldap":
continue
if not self.getRunService(service):
startService = service
textLine = self.execProg("/etc/init.d/%s start"\
%(startService))
if not ("ok" in textLine):
self.printERROR( _("Service %s is not started"))
if service == "mail":
if not self.startDaemons('mail',['postfix', 'dovecot']):
flagError = True
else:
self.printOK(service.capitalize() + " " +\
_("started")+ " ...")
break
else:
if not self.startDaemons(service,[service]):
flagError = True
break
if flagError:
return False
else:
@ -3070,13 +3267,14 @@ class servLdap(shareLdap):
str(bFile))
return False
# останавливаем сервисы
self.stopServices(self.allServices)
if not self.stopServices(self.getALLServices()):
return False
# Удаляем старую базу данных
self.removeLdapDatabase()
# Создаем объект переменных clVars
self.createClVars()
# Накладываем профили (берем из папки backup)
if not self.applyProfilesFromService("backup"):
if not self.applyProfilesFromService(self.backupDir):
self.printERROR(_("Can not apply profile: backup"))
return False
# Запускаем LDAP сервер
@ -3113,6 +3311,11 @@ class servLdap(shareLdap):
if self.ldapObj.getError():
print _("LDAP Error") + ": " + self.ldapObj.getError()
return False
# Останавливаем LDAP сервер
if not self.stopLdapServer():
return False
# Удаляем временные файлы нужные для установки сервисов
self.removeTmpRestoreFile()
# Распаковываем целиком архив
if not (self.execProg("tar -C / -xjf %s"\
%(bFile)) == None):
@ -3123,27 +3326,45 @@ class servLdap(shareLdap):
os.remove(self.tmpListFile)
if os.path.exists(self.archLdifFile):
os.remove(self.archLdifFile)
# Стартуем все сервисы
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("setup_path_profinstall")[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(_("Removed previous LDAP Database") + " ...")
return True
def runLdapServer(self, opt = "start"):
"""Запускает LDAP сервер"""
textLine = self.execProg("/etc/init.d/slapd %s" %(opt))
if "ok" in textLine:
self.printOK(_("LDAP start")+ " ...")
return True
else:
self.printNotOK(_("LDAP start")+ " ...")
return False
def connectLdapServer(self):
"""Соединяемся с LDAP сервером
@ -3162,30 +3383,44 @@ class servLdap(shareLdap):
"""Начальная настройка LDAP сервиса"""
# Принудительная установка
forceOptions = False
self.createClVars()
if options.has_key("f"):
forceOptions = True
self.createClVars()
if self.clVars.Get("soft_ldap_setup") == "yes" and\
not forceOptions:
self.printWARNING (_("WARNING") + ": " +\
_("LDAP server is configured")+ ".")
return True
# Проверим запущен ли ldap
if self.getRunService("ldap"):
if not forceOptions:
# предупреждение при выполнении этой программы будут изменены
# конфигурационные файлы и база данных сервиса LDAP а также
# конфигурационные файлы установленных сервисов
self.printWARNING (_("WARNING") + ": " +\
_("The LDAP service is running") + ".")
print "1. " +_("Stop LDAP service")
print " /etc/init.d/slapd stop"
print "2. " + _("You can save configuration files") + " " +\
_("and the datebase of LDAP in backup directory")
print "3. " + _("Restart the program")
return True
# Получем путь к ini файлу
_("When you execute this program the configuration files and data \
service LDAP will be changed")+ ".")
# если вы ранее использовали программу cl-setup то в дальнейшем
# можете использовать cl-backup для резервного копирования
self.printWARNING (_("If previously used the program cl-setup") +\
", " + _("you can run cl-backup for backup services"))
# если вы готовы продолжить работу программы нажмите Y если нет n
messDialog = _("If you are ready to continue the program, press Y,\
if not n")
if not self.dialogYesNo(messDialog):
return True
# останавливаем сервисы
if not self.stopServices(self.getALLServices()):
return False
# Получим путь к ini файлу
iniFile = "/" + self.clVars.Get("sys_calculate_ini")
# Удаляем ini файл
if os.path.exists(iniFile):
os.remove(iniFile)
# Получим путь к ldap файлу
ldapFile = iniFile.replace(".ini",".ldap")
# Удаляем ldap файл
if os.path.exists(ldapFile):
os.remove(ldapFile)
self.clVars.Write("soft_ldap_setup","no")
# Первый проход
self.clVars.Set("setup_pass_parser","1",True)
@ -3216,7 +3451,7 @@ class servLdap(shareLdap):
self.printERROR(_("Can not apply profiles") +":"+ _("second pass"))
return False
# Перезапускаем LDAP сервер
if not self.runLdapServer("restart"):
if not self.restartLdapServer():
return False
# Записываем данные администратора сервера
ldapParser = iniLdapParser()
@ -3224,6 +3459,7 @@ class servLdap(shareLdap):
{"DN":self.clVars.Get("soft_ldap_admin"),
"PASS":self.clVars.Get("soft_ldap_adminpw")})
self.clVars.Write("soft_ldap_setup","yes")
self.printOK(_("LDAP service configured") +" ...")
return True
class cl_ldap(shareLdap):
@ -3371,6 +3607,14 @@ class cl_ldap(shareLdap):
'helpChapter':_("Unix service options"),
'help':_("print the gidNumber to stdout")
},
{'progAccess':(0,),
'shortOption':"e",
'longOption':"alt-emails",
'optVal':_("ALT_EMAILS"),
'helpChapter':_("Mail service options"),
#New
'help':_("set alternate email addresses for the new mail group")
},
{'progAccess':(2,),
'shortOption':"a",
'longOption':"add",
@ -4033,15 +4277,19 @@ class tsOpt(cl_base.opt):
parBeforeService дополнительные необходимые параметры перед указанным
сервисом. (например "group" или "user")
optService проверять хвост командной строки на наличие сервиса
notOptError выдавать ошибку при отсутствии опций командной строки
"""
def __init__(self, helpObj, parBeforeService, optService=True):
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])
shortOpt, longOpt = helpObj.getAllOpt('all',
helpObj.relServices[service])
else:
shortOpt,longOpt = helpObj.getAllOpt('all', helpObj.relOptions['h'])
shortOpt,longOpt = helpObj.getAllOpt('all',
helpObj.relOptions['h'])
# вызвать конструктор объекта, распознающего опции
cl_base.opt.__init__(self,shortOpt,longOpt)
@ -4074,6 +4322,13 @@ class tsOpt(cl_base.opt):
self.handlerErrOpt()
else:
self.handlerErrOpt()
# В случае остсутствия опций командной строки
if notOptError and not self.opt:
self.printErrorNotOpt()
def printErrorNotOpt(self):
"""Сообщение в случае отсутствия опций"""
print _("Not options.")
def handlerOpt(self,option,value):
# Обработчик (опция значение)

@ -234,6 +234,12 @@ class Data:
soft_ldap_admin_mailpw_hash= {'mode':"r",
'type':('param','soft'),
}
#почтовый релей
# Пример заполнения:
# value:', 212.113.122.130'
soft_ldap_mail_relay = {'mode':"r",
'type':('param','soft'),
'value':'' }
#-----------------------------------------------------
#Служебные переменные
#-----------------------------------------------------

@ -27,7 +27,7 @@ import cl_ldap
if __name__ == "__main__":
ldapObj = cl_ldap.cl_ldap("cl-groupmod")
optObj = cl_ldap.tsOpt(ldapObj,['group'])
optObj = cl_ldap.tsOpt(ldapObj,['group'],True,True)
flagError = False
if not optObj.flagHelp and optObj.params.has_key('service') and\
optObj.params.has_key('group'):

@ -28,7 +28,7 @@ import cl_ldap
if __name__ == "__main__":
ldapObj = cl_ldap.cl_ldap("cl-usermod")
optObj = cl_ldap.tsOpt(ldapObj,['user'])
optObj = cl_ldap.tsOpt(ldapObj,['user'],True,True)
flagError = False
if not optObj.flagHelp and optObj.params.has_key('service') and\
optObj.params.has_key('user'):

Loading…
Cancel
Save