develop
asamoukin 16 years ago
parent 18080c88c8
commit a845f7db67

@ -0,0 +1,21 @@
# Mail server
dn: #-soft_ldap_admin_mail-#
objectClass: top
objectClass: organizationalUnit
ou: #-soft_ldap_admin_mail_name-#
userPassword: #-soft_ldap_admin_mailpw_hash-#
# Users
dn: ou=Users,#-soft_ldap_admin_mail-#
objectClass: top
objectClass: organizationalUnit
ou: Users
# Groups
dn: ou=Groups,#-soft_ldap_admin_mail-#
objectClass: top
objectClass: organizationalUnit
ou: Groups

@ -0,0 +1,7 @@
#Mail group
dn: cn=#-soft_ldap_group_name-#,ou=Groups,#-soft_ldap_admin_mail-#
objectClass: nisNetgroup
objectClass: qmailGroup
cn: #-soft_ldap_group_name-#
mail: #-soft_ldap_group_name-#@#-net_host-#.#-sys_domain-#
mailMessageStore: #-soft_ldap_group_name-#/

@ -0,0 +1,11 @@
#Mail user
dn: uid=#-soft_ldap_user_login-#,ou=Users,#-soft_ldap_admin_mail-#
objectClass: inetOrgPerson
objectClass: qmailUser
uid: #-soft_ldap_user_login-#
cn: #-soft_ldap_user_full_name-#
sn: #-soft_ldap_user_full_name-#
accountStatus: active
mailMessageStore: #-soft_ldap_user_login-#/
mail: #-soft_ldap_user_login-#@#-net_host-#.#-sys_domain-#
userPassword: #-soft_ldap_user_pw_hash-#

@ -1,23 +1,24 @@
# Samba
dn: ou=Samba,ou=Services,#-soft_ldap_base-#
# Samba server
dn: #-soft_ldap_admin_samba-#
objectClass: top
objectClass: organizationalUnit
ou: Samba
ou: #-soft_ldap_admin_samba_name-#
userPassword: #-soft_ldap_admin_sambapw_hash-#
# Samba computers
dn: ou=Computers,ou=Samba,ou=Services,#-soft_ldap_base-#
# Users
dn: ou=Computers,#-soft_ldap_admin_samba-#
objectClass: top
objectClass: organizationalUnit
ou: Computers
# Samba Users
dn: ou=Users,ou=Samba,ou=Services,#-soft_ldap_base-#
# Users
dn: ou=Users,#-soft_ldap_admin_samba-#
objectClass: top
objectClass: organizationalUnit
ou: Users
# Samba Groups
dn: ou=Groups,ou=Samba,ou=Services,#-soft_ldap_base-#
# Groups
dn: ou=Groups,#-soft_ldap_admin_samba-#
objectClass: top
objectClass: organizationalUnit
ou: Groups

@ -1,20 +1,20 @@
# Directory Server
# Unix Server
dn: ou=Unix,ou=Services,#-soft_ldap_base-#
dn: #-soft_ldap_admin_unix-#
objectClass: top
objectClass: organizationalUnit
ou: Unix
ou: #-soft_ldap_admin_unix_name-#
userPassword: #-soft_ldap_admin_unixpw_hash-#
# Users
dn: ou=Users,ou=Unix,ou=Services,#-soft_ldap_base-#
dn: ou=Users,#-soft_ldap_admin_unix-#
objectClass: top
objectClass: organizationalUnit
ou: Users
# Groups
dn: ou=Groups,ou=Unix,ou=Services,#-soft_ldap_base-#
dn: ou=Groups,#-soft_ldap_admin_unix-#
objectClass: top
objectClass: organizationalUnit
ou: Groups

@ -1,5 +1,5 @@
# LDAP Group
dn: cn=#-soft_ldap_group_name-#,ou=Groups,ou=Unix,ou=Services,#-soft_ldap_base-#
dn: cn=#-soft_ldap_group_name-#,ou=Groups,#-soft_ldap_admin_unix-#
objectClass: posixGroup
cn: #-soft_ldap_group_name-#
gidNumber: #-soft_ldap_group_id-#

@ -1,5 +1,5 @@
# Add posix Account
dn: uid=#-soft_ldap_user_login-#,ou=Users,ou=Unix,ou=Services,#-soft_ldap_base-#
dn: uid=#-soft_ldap_user_login-#,ou=Users,#-soft_ldap_admin_unix-#
objectClass: top
objectClass: person
objectClass: posixAccount

@ -19,14 +19,62 @@ modulepath /usr/lib/openldap/modules
# Доступ к аттрибуту userPassword
access to attrs=userPassword
by self write
by dn="#-soft_ldap_admin-#" write
by * auth
by self write
by dn="#-soft_ldap_admin-#" write
by dn="#-soft_ldap_admin_samba-#" write
by dn="#-soft_ldap_admin_unix-#" write
by dn="#-soft_ldap_admin_mail-#" read
by * auth
# Доступ к пользователю только для просмотра
access to dn.base="#-soft_ldap_bind-#"
by dn="#-soft_ldap_admin-#" write
by dn="#-soft_ldap_bind-#" read
by * none
# Доступ к администратору сервера LDAP
access to dn.base="#-soft_ldap_admin-#"
by dn="#-soft_ldap_admin-#" write
by * none
# Доступ к ветке Samba
access to dn.regex=".*#-soft_ldap_admin_samba-#$"
by dn="#-soft_ldap_admin-#" write
by dn="#-soft_ldap_admin_samba-#" write
by dn="#-soft_ldap_admin_unix-#" write
by dn="#-soft_ldap_bind-#" read
by * none
# Доступ к ветке Unix
access to dn.regex=".*#-soft_ldap_admin_unix-#$"
by dn="#-soft_ldap_admin-#" write
by dn="#-soft_ldap_admin_samba-#" write
by dn="#-soft_ldap_admin_unix-#" write
by dn="#-soft_ldap_bind-#" read
by * none
# Доступ к ветке Mail
access to dn.regex=".*#-soft_ldap_admin_mail-#$"
by dn="#-soft_ldap_admin-#" write
by dn="#-soft_ldap_admin_mail-#" read
by * none
# Доступ к остальным веткам сервисов
access to dn.regex=".*ou=([^,]+),#-soft_ldap_sevices_dn-#$"
by dn="#-soft_ldap_admin-#" write
by dn.regex="ou=$1,#-soft_ldap_sevices_dn-#" write
by * none
# Закрываем доступ к веткам
access to dn.regex=".*,#-soft_ldap_sevices_dn-#"
by dn="#-soft_ldap_admin-#" write
by * none
# Доступ ко всем аттрибутам
access to *
by dn="#-soft_ldap_admin-#" write
by self write
by * read
by dn="#-soft_ldap_admin-#" write
by self write
by * read
# Доступ по умолчанию только для чтения
defaultaccess read

@ -0,0 +1,76 @@
# Calculate format=dovecot
# This file is opened as root, so it should be owned by root and mode 0600.
#
# http://wiki.dovecot.org/AuthDatabase/LDAP
#
# Space separated list of LDAP hosts to use. host:port is allowed too.
hosts = #-net_host-#
# Distinguished Name - the username used to login to the LDAP server
dn = #-soft_ldap_admin_mail-#
# Password for LDAP server
dnpass = #-soft_ldap_admin_mailpw-#
auth_bind = yes
auth_bind_userdn = uid=%u,ou=Users,#-soft_ldap_admin_mail-#
# LDAP protocol version to use. Likely 2 or 3.
ldap_version = 2
# LDAP base. %variables can be used here.
#base = uid=someone, dc=foo, dc=bar, dc=org
base = ou=Users,#-soft_ldap_admin_mail-#
# Dereference: never, searching, finding, always
#deref = never
# Search scope: base, onelevel, subtree
scope = subtree
# User attributes are given in LDAP-name=dovecot-internal-name list. The
# internal names are:
# uid - System UID
# gid - System GID
# home - Home directory
# mail - Mail location
#
# There are also other special fields which can be returned, see
# http://wiki.dovecot.org/UserDatabase/ExtraFields
#user_attrs = homeDirectory=home,uidNumber=uid,gidNumber=gid
# Filter for user lookup. Some variables can be used (see
# http://wiki.dovecot.org/Variables for full list):
# %u - username
# %n - user part in user@domain, same as %u if there's no domain
# %d - domain part in user@domain, empty if user there's no domain
#user_filter = (&(objectClass=posixAccount)(uid=%u))
user_filter = (&(objectClass=qmailUser)(uid=%u))
# Password checking attributes:
# user: Virtual user name (user@domain), if you wish to change the
# user-given username to something else
# password: Password, may optionally start with {type}, eg. {crypt}
# There are also other special fields which can be returned, see
# http://wiki.dovecot.org/PasswordDatabase/ExtraFields
#pass_attrs = uid=user,userPassword=password
# If you wish to avoid two LDAP lookups (passdb + userdb), you can use
# userdb prefetch instead of userdb ldap in dovecot.conf. In that case you'll
# also have to include user_attrs in pass_attrs field prefixed with "userdb_"
# string. For example:
#pass_attrs = uid=user,userPassword=password,homeDirectory=userdb_home,uidNumber=userdb_uid,gidNumber=userdb_gid
# Filter for password lookups
pass_filter = (&(objectClass=qmailUser)(uid=%u))
# Default password scheme. "{scheme}" before password overrides this.
# List of supported schemes is in: http://wiki.dovecot.org/Authentication
#default_pass_scheme = CRYPT
default_pass_scheme = SSHA
# You can use same UID and GID for all user accounts if you really want to.
# If the UID/GID is still found from LDAP reply, it overrides these values.

@ -0,0 +1,95 @@
# Calculate format=dovecot
## Dovecot configuration file
# IP or host address where to listen in for connections. It's not currently
# possible to specify multiple addresses. "*" listens in all IPv4 interfaces.
# "[::]" listens in all IPv6 interfaces, but may also listen in all IPv4
# interfaces depending on the operating system.
#
# If you want to specify ports for each service, you will need to configure
# these settings inside the protocol imap/pop3 { ... } section, so you can
# specify different ports for IMAP/POP3. For example:
# protocol imap {
# listen = *:10143
# ssl_listen = *:10943
# ..
# }
# protocol pop3 {
# listen = *:10100
# ..
# }
listen = [::]
# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert_file = /etc/ssl/dovecot/server.pem
ssl_key_file = /etc/ssl/dovecot/server.key
##
## Mailbox locations and namespaces
##
# Location for users' mailboxes. This is the same as the old default_mail_env
# setting. The default is empty, which means that Dovecot tries to find the
# mailboxes automatically. This won't work if the user doesn't have any mail
# yet, so you should explicitly tell Dovecot the full location.
#
# If you're using mbox, giving a path to the INBOX file (eg. /var/mail/%u)
# isn't enough. You'll also need to tell Dovecot where the other mailboxes are
# kept. This is called the "root mail directory", and it must be the first
# path given in the mail_location setting.
#
# There are a few special variables you can use, eg.:
#
# %u - username
# %n - user part in user@domain, same as %u if there's no domain
# %d - domain part in user@domain, empty if there's no domain
# %h - home directory
#
# See doc/wiki/Variables.txt for full list. Some examples:
#
# mail_location = maildir:~/Maildir
# mail_location = mbox:~/mail:INBOX=/var/mail/%u
# mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
# <doc/wiki/MailLocation.txt>
#
#mail_location = maildir:~/.maildir
mail_location = maildir:/var/calculate/mail/%u
auth default {
# Space separated list of wanted authentication mechanisms:
# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi
# NOTE: See also disable_plaintext_auth setting.
mechanisms = plain
!passdb pam {
args = "*"
}
# LDAP database <doc/wiki/AuthDatabase.LDAP.txt>
passdb ldap {
# Path for LDAP configuration file, see doc/dovecot-ldap-example.conf
args = /etc/dovecot/dovecot-ldap.conf
}
# LDAP database <doc/wiki/AuthDatabase.LDAP.txt>
#userdb ldap {
# # Path for LDAP configuration file, see doc/dovecot-ldap-example.conf
# args = /etc/dovecot/dovecot-ldap.conf
#}
# User to use for the process. This user needs access to only user and
# password databases, nothing else. Only shadow and pam authentication
# requires roots, so use something else if possible. Note that passwd
# authentication with BSDs internally accesses shadow files, which also
# requires roots. Note that this user is NOT used to access mails.
# That user is specified by userdb above.
user = root
}

@ -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 ) )

@ -0,0 +1,2 @@
# Calculate format=ldap
+include /etc/openldap/schema/qmail.schema

@ -0,0 +1,10 @@
# Calculate format=postfix
server_host = #-net_host-#
server_port = 389
bind = yes
bind_dn = #-soft_ldap_admin_mail-#
bind_pw = #-soft_ldap_admin_mailpw-#
search_base = ou=Groups,#-soft_ldap_admin_mail-#
query_filter = (|(mail=%s)(mailAlternateAddress=%s))
result_attribute = rfc822member
#result_filter = %s,%u@cds.local.calculate.ru

@ -0,0 +1,9 @@
# Calculate format=postfix
server_host = #-net_host-#
server_port = 389
bind = yes
bind_dn = #-soft_ldap_admin_mail-#
bind_pw = #-soft_ldap_admin_mailpw-#
search_base = #-soft_ldap_admin_mail-#
query_filter = (&(|(mail=%s)(mailAlternateAddress=%s))(AccountStatus=active))
result_attribute = mail

@ -0,0 +1,9 @@
# Calculate format=postfix
server_host = #-net_host-#
server_port = 389
bind = yes
bind_dn = #-soft_ldap_admin_mail-#
bind_pw = #-soft_ldap_admin_mailpw-#
search_base = ou=Groups,#-soft_ldap_admin_mail-#
query_filter = (|(mail=%s)(mailAlternateAddress=%s))
result_attribute = cn

@ -0,0 +1,9 @@
# Calculate format=postfix
server_host = #-net_host-#
server_port = 389
bind = yes
bind_dn = #-soft_ldap_admin_mail-#
bind_pw = #-soft_ldap_admin_mailpw-#
search_base = ou=Users,#-soft_ldap_admin_mail-#
query_filter = (&(|(mail=%s)(mailAlternateAddress=%s))(AccountStatus=active))
result_attribute = uid

@ -0,0 +1,274 @@
# Calculate format=postfix
#Документация на русском:
#http://www.elantech.ru/docs/postfix-docs-ru/
#Рабочая директория Postfix. То место, где временно сохраняется
#вся приходящая почта до процесса доставки.
queue_directory = /var/spool/postfix
#Путь для всех выполняемых программ почтового сервера.
command_directory = /usr/sbin
# The daemon_directory parameter specifies the location of all Postfix
# daemon programs (i.e. programs listed in the master.cf file). This
# directory must be owned by root.
#
daemon_directory = /usr/lib/postfix
#Определяет местоположение всех программ системы postfix.
mail_owner = postfix
#Имя хоста
#myhostname = cds.local.calculate.ru
#Определяет домен данного компьютера. По умолчанию преобразуется из myhostname
#mydomain = local.calculate.ru
#Это имя добавляется локально посланным сообщениям.
#Например: если вы посылаете сообщение от пользователя root,
#то он его получит таким: from root@mta1.domain.com.
#myorigin = $mydomain
#Эта директива указывает postfix что он должен принять почту для
#пользователя этого домена. Пожалуйста, учтите, что данная директива НЕ
#может быть использована для витруального домена или для запасного MX
#хоста. В нашем случае, мы сделаем так, чтобы принималась почта для
#пользователей следующих доменов:
mydestination = $myhostname, localhost.$mydomain, $mydomain
#Разрешенные адреса получателей указаны в параметре virtual_alias_maps. SMTP #сервер Postfix отклоняет недопустимые адреса получателей с сообщением "User #unknown in virtual alias table (Пользователь неизвестен в таблице #виртуальных алиасов)".
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf, ldap:/etc/postfix/ldap-aliases-gr.cf
# The unknown_local_recipient_reject_code specifies the SMTP server
# response code when a recipient domain matches $mydestination or
# ${proxy,inet}_interfaces, while $local_recipient_maps is non-empty
# and the recipient address or address local-part is not found.
unknown_local_recipient_reject_code = 550
#Эта директива указывает postfix какие сети он должен считать
#локальными. Другими словами, компьютеры, соединяющиеся из этих сетей
#будут иметь возможность релея почтовых сообщений. В нашем случае мы
#прописываем следующие сети 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
#По умолчанию, Postfix пытается посылать почту в Internet напрямую. В зависимости
#от окружения, в котором функционирует Ваш почтовый сервер, это может быть
#невозможно или нежелательно. Например, Ваша машина может быть отключена от
#Internet-а в нерабочее время, она может быть закрыта файрволлом, Ваш провайдер
#может запрещать пересылку почты в Internet напрямую. В таких случаях Вам
#необходимо настроить Postfix на пересылку писем через другой почтовый сервер
#(relay host).
#Вариант, заключенный в квадратные скобки [], заставляет Postfix
#не предпринимать поиск записей DNS MX.
#по умолчанию: посылать в Internet напрямую
#relayhost = [mail.$mydomain]
# The alias_maps parameter specifies the list of alias databases used
# by the local delivery agent. The default list is system dependent.
alias_maps = hash:/etc/mail/aliases
# The alias_database parameter specifies the alias database(s) that
# are built with "newaliases" or "sendmail -bi". This is a separate
# configuration parameter, because alias_maps (see above) may specify
# tables that are not necessarily all under control by Postfix.
#
# If you change the alias database, run "postalias /etc/aliases" (or
# wherever your system stores the mail alias file), or simply run
# "newaliases" to build the necessary DBM or DB file.
#alias_database = hash:/etc/mail/aliases, ldap:/etc/postfix/ldap-aliases.cf
alias_database = hash:/etc/mail/aliases
#Эта директива указывает postfix где ему искать имена локальных
#пользователей для доставки им почты. Здесь ничего не надо указывать
#(не удаляйте саму директиву - это может вызвать ошибки).
local_recipient_maps = ldap:/etc/postfix/ldap-recipient.cf, ldap:/etc/postfix/ldap-recipient-gr.cf
#local_recipient_maps = hash:/etc/postfix/recipient
# DELIVERY TO MAILBOX
# The home_mailbox parameter specifies the optional pathname of a
# mailbox file relative to a user's home directory. The default
# mailbox file is /var/spool/mail/user or /var/mail/user. Specify
# "Maildir/" for qmail-style delivery (the / is required).
#home_mailbox = Maildir/
# The mail_spool_directory parameter specifies the directory where
# UNIX-style mailboxes are kept. The default setting depends on the
# system type.
#mail_spool_directory = /var/spool/mail
#Эта директива указывает адрес назначения для недоставленной
#(undeliverable) почты для адресата с пустым полем: от (from <> ). В
#нашем случае - это MAILER-DAEMON (а еще лучше послать на /dev/null)
empty_address_recipient = MAILER-DAEMON
#Эта директива запрещает принимать какие-либо сообщения, если
#пространства на жестком диске осталось менее чем 200Mb. This number
#should be 1.5 times the message_size_limit or you will get an error
#message.
queue_minfree = 200000000
#Эта директива указывает максимальный размер сообщения. Сообщения,
#размером более чем 100Mb будут отклоняться.
message_size_limit = 100000000
#Эта директива указывает максимальный размер локального почтового
#ящика. Установим в 1гб
mailbox_size_limit = 1000000000
#Сообщение сервера, подключившемуся компьютеру. Чем меньше информации
#при этом будет выдано о сервере, тем лучше... в целях безопасности.
smtpd_banner = $myhostname ESMTP
# PARALLEL DELIVERY TO THE SAME DESTINATION
# How many parallel deliveries to the same user or domain? With local
# delivery, it does not make sense to do massively parallel delivery
# to the same user, because mailbox updates must happen sequentially,
# and expensive pipelines in .forward files can cause disasters when
# too many are run at the same time. With SMTP deliveries, 10
# simultaneous connections to the same domain could be sufficient to
# raise eyebrows.
#
# Each message delivery transport has its XXX_destination_concurrency_limit
# parameter. The default is $default_destination_concurrency_limit for
# most delivery transports. For the local delivery agent the default is 2.
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 20
# Отключает SMTP команду VRFY. В результате чего, невозможно определить
# существование определенного ящика. Данная техника (применение команды
# VRFY) используется спамерами для сбора имен почтовых ящиков.
disable_vrfy_command = yes
# Скрываем отображение имени таблицы получателей в ответе "User unknown"
# yes: User unknown in virtual mailbox table
# no: User unknown
show_user_unknown_table_name = no
# Чтобы проверка шла в порядке заданном нами
smtpd_delay_reject = yes
#Эти директивы используются для запрещения доступа к Postfix
#Принимаем письма:
# от авторизованных клиентов
# принимать от локальных сетей
# не принимаем от тех кто посылает почту не по назначению
# когда когда адрес получателя не соответсвует RFC
# не общаться с почтовыми системами, которые не знают имени своего хоста
smtpd_sender_restrictions =
#smtpd_recipient_restrictions =
smtpd_client_restrictions =
#smtpd_recipient_restrictions =
# permit_sasl_authenticated,
# permit_mynetworks,
# reject_unauth_destination,
# reject_non_fqdn_recipient,
# reject_unknown_hostname
#проверяем клиент запросивший соединение
#smtpd_client_restrictions =
# permit_mynetworks,
# reject_unknown_client
#проверяем HELO если нам его передали
#smtpd_helo_restrictions =
# permit_mynetworks,
# reject_invalid_hostname
#проверяем почтовый адрес отправителя
#smtpd_sender_restrictions =
# permit_mynetworks,
# reject_unauth_destination,
# reject_unknown_sender_domain,
# reject_non_fqdn_sender
#проверяем получателя
#smtpd_recipient_restrictions =
# permit_mynetworks,
# permit_sasl_authenticated,
# reject_unauth_destination,
# check_recipient_maps,
# reject_unknown_recipient_domain,
# reject_non_fqdn_recipient
# не принимать почту от доменов, которые не существуют
#smtpd_sender_restrictions = reject_unknown_sender_domain
#не принимать почту от доменов, которые не существуют
#smtpd_helo_restrictions = reject_unknown_hostname
# максимальное время жизни письма.
# если в течении 5 часов сервер не достучится сервера адресата.
# письмо вернется отправителю. По умолчанию стоит 5 дней.
maximal_queue_lifetime = 3h
bounce_queue_lifetime = 1h
#Эта директива описывает все виды служебных сообщений посылаемых
#Postfix на postmaster аккаунт.
#вот список возможных опций :
# bounce: отсылает постмастеру копию заголовка непринятого сообщения.
# 2bounce: отсылает недоставленную непринятую (undelivered) почту постмастеру.
# delay: отсылает постмастеру копию заголовка отложенной (delayed) почты.
# policy: отсылает постмастеру описание SMTP сессии в том случае, если
# клиентское соединение было отвергнуто в соотвествии с правилами
# политики. Если вы разрешите эту опцию, вы будете получать по одному
# сообщению на каждое спам сообщение - это неплохо для отладки, но плохо
# сказывается на производительности
# protocol: отсылает постмастеру описание SMTP сессии в случае если
# произощла ошибка со стороны клиента или сервера.
# resource: информирует постмастера о невозможности доставки почты в
# случае нехватки ресурсов.
# software: информирует постмастера о невозможности доставки почты в
# случае проблемы с программным обеспечением.
notify_classes = protocol, resource, software
#Пути программ
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /etc/postfix
readme_directory = no
#Например, если для службы безопасности
#требуеться копировать всю почту в отдельный ящик:
#В данном примере backup
#always_bcc = backup@mydomain.ru
#Особенности настройки host.calculate.ru
#setgid_group = maildrop
#content_filter = smtp-amavis:[127.0.0.1]:10024
#Необходимо для функционирования антивируса - clamsmtp
#Первая строка говорит postfix'у о том, что необходимо пересылать всю почту через сервис (фильтр) 'scan'
#на 10025-ый порт, который, как раз, открыт clamsmtpd(или иной фильтр)
#Вторая строчка говорит о том, чтобы postfix не делал никаких манипуляций с адресами до того,
#как они дойдут до content_filter. Так что получается, что фильтр работает с реальными почтовыми
#адресами, а не с результатами перевода в виртуальные псевдонимы, маскарадингом и т.п.
#content_filter = scan:127.0.0.1:10025
#receive_override_options = no_address_mappings
#mailbox_command = /usr/bin/procmail -a $USER
#mailbox_command = /usr/bin/procmail
mailbox_command = /usr/bin/procmail -m /etc/procmailrc

@ -0,0 +1,5 @@
# Calculate format=procmail
# Use maildir-style mailbox in user's home directory
DEFAULT=/var/calculate/mail/$LOGNAME/
MAILDIR=$DEFAULT

@ -1,2 +1,2 @@
# Calculate format=ldap
+nss_base_passwd ou=Computers,ou=Samba,ou=Services,#-soft_ldap_base-#?one
+nss_base_passwd ou=Computers,#-soft_ldap_admin_samba-#?one

@ -1,6 +1,7 @@
# Calculate format=ldap
+include /etc/openldap/schema/samba.schema
#Доступ к samba аттрибутам
# Доступ к аттрибутам Samba
+access to attrs=sambaLMPassword,sambaNTPassword
by dn="#-soft_ldap_admin-#" write
by * none
by dn="#-soft_ldap_admin-#" write
by dn="#-soft_ldap_admin_samba-#" write
by * none

@ -27,8 +27,8 @@
passdb backend = ldapsam:ldap://127.0.0.1/
ldap filter = (&(objectclass=sambaSamAccount)(uid=%u))
ldap admin dn = #-soft_ldap_admin-#
ldap suffix = ou=Samba,ou=Services,#-soft_ldap_base-#
ldap admin dn = #-soft_ldap_admin_samba-#
ldap suffix = #-soft_ldap_admin_samba-#
ldap group suffix = ou=Groups
ldap user suffix = ou=Users
ldap machine suffix = ou=Computers

@ -1,7 +1,7 @@
# Calculate format=ldap
host localhost
base #-soft_ldap_base-#
rootbinddn #-soft_ldap_admin-#
base #-soft_ldap_sevices_dn-#
rootbinddn #-soft_ldap_admin_unix-#
binddn #-soft_ldap_bind-#
bindpw #-soft_ldap_bindpw-#
port 389
@ -9,8 +9,8 @@ ldap_version 3
bind_policy soft
#ускорим ограничив область поиска
nss_base_passwd ou=Users,ou=Unix,ou=Services,#-soft_ldap_base-#?one
nss_base_shadow ou=Users,ou=Unix,ou=Services,#-soft_ldap_base-#?one
nss_base_group ou=Groups,ou=Unix,ou=Services,#-soft_ldap_base-#?one
nss_base_passwd ou=Users,#-soft_ldap_admin_unix-#?one
nss_base_shadow ou=Users,#-soft_ldap_admin_unix-#?one
nss_base_group ou=Groups,#-soft_ldap_admin_unix-#?one
pam_password md5

@ -41,9 +41,11 @@ tr.setLanguage(sys.modules[__name__])
pcs = cl_utils.prettyColumnStr
# Декоратор соединения с LDAP и получения Vars
def foundConnect(fun):
"""Проверка установки необходимых переменных (декоратор)"""
def adminConnectLdap(fun):
"""Cоединение с LDAP администратором сервиса (декоратор)
соединение с LDAP и проверка установки необходимых переменных
"""
def ret (self, *arg, **argv):
flagError = False
if not self.clVars:
@ -162,6 +164,20 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
# DN сервисов относительно базового
self.ServicesDN = "ou=Services"
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('=')
@ -200,26 +216,28 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
def getRunService(self, nameService):
"""Проверка, запущен ли сервис с данным именем"""
baseDir = "/var/run"
addDirDict = {"ldap":"openldap",
"samba":"samba"}
pidDir = baseDir + "/" + addDirDict[nameService]
if os.access(pidDir, os.F_OK) and os.listdir(pidDir):
# Проверка на запуск сервиса 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])):
return True
else:
return False
def unicList(self, lst):
"""Список уникальных элементов из списка не уникальных"""
if len(lst) > 1:
lst.sort()
outLst = []
prVal = False
for val in lst:
if prVal != val:
outLst.append(val)
prVal = val
return outLst
return lst
return list(set(lst)|set([]))
def addDN(self, *arg):
"""Складывает текстовые элементы DN"""
@ -249,7 +267,7 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
os.lchown(linkCh[1], uid, gid)
return True
@foundConnect
@adminConnectLdap
def modAttrsDN(self, relDN, modAttrs):
"""Модифицирует аттрибуты DN"""
DN = self.addDN(relDN,self.baseDN)
@ -261,7 +279,7 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
return False
return True
@foundConnect
@adminConnectLdap
def modifyElemDN(self, relDN, newFirstDn):
"""Изменяет основной элемент DN (uid, cn и др.)"""
DN = self.addDN(relDN,self.baseDN)
@ -272,7 +290,7 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
return False
return True
@foundConnect
@adminConnectLdap
def delDN(self, relDN):
DN = self.addDN(relDN,self.baseDN)
try:
@ -297,7 +315,7 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
return max(lst)
return False
@foundConnect
@adminConnectLdap
def fullElementDNtoText(self, relDN):
"""Выводит все внутренние элементы DN виде текста"""
DN = self.addDN(relDN, self.baseDN)
@ -333,12 +351,10 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
outText += "\n"
return outText
@foundConnect
@adminConnectLdap
def deleteDN(self, relDelDN):
"""Удаляет DN и все внутренние элементы"""
delDN = self.addDN(relDelDN, self.baseDN)
print "delDN", delDN
print self.conLdap
delListDN=[]
try:
dnList = self.conLdap.search_s(delDN,
@ -419,14 +435,14 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
return max(lst)
return False
def getLdapObjInFile(self):
def getLdapObjInFile(self, part="admin"):
"""Получаем объект ldapFunction из ini файла
В выходном объекте есть соединение с LDAP сервером: self.conLdap
"""
ldapParser = iniLdapParser()
adminDn = ldapParser.getVar("admin","DN")
adminPw = ldapParser.getVar("admin","PASS")
adminDn = ldapParser.getVar(part,"DN")
adminPw = ldapParser.getVar(part,"PASS")
ldapObj = ldapFunction(adminDn, adminPw)
if ldapObj.getError():
self.printERROR (_("LDAP connect error") + ": " +\
@ -447,7 +463,7 @@ class shareLdap(imp_cl_err, imp_cl_xml, imp_cl_help, imp_cl_smcon):
self.clVars = clVars
return True
@foundConnect
@adminConnectLdap
def searchLdapDN(self, name, relDN, attr, retAttr=None):
"""Находит DN в LDAP"""
DN = self.addDN(relDN,self.baseDN)
@ -513,6 +529,10 @@ class servUnix(shareLdap):
# DN, компьютеров относительно базового DN
self.relComputersDN = self.servSambaObj.relComputersDN
def getLdapObjInFile(self):
"""Cоединение с LDAP администратором Samba сервиса"""
return shareLdap.getLdapObjInFile(self, "unix")
def createHomeDir(self, userName, homeDir, skelDir):
"""Создаем домашнюю директорию пользователя
@ -747,7 +767,7 @@ class servUnix(shareLdap):
findUsers.append(userName)
return findUsers
@foundConnect
@adminConnectLdap
def addGroupUnixServer(self, groupName, options):
"""Добавляет группу пользователей LDAP"""
# Если группа существует выходим без ошибки
@ -811,7 +831,7 @@ class servUnix(shareLdap):
self.printSUCCESS(_("Add group in unix service") + " ...")
return True
@foundConnect
@adminConnectLdap
def addMachineLdapServer(self, machineName, options):
"""Добавляет LDAP машину в LDAP-сервер"""
machineLogin = machineName.replace('$','') + "$"
@ -859,7 +879,7 @@ class servUnix(shareLdap):
self.printSUCCESS(_("Add machine ..."))
return True
@foundConnect
@adminConnectLdap
def addUserUnixServer(self,userName,options):
"""Добавляет LDAP пользователя в LDAP-сервер"""
# id нового пользователя
@ -1542,11 +1562,13 @@ class servUnix(shareLdap):
return self.modAttrsDN(groupDN, modAttrs)
@foundConnect
def setupUnixServer(self, options):
"""Начальная настройка LDAP сервиса"""
# Принудительная установка
forceOptions = False
# Cоздаем объект переменные
self.createClVars()
if options.has_key("f"):
forceOptions = True
# В случае если сервер установлен
@ -1565,15 +1587,16 @@ class servUnix(shareLdap):
print "1. " +_("Start the LDAP service")
print " /etc/init.d/slapd start"
return True
#Cоединение с Ldap (администратор)
shareLdap.getLdapObjInFile(self)
#self.setParamIniFile("setup_LDAP","no")
self.clVars.Write("soft_unix_setup","no")
# Для тестовых целей устанавливаем директорию инсталяции
#clVars.Set("setup_path_install","/tmp/test1/")
# Cоздаем объект профиль устанавливая директорию ldap для
# файлов профилей
clProf = cl_profile.profile(self.clVars,"unix")
# Объединяем профили
clProf.applyProfiles()
if not self.applyProfilesFromService('unix'):
return False
# Удаляем предыдущую ветку сервиса Unix
servicesDN = self.relDN
resSearch = self.searchService()
@ -1595,8 +1618,13 @@ class servUnix(shareLdap):
print _("LDAP Error") + ": " + self.ldapObj.getError()
return False
self.printOK(_("Add ldif file ..."))
self.clVars.Write("soft_unix_setup","yes")
# Записываем данные администратора сервиса Unix
ldapParser = iniLdapParser()
ldapParser.setVar("unix",
{"DN":self.clVars.Get("soft_ldap_admin_unix"),
"PASS":self.clVars.Get("soft_ldap_admin_unixpw")})
self.printOK(_("Unix service configured ..."))
self.clVars.Write("soft_unix_setup","yes")
return True
def setShadowLastChange(self, userName):
@ -1610,6 +1638,220 @@ class servUnix(shareLdap):
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"
# Алгоритм шифрования пароля для Mail пользователя
self.userCrypt = "{SSHA}"
# Директория где хранятся письма
self.mailLocation = "/var/calculate/mail"
if unixObj:
# получаем объект сервиса Unix
self.servUnixObj = unixObj
else:
# создаем объект сервиса Unix
self.servUnixObj = servUnix()
def createMailDir(self, userName, uid, gid):
"""Создание пользовательской директории для почты"""
mailDir = os.path.join(self.mailLocation,userName)
if not os.path.exists(mailDir):
os.makedirs(mailDir)
os.chown(mailDir,uid,gid)
return True
def searchMailUser(self, userName):
"""Находит пользователя сервиса Unix"""
resSearch = self.searchLdapDN(userName, self.relUsersDN, "uid")
return resSearch
@adminConnectLdap
def addUserMailServer(self, userName, options):
"""Добавляет почтового пользователя в LDAP-сервер"""
resUnix = self.servUnixObj.searchUnixUser(userName)
resPwd = self.servUnixObj.searchPasswdUser(userName)
if not (resUnix or resPwd):
if options.has_key('f'):
# Добавим пользователя LDAP
optUnix = {}
# Группа пользователя
if options.has_key('g'):
optUnix['g'] = options['g']
# Полное имя пользователя
if options.has_key('c'):
optUnix['с'] = options['c']
if not self.servUnixObj.addUserUnixServer(userName, optUnix):
return False
else:
self.printERROR(_("Not found user") + " " + str(userName) +\
" " + _("in unix service" + " ..."))
return False
if self.searchMailUser(userName):
self.printERROR(_("User exists in LDAP"))
return False
self.clVars.Set("soft_ldap_user_login", userName)
#Полное имя пользователя
fullNameUser = self.servUnixObj.fullNameUser
if options.has_key('c'):
fullNameUser = options['c']
else:
resUnix = self.servUnixObj.searchUnixUser(userName)
if resUnix and resUnix[0][0][1].has_key('gecos'):
fullNameUser = resUnix[0][0][1]['gecos'][0]
self.clVars.Set("soft_ldap_user_full_name",fullNameUser)
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("soft_ldap_user_pw_hash",userPwdHash)
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()
return False
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(_("Not found uid and gid user"))
return False
self.createMailDir(userName, uid, gid)
print "OK"
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("soft_unix_setup") != "yes":
self.printERROR (_("ERROR") + ": " +\
_("LDAP server is not configured")+ ".")
self.printWARNING(_("Not setup service Unix"))
return False
# В случае если сервер установлен
if self.clVars.Get("soft_mail_setup") == "yes" and\
not forceOptions:
self.printWARNING (_("WARNING") + ": " +\
_("Mail server is configured")+ ".")
return True
# Проверим запущен ли сервис Mail
if self.getRunService("mail"):
self.printWARNING (_("WARNING") + ": " +\
_("The Mail service is running") + ".")
print "1. " +_("Stop the Mail service")
print " /etc/init.d/postfix stop"
print "2. " + _("You can save configuration files \
Postfix in backup directory")
print "3. " + _("Restart the program")
return True
# Проверим запущен ли сервис Dovecot
if self.getRunService("dovecot"):
self.printWARNING (_("WARNING") + ": " +\
_("The Dovecot is running") + ".")
print "1. " +_("Stop the Dovecot")
print " /etc/init.d/dovecot stop"
print "2. " + _("You can save configuration files \
Dovecot in backup directory")
print "3. " + _("Restart the program")
return True
# Подключаемся к LDAP cерверу
if not shareLdap.getLdapObjInFile(self):
return False
self.clVars.Write("soft_mail_setup","no")
# Находим в LDAP Mail сервис
resSearch = self.searchService()
ret = True
if resSearch:
delDN = self.relDN
ret = self.deleteDN(delDN)
if ret:
self.printOK(_("Remove Mail DN in LDAP Database ..."))
else:
self.printERROR(_("Not remove Mail DN in 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()
return False
self.clVars.Write("soft_samba_setup","no")
# Cоздаем объект профиль устанавливая директорию samba для
# файлов профилей
if not self.applyProfilesFromService('mail'):
return False
textLine = self.execProg("/etc/init.d/slapd restart")
if "ok" in textLine:
self.printOK("LDAP" + " " + _("restart")+ " ...")
else:
self.printNotOK("LDAP" + " " + _("restart")+ " ...")
return False
# Записываем данные администратора сервиса Mail
ldapParser = iniLdapParser()
ldapParser.setVar("mail",
{"DN":self.clVars.Get("soft_ldap_admin_mail"),
"PASS":self.clVars.Get("soft_ldap_admin_mailpw")})
self.printOK(_("Add ldif file ..."))
textLine = self.execProg("newaliases")
if not (textLine == None):
self.printERROR(_("Not create Postfix aliases") + " ...")
return False
textLine = self.execProg("/etc/init.d/postfix start")
if "ok" in textLine:
self.printOK("Postfix" + " " + _("start")+ " ...")
else:
self.printNotOK("Postfix" + " " + _("start")+ " ...")
return False
textLine = self.execProg("/etc/init.d/dovecot start")
if "ok" in textLine:
self.printOK("Dovecot" + " " + _("start")+ " ...")
else:
self.printNotOK("Dovecot" + " " + _("start")+ " ...")
return False
self.clVars.Write("soft_mail_setup","yes")
return True
class servSamba(shareLdap):
"""Методы севисa Samba"""
def __init__(self, unixObj=False):
@ -1634,6 +1876,10 @@ class servSamba(shareLdap):
# создаем объект сервиса Unix
self.servUnixObj = servUnix(self)
def getLdapObjInFile(self):
"""Cоединение с LDAP администратором Samba сервиса"""
return shareLdap.getLdapObjInFile(self, "samba")
def delUserSambaServer(self, userName, options):
"""Удаляем Samba пользователя"""
if options.has_key('r'):
@ -1676,7 +1922,7 @@ class servSamba(shareLdap):
str(delUser) + " ...")
return True
@foundConnect
@adminConnectLdap
def addUserSambaServer(self, userName, options):
"""Добавляет LDAP пользователя в LDAP-сервер"""
# Добавление машины samba
@ -1687,10 +1933,9 @@ class servSamba(shareLdap):
return False
resSearch = self.servUnixObj.searchUnixUser(userName)
if not resSearch:
# Cоздание пользователя Unix
if options.has_key('f'):
resSearch = self.servUnixObj.searchPasswdUser(userName)
else:
resSearch = self.servUnixObj.searchPasswdUser(userName)
# создание пользователя Unix опция f
if not resSearch and not options.has_key('f'):
self.printERROR(_("Not found user") + " " + str(userName) +\
" " + _("in unix service" + " ..."))
return False
@ -1708,9 +1953,14 @@ class servSamba(shareLdap):
if not resSearch:
# Добавим пользователя LDAP
optUnix = {}
# Группа пользователя
if options.has_key('g'):
optUnix['g'] = options['g']
self.servUnixObj.addUserUnixServer(userName, optUnix)
# Полное имя пользователя
if options.has_key('c'):
optUnix['с'] = options['c']
if not self.servUnixObj.addUserUnixServer(userName, optUnix):
return False
if userPwd:
textLine = self.execProg("smbpasswd -a -s %s" %(userName),
"%s\n%s\n" %(userPwd,userPwd))
@ -1764,11 +2014,13 @@ class servSamba(shareLdap):
self.printERROR(_("Not add machine ..."))
return False
@foundConnect
def setupSambaServer(self, options):
"""Начальная настройка Samba сервиса"""
# Принудительная установка
forceOptions = False
# Cоздаем объект переменные
self.createClVars()
if options.has_key("f"):
forceOptions = True
if self.clVars.Get("soft_unix_setup") != "yes":
@ -1809,15 +2061,18 @@ Samba in backup directory")
self.clVars.Write("soft_samba_setup","no")
# Cоздаем объект профиль устанавливая директорию samba для
# файлов профилей
clProf = cl_profile.profile(self.clVars,"samba")
# Объединяем профили
clProf.applyProfiles()
if not self.applyProfilesFromService('samba'):
return False
# Записываем данные администратора сервиса Samba
ldapParser = iniLdapParser()
ldapParser.setVar("samba",
{"DN":self.clVars.Get("soft_ldap_admin_samba"),
"PASS":self.clVars.Get("soft_ldap_admin_sambapw")})
ldapParser = iniLdapParser()
pswd = ldapParser.getVar("admin","PASS")
pswd = ldapParser.getVar("samba","PASS")
if not pswd:
self.printERROR(_("ERROR") + ": " +\
_("Not find Ldap admin password"))
_("Not find Ldap Samba admin password"))
return False
textLine = self.execProg("smbpasswd -w %s" %(pswd))
if not "stored" in textLine:
@ -1825,8 +2080,9 @@ Samba in backup directory")
_("Add Ldap admin password"))
return False
textLine = self.execProg("/etc/init.d/slapd restart")
# Обнуляем LDAP cоединение
self.ldapObj = False
#Cоединение с Ldap (администратор)
shareLdap.getLdapObjInFile(self)
if not "ok" in textLine:
self.printNotOK(_("LDAP restart ..."))
@ -1842,7 +2098,6 @@ Samba in backup directory")
self.printERROR(_("Not remove Samba DN in LDAP Database ..."))
if not ret:
return False
ldifFile = self.ldifFileBase
baseLdif = self.createLdif(ldifFile)
if not self.ldapObj.getError():
@ -2013,7 +2268,7 @@ class servLdap(shareLdap):
servInstalled.append(serv)
return (servicePaths, servInstalled)
@foundConnect
@adminConnectLdap
def backupServer(self):
"""Сохраняет настройки установленных сервисов и базу LDAP"""
# создаем директорию backup-а
@ -2103,7 +2358,10 @@ class servLdap(shareLdap):
return self.restoreServer()
def stopServices(self, servInstalled):
"""Останавливает все сервисы поданные на вход"""
"""Останавливает все сервисы поданные на вход этому методу
Входные даннные - список
"""
flagError = False
flagLdap = False
for service in servInstalled:
@ -2142,6 +2400,8 @@ class servLdap(shareLdap):
self.printERROR(_("Service") + " ldap " +\
_("not started"))
flagError = True
else:
self.printOK(_("LDAP" + " " + _("start")+ " ..."))
for service in servInstalled:
if service == "unix" or service == "ldap":
continue
@ -2153,13 +2413,19 @@ class servLdap(shareLdap):
self.printERROR(_("Service") + " "+ str(service) + " " +\
_("not started"))
flagError = True
else:
self.printOK(service.capitalize() + " " +\
_("start")+ " ...")
if flagError:
return False
else:
return True
def restoreServer(self):
"""Восстанавливает все установленные сервисы"""
"""Восстанавливает из архива все установленные сервисы
Восстановленные сервисы будут запущены
"""
if not os.path.exists(self.backupDirectory):
self.printERROR(_("Not found backup path") + ": " +\
str(self.backupDirectory))
@ -2244,20 +2510,6 @@ class servLdap(shareLdap):
self.printOK(_("Restore all installed services") + " ...")
return True
def applyProfilesFromService(self, service="ldap"):
"""Применяем профили для данного сервиса"""
# Cоздаем объект профиль устанавливая директорию
# service для файлов профилей
clProf = cl_profile.profile(self.clVars,service)
# Объединяем профили
clProf.applyProfiles()
if clProf.getError():
self.printERROR(clProf.getError())
return False
else:
return True
def removeLdapDatabase(self):
"""Удаляем предыдущую базу данных"""
self.execProg("rm -rf /var/lib/openldap-data/*")
@ -2268,10 +2520,10 @@ class servLdap(shareLdap):
"""Запускает LDAP сервер"""
textLine = self.execProg("/etc/init.d/slapd %s" %(opt))
if "ok" in textLine:
self.printOK(_("LDAP start ..."))
self.printOK("LDAP" + " " + _("start")+ " ...")
return True
else:
self.printNotOK(_("LDAP start ..."))
self.printNotOK("LDAP" + " " + _("start")+ " ...")
return False
def connectLdapServer(self):
@ -2319,7 +2571,7 @@ LDAP in backup directory")
self.clVars.Write("soft_ldap_setup","no")
# Первый проход
self.clVars.Set("setup_pass_parser","1",True)
if not self.applyProfilesFromService():
if not self.applyProfilesFromService('ldap'):
self.printERROR(_("Not apply profiles: one pass"))
return False
# Удаляем старую базу данных
@ -2342,7 +2594,7 @@ LDAP in backup directory")
# Второй проход,
# удаляем временного пользователя root из конфигурационного файла
self.clVars.Set("setup_pass_parser","2",True)
if not self.applyProfilesFromService():
if not self.applyProfilesFromService('ldap'):
self.printERROR(_("Not apply profiles: two pass"))
return False
# Перезапускаем LDAP сервер
@ -2385,6 +2637,7 @@ class cl_ldap(shareLdap):
(_("Service LDAP options"),True,1,1,"options"),
(_("Service Unix options"),True,1,1,"options"),
(_("Service Samba options"),True,1,1,"options"),
(_("Service Mail options"),True,1,1,"options"),
(_("Services"),True,1,0,"")
]
@ -2407,6 +2660,8 @@ class cl_ldap(shareLdap):
_("Service LDAP options")],
"unix":[_("Common options"),
_("Service Unix options")],
"mail":[_("Common options"),
_("Service Mail options")],
}
# Cвязь длинных опций помощи и выводимых разделов помощи с опциями
self.relOptions = {"h":[_("Common options")],
@ -2416,10 +2671,13 @@ class cl_ldap(shareLdap):
_("Service Unix options")],
"help-samba":[_("Common options"),
_("Service Samba options")],
"help-mail":[_("Common options"),
_("Service Mail options")],
"help-all":[_("Common options"),
_("Service Samba options"),
_("Service LDAP options"),
_("Service Unix options")
_("Service Unix options"),
_("Service Mail options")
]
}
@ -2454,6 +2712,10 @@ class cl_ldap(shareLdap):
'helpChapter':_("Common options"),
'help':_("display help options service Samba")
},
{'longOption':"help-mail",
'helpChapter':_("Common options"),
'help':_("display help options service Mail")
},
{'longOption':"help-all",
'helpChapter':_("Common options"),
'help':_("display help options all services")
@ -2526,6 +2788,20 @@ group already exists")
'helpChapter':_("Service Unix options"),
'help':_("set the GECOS field for the new user account")
},
{'progAccess':(3,),
'shortOption':"c",
'longOption':"comment",
'optVal':"COMMENT",
'helpChapter':_("Service Samba options"),
'help':_("set the GECOS field for the new unix account")
},
{'progAccess':(3,),
'shortOption':"c",
'longOption':"comment",
'optVal':"COMMENT",
'helpChapter':_("Service Mail options"),
'help':_("set the GECOS field for the new unix account")
},
{'progAccess':(3,),
'shortOption':"d",
'longOption':"home-dir",
@ -2540,6 +2816,13 @@ group already exists")
'helpChapter':_("Service Samba options"),
'help':_("force use GROUP for the new user Unix service account")
},
{'progAccess':(3,),
'shortOption':"g",
'longOption':"gid",
'optVal':"GROUP",
'helpChapter':_("Service Mail options"),
'help':_("force use GROUP for the new user Unix service account")
},
{'progAccess':(3,),
'shortOption':"g",
'longOption':"gid",
@ -2584,6 +2867,12 @@ group already exists")
'helpChapter':_("Service Samba options"),
'help':_("create unix user account and samba user account")
},
{'progAccess':(3,),
'shortOption':"f",
'longOption':"force",
'helpChapter':_("Service Mail options"),
'help':_("create unix user account and mail user account")
},
{'progAccess':(3,),
'shortOption':"p",
'longOption':"password",
@ -2595,6 +2884,17 @@ group already exists")
'helpChapter':_("Service Samba options"),
'help':_("use password for the user account (from standart input)")
},
{'progAccess':(3,),
'shortOption':"p",
'longOption':"password",
'helpChapter':_("Service Mail options"),
'help':_("use password for the user account (from dialog)")
},
{'progAccess':(3,),
'shortOption':"P",
'helpChapter':_("Service Mail options"),
'help':_("use password for the user account (from standart input)")
},
{'progAccess':(3,),
'shortOption':"w",
'helpChapter':_("Service Samba options"),
@ -2769,6 +3069,11 @@ group already exists")
'help':pcs(" samba", self.column_width,
"samba " + servName, self.consolewidth-self.column_width)
},
{'progAccess':(3,6,),
'helpChapter':_("Services"),
'help':pcs(" mail", self.column_width,
"mail " + servName, self.consolewidth-self.column_width)
},
##{'helpChapter':_("Services"),
##'help':" mail \t\t\tmail " + servName + "\n"
##},

@ -103,6 +103,10 @@ class Data:
soft_samba_setup= {'mode':"w",
'type':('param','soft'),
}
#Настроен или нет сервис Mail
soft_mail_setup= {'mode':"w",
'type':('param','soft'),
}
#Логин LDAP пользователя
soft_ldap_user_login= {'mode':"w",
'type':('param','soft'),
@ -161,6 +165,76 @@ class Data:
'value':'Computers',
}
#-----------------------------------------------------
#Все сервисы Unix
#-----------------------------------------------------
#Имя для всех сервисов
soft_ldap_sevices_dn_name = {'mode':"r",
'type':('param','soft'),
'value':'Services',
}
#DN всех сервисов
soft_ldap_sevices_dn= {'mode':"r",
'type':('param','soft'),
}
#-----------------------------------------------------
#Сервис Unix
#-----------------------------------------------------
#DN админстратора сервиса Unix (он, же DN сервиса)
soft_ldap_admin_unix= {'mode':"r",
'type':('param','soft'),
}
#имя админстратора сервиса Unix
soft_ldap_admin_unix_name= {'mode':"r",
'type':('param','soft'),
}
#пароль админстратора сервиса Unix
soft_ldap_admin_unixpw= {'mode':"r",
'type':('param','soft'),
}
#hash пароля админстратора сервиса Unix
soft_ldap_admin_unixpw_hash= {'mode':"r",
'type':('param','soft'),
}
#-----------------------------------------------------
#Сервис Samba
#-----------------------------------------------------
#DN админстратора сервиса Samba (он, же DN сервиса)
soft_ldap_admin_samba= {'mode':"r",
'type':('param','soft'),
}
#имя админстратора сервиса Samba
soft_ldap_admin_samba_name= {'mode':"r",
'type':('param','soft'),
}
#пароль админстратора сервиса Samba
soft_ldap_admin_sambapw= {'mode':"r",
'type':('param','soft'),
}
#hash пароля админстратора сервиса Samba
soft_ldap_admin_sambapw_hash= {'mode':"r",
'type':('param','soft'),
}
#-----------------------------------------------------
#Сервис Mail
#-----------------------------------------------------
#DN админстратора сервиса Mail (он, же DN сервиса)
soft_ldap_admin_mail= {'mode':"r",
'type':('param','soft'),
}
#имя админстратора сервиса Mail
soft_ldap_admin_mail_name= {'mode':"r",
'type':('param','soft'),
}
#пароль админстратора сервиса Mail
soft_ldap_admin_mailpw= {'mode':"r",
'type':('param','soft'),
}
#hash пароля админстратора сервиса Mail
soft_ldap_admin_mailpw_hash= {'mode':"r",
'type':('param','soft'),
}
#-----------------------------------------------------
#Служебные переменные
#-----------------------------------------------------
#запущенные сервисы CDS

@ -45,6 +45,11 @@ if __name__ == "__main__":
obj = cl_ldap.servSamba()
if obj.setupSambaServer(optObj.opt):
flagError = False
# Настройка сервера Mail
elif optObj.params['service'] == "mail":
obj = cl_ldap.servMail()
if obj.setupMailServer(optObj.opt):
flagError = False
if flagError:
sys.exit(1)
else:

@ -42,6 +42,11 @@ if __name__ == "__main__":
obj = cl_ldap.servSamba()
if obj.addUserSambaServer(optObj.params['user'], optObj.opt):
flagError = False
elif optObj.params['service'] == "mail":
# Добавляем Samba пользователя
obj = cl_ldap.servMail()
if obj.addUserMailServer(optObj.params['user'], optObj.opt):
flagError = False
if flagError:
sys.exit(1)
else:

Loading…
Cancel
Save