Changeset View
Changeset View
Standalone View
Standalone View
pykolab/setup/setup_ldap.py
Show All 11 Lines | |||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | # GNU General Public License for more details. | ||||
# You should have received a copy of the GNU General Public License | # You should have received a copy of the GNU General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | # | ||||
import base64 | |||||
import ldap | import ldap | ||||
import ldap.modlist | import ldap.modlist | ||||
import ldap.dn | |||||
import ldif | |||||
import os | import os | ||||
import pwd | import pwd | ||||
import shutil | import shutil | ||||
import socket | |||||
import subprocess | import subprocess | ||||
import tempfile | import tempfile | ||||
import time | import time | ||||
import components | import components | ||||
import pykolab | import pykolab | ||||
from pykolab import utils | from pykolab import utils | ||||
from pykolab.auth import Auth | from pykolab.auth import Auth | ||||
from pykolab.constants import * | from pykolab.constants import * | ||||
from pykolab.translate import _ | from pykolab.translate import _ | ||||
from StringIO import StringIO | |||||
from jinja2 import Template | |||||
log = pykolab.getLogger('pykolab.setup') | log = pykolab.getLogger('pykolab.setup') | ||||
conf = pykolab.getConf() | conf = pykolab.getConf() | ||||
def __init__(): | def __init__(): | ||||
components.register('ldap', execute, description=description()) | components.register('ldap', execute, description=description()) | ||||
def cli_options(): | def cli_options(): | ||||
ldap_group = conf.add_cli_parser_option_group(_("LDAP Options")) | ldap_group = conf.add_cli_parser_option_group(_("LDAP Options")) | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | ldap_group.add_option( | ||||
action = "store", | action = "store", | ||||
default = None, | default = None, | ||||
help = _("Specify password for the Domain Manager.") | help = _("Specify password for the Domain Manager.") | ||||
) | ) | ||||
def description(): | def description(): | ||||
return _("Setup LDAP.") | return _("Setup LDAP.") | ||||
def execute(*args, **kw): | def get_answers(): | ||||
ask_questions = True | |||||
if not conf.config_file == conf.defaults.config_file: | |||||
ask_questions = False | |||||
if conf.without_ldap: | answers = {} | ||||
print >> sys.stderr, _("Skipping setup of LDAP, as specified") | |||||
return | |||||
_input = {} | |||||
if conf.with_openldap and not conf.with_ad: | if conf.fqdn: | ||||
answers['fqdn'] = conf.fqdn | |||||
conf.command_set('ldap', 'unique_attribute', 'entryuuid') | answers['hostname'] = conf.fqdn.split('.')[0] | ||||
answers['domain'] = '.'.join(conf.fqdn.split('.')[1:]) | |||||
else: | |||||
answers['fqdn'] = fqdn | |||||
answers['hostname'] = hostname.split('.')[0] | |||||
answers['domain'] = domainname | |||||
fp = open(conf.defaults.config_file, "w+") | print >> sys.stderr, utils.multiline_message( | ||||
conf.cfg_parser.write(fp) | _(""" | ||||
fp.close() | This setup procedure plans to set up Kolab Groupware for | ||||
the following domain name space. This domain name is | |||||
obtained from the reverse DNS entry on your network | |||||
interface. Please confirm this is the appropriate domain | |||||
name space. | |||||
""") | |||||
) | |||||
return | answers['domain'] = utils.ask_question( | ||||
_("Domain name to use"), | |||||
default = answers['domain'] | |||||
) | |||||
elif conf.with_ad and not conf.with_openldap: | answers['nodotdomain'] = answers['domain'].replace('.','_') | ||||
conf.command_set('ldap', 'auth_attributes', 'samaccountname') | |||||
conf.command_set('ldap', 'modifytimestamp_format', '%%Y%%m%%d%%H%%M%%S.0Z') | |||||
conf.command_set('ldap', 'unique_attribute', 'userprincipalname') | |||||
# TODO: These attributes need to be checked | print >> sys.stderr, utils.multiline_message( | ||||
conf.command_set('ldap', 'mail_attributes', 'mail') | _(""" | ||||
conf.command_set('ldap', 'mailserver_attributes', 'mailhost') | The standard root dn we composed for you follows. Please | ||||
conf.command_set('ldap', 'quota_attribute', 'mailquota') | confirm this is the root dn you wish to use. | ||||
""") | |||||
) | |||||
return | answers['base_dn'] = utils.ask_question( | ||||
_("LDAP base DN"), | |||||
default = utils.standard_root_dn(answers['domain']) | |||||
) | |||||
elif conf.with_ad and conf.with_openldap: | if conf.with_ad: | ||||
print >> sys.stderr, utils.multiline_message( | print >> sys.stderr, utils.multiline_message( | ||||
_(""" | _(""" | ||||
You can not configure Kolab to run against OpenLDAP | Please supply Active Directory Administrator bind DN. | ||||
and Active Directory simultaneously. | This will be used to bind to Active Directory LDAP to | ||||
perform various administrative tasks. This user should | |||||
have necessary privileges in Active Directory already. | |||||
""") | """) | ||||
) | ) | ||||
sys.exit(1) | answers['bind_dn'] = utils.ask_question( | ||||
_("AD Administrator bind DN"), | |||||
default="CN=Administrator,CN=Users,%s" % answers['base_dn'] | |||||
) | |||||
elif not conf.with_ad and not conf.with_openldap: | |||||
# Assuming Dirsrv | |||||
answers['bind_dn'] = "cn=Directory Manager" | |||||
log.info(_("Default administrative bind dn for Directory Server: %s") % answers['bind_dn']) | |||||
# Pre-execution checks | # Get cn=Directory Manger password | ||||
for path, directories, files in os.walk('/etc/dirsrv/'): | if conf.directory_manager_pwd is not None: | ||||
for direct in directories: | # password was set with command line options | ||||
if direct.startswith('slapd-'): | answers['bind_pw'] = conf.directory_manager_pwd | ||||
else: | |||||
# Ask for password | |||||
if conf.with_ad: | |||||
print >> sys.stderr, utils.multiline_message( | print >> sys.stderr, utils.multiline_message( | ||||
_(""" | _(""" | ||||
It seems 389 Directory Server has an existing | Please supply a password for the Active Directory Administrator user. | ||||
instance configured. This setup script does not | |||||
intend to destroy or overwrite your data. Please | |||||
make sure /etc/dirsrv/ and /var/lib/dirsrv/ are | |||||
clean so that this setup does not have to worry. | |||||
""") | """) | ||||
) | ) | ||||
_short_text = _("Active Directory administrator password") | |||||
else: | |||||
print >> sys.stderr, utils.multiline_message( | |||||
_(""" | |||||
Please supply a password for the LDAP Directory Manager | |||||
user, which is the administrator user you will be using | |||||
to at least initially log in to the Web Admin, and that | |||||
Kolab uses to perform administrative tasks. | |||||
""") | |||||
) | |||||
_short_text = _("Directory Manager password") | |||||
sys.exit(1) | answers['bind_pw'] = utils.ask_question( | ||||
_short_text, | |||||
_input = {} | default=utils.generate_password(), | ||||
password=True, | |||||
confirm=True | |||||
) | |||||
if ask_questions: | # Ask only if LDAP is DS | ||||
if not conf.with_openldap and not conf.with_ad: | |||||
# Get Dirsrv Admin server admin user pass | |||||
print >> sys.stderr, utils.multiline_message( | print >> sys.stderr, utils.multiline_message( | ||||
_(""" | _(""" | ||||
Please supply a password for the LDAP administrator user | Please supply a password for the LDAP administrator user | ||||
'admin', used to login to the graphical console of 389 | 'admin', used to login to the graphical console of 389 | ||||
Directory server. | Directory server. | ||||
""") | """) | ||||
) | ) | ||||
_input['admin_pass'] = utils.ask_question( | answers['admin_pass'] = utils.ask_question( | ||||
_("Administrator password"), | _("Administrator password"), | ||||
default=utils.generate_password(), | default=utils.generate_password(), | ||||
password=True, | password=True, | ||||
confirm=True | confirm=True | ||||
) | ) | ||||
if conf.directory_manager_pwd is not None: | |||||
_input['dirmgr_pass'] = conf.directory_manager_pwd | # Set users for DS LDAP | ||||
print >> sys.stderr, utils.multiline_message( | |||||
_(""" | |||||
Please choose the system user and group the service | |||||
should use to run under. These should be existing, | |||||
unprivileged, local system POSIX accounts with no shell. | |||||
""") | |||||
) | |||||
try: | |||||
pw = pwd.getpwnam("dirsrv") | |||||
except: | |||||
answers['userid'] = utils.ask_question(_("User"), default="nobody") | |||||
answers['group'] = utils.ask_question(_("Group"), default="nobody") | |||||
else: | else: | ||||
answers['userid'] = utils.ask_question(_("User"), default="dirsrv") | |||||
answers['group'] = utils.ask_question(_("Group"), default="dirsrv") | |||||
# Ask if Active Directory | |||||
elif conf.with_ad and not conf.with_openldap: | |||||
# Get answers for Active Directory setup | |||||
print >> sys.stderr, utils.multiline_message( | print >> sys.stderr, utils.multiline_message( | ||||
_(""" | _(""" | ||||
Please supply a password for the LDAP Directory Manager | Specify basic Active Directory connection information. | ||||
user, which is the administrator user you will be using | |||||
to at least initially log in to the Web Admin, and that | |||||
Kolab uses to perform administrative tasks. | |||||
""") | """) | ||||
) | ) | ||||
_input['dirmgr_pass'] = utils.ask_question( | print >> sys.stderr, utils.multiline_message( | ||||
_("Directory Manager password"), | _(""" | ||||
Specify LDAP tree DN for Kolab related data. Kolab specific | |||||
LDAP records such as Kolab domain information, special users | |||||
for Kolab, shared folders and resources LDAP information. | |||||
""") | |||||
) | |||||
answers['kolab_tree_dn'] = utils.ask_question( | |||||
_("AD LDAP tree for Kolab:"), | |||||
default="OU=Kolab,%s" % answers['base_dn'] | |||||
) | |||||
answers['specialuser_base_dn'] = "OU=Special Users,%s" % answers['kolab_tree_dn'] | |||||
answers['cyrus_admin_dn'] = "CN=Cyrus Admin,%s" % answers['specialuser_base_dn'] | |||||
answers['service_bind_dn'] = "CN=Kolab Service,%s" % answers['specialuser_base_dn'] | |||||
answers['domain_base_dn'] = "OU=Domains,%s" % answers['kolab_tree_dn'] | |||||
answers['group_base_dn'] = "OU=Groups,%s" % answers['kolab_tree_dn'] | |||||
answers['resource_base_dn'] = "OU=Resources,%s" % answers['kolab_tree_dn'] | |||||
answers['sharedfolder_base_dn'] = "OU=Shared Folders,%s" % answers['kolab_tree_dn'] | |||||
answers['user_base_dn'] = "CN=Users,%s" % answers['base_dn'] | |||||
answers['kolab_user_base_dn'] = answers['user_base_dn'] | |||||
print >> sys.stderr, utils.multiline_message( | |||||
_(""" | |||||
Please provide Active Directory server URI. Setup will use it to load | |||||
Kolab schema into AD and then will configure Kolab to run with AD as | |||||
LDAP server. Schema can be loaded to schema master server only wherefore | |||||
this needs to be URI specifying AD schema master. You can change AD server | |||||
URI later, in kolab.conf file. | |||||
""") | |||||
) | |||||
#answers['ldap_uri'] = utils.ask_question( | |||||
# _("AD server URI"), | |||||
# default="ldap://adserver.domain:389" | |||||
# ) | |||||
answers['ldap_uri'] = utils.ask_question( | |||||
_("AD server URI"), | |||||
default="ldaps://w2k16-1.ad-lab.loc:636" | |||||
) | |||||
print >> sys.stderr, utils.multiline_message( | |||||
_(""" | |||||
Please supply a Cyrus Administrator password. This | |||||
password is used by Kolab to execute administrative | |||||
tasks in Cyrus IMAP. You may also need the password | |||||
yourself to troubleshoot Cyrus IMAP and/or perform | |||||
other administrative tasks against Cyrus IMAP directly. | |||||
""") | |||||
) | |||||
answers['cyrus_admin_password'] = utils.ask_question( | |||||
_("Cyrus Administrator password"), | |||||
default=utils.generate_password(), | default=utils.generate_password(), | ||||
password=True, | password=True, | ||||
confirm=True | confirm=True | ||||
) | ) | ||||
print >> sys.stderr, utils.multiline_message( | print >> sys.stderr, utils.multiline_message( | ||||
_(""" | _(""" | ||||
Please choose the system user and group the service | Please supply a Kolab Service account password. This | ||||
should use to run under. These should be existing, | account is used by various services such as Postfix, | ||||
unprivileged, local system POSIX accounts with no shell. | and Roundcube, as anonymous binds to the LDAP server | ||||
will not be allowed. | |||||
""") | """) | ||||
) | ) | ||||
answers['service_bind_pw'] = utils.ask_question( | |||||
_("Kolab Service password"), | |||||
default=utils.generate_password(), | |||||
password=True, | |||||
confirm=True | |||||
) | |||||
return answers | |||||
def ad_schema_import(*args, **kwargs): | |||||
""" | |||||
Function to load Kolab schema to Active Directory | |||||
Does checks if ldap_uri points to Schema master | |||||
""" | |||||
conf.ldap_uri = kwargs['ldap_uri'] | |||||
# Create LDAP connection | |||||
try: | try: | ||||
pw = pwd.getpwnam("dirsrv") | auth = Auth(kwargs['domain']) | ||||
except: | auth.connect(immediate=True) | ||||
_input['userid'] = utils.ask_question(_("User"), default="nobody") | auth._auth.connect() | ||||
_input['group'] = utils.ask_question(_("Group"), default="nobody") | auth._auth._bind(kwargs['bind_dn'], kwargs['bind_pw']) | ||||
else: | |||||
_input['userid'] = utils.ask_question(_("User"), default="dirsrv") | ad_schema_naming_context = auth._auth.get_entry_attribute("", "schemaNamingContext") | ||||
_input['group'] = utils.ask_question(_("Group"), default="dirsrv") | |||||
log.debug("AD Schema Naming context is %s" % ad_schema_naming_context, level=8) | |||||
# Find out AD schema master server. Only this server has writable copy of | |||||
# AD schema. First need to get fsmoRoleOwner attribute value. | |||||
ad_fsmo_attribute = auth._auth.get_entry_attribute(ad_schema_naming_context, "fSMORoleOwner") | |||||
log.debug(_("AD FSMO Role Owner entry is: %s") % ad_fsmo_attribute, level=8) | |||||
except Exception as errmsg: | |||||
log.error(_("Could not connect to LDAP. Error: %s") % errmsg) | |||||
sys.exit(1) | |||||
# Now get parent of fsmoRoleOwner | |||||
if ad_fsmo_attribute is not None: | |||||
ad_fsmo_dn = ldap.dn.explode_dn(ad_fsmo_attribute) | |||||
ad_fsmo_parent = ','.join(ad_fsmo_dn[1:]) | |||||
log.debug(_("AD FSMO entry parent is: %s") % ad_fsmo_parent, level=8) | |||||
# Look for dNSHostName attribute of the parent | |||||
if ad_fsmo_parent is not None: | |||||
ad_schema_master = auth._auth.get_entry_attribute(ad_fsmo_parent, "dNSHostName") | |||||
log.debug(_("AD schema master server is: %s") % ad_schema_master, level=8) | |||||
( | |||||
_ad_protocol, | |||||
_ad_server, | |||||
_ad_port, | |||||
_ad_base_dn, | |||||
_ad_attr, | |||||
_ad_scope, | |||||
_ad_filter | |||||
) = utils.parse_ldap_uri(conf.ldap_uri) | |||||
if not _ad_server == ad_schema_master: | |||||
log.debug(_("AD schema master %s is not the same as %s.") % (ad_schema_master, _ad_server), level=5) | |||||
log.error(_("Cannot install Kolab schema on AD server which is not schema master")) | |||||
sys.exit(1) | |||||
template_file = utils.find_template(file_name='kolab3-ad-schema.ldif.j2') | |||||
if not template_file == None: | |||||
log.debug(_("Using template file %r") % (template_file), level=8) | |||||
fp = open(template_file, 'r') | |||||
template_definition = fp.read() | |||||
fp.close() | |||||
schema_template = Template(template_definition) | |||||
log.debug( | |||||
_("Successfully compiled template %r, ready to add schema to AD server") % (template_file), | |||||
level=8 | |||||
) | |||||
schema_ldif = StringIO( | |||||
schema_template.render(ad_schema_naming_context=ad_schema_naming_context).__str__() | |||||
) | |||||
parser = ldif.LDIFRecordList(schema_ldif) | |||||
parser.parse() | |||||
# If silent install or install without asking questions | |||||
# when no need to ask confirmation | |||||
if kwargs['confirm']: | |||||
print >> sys.stderr, utils.multiline_message( | |||||
_(""" | |||||
Setup is going to add Kolab schema elements to | |||||
Active Directory. This is ireversable operation. | |||||
""") | |||||
) | |||||
confirmed = utils.ask_confirmation( | |||||
_("Modify Active Directory schema?"), | |||||
default="y" | |||||
) | |||||
else: | else: | ||||
_input['admin_pass'] = conf.get('ldap', 'bind_pw') | # this is silent install | ||||
_input['dirmgr_pass'] = conf.get('ldap', 'bind_pw') | confirmed = True | ||||
if confirmed: | |||||
for dn, attributes in parser.all_records: | |||||
log.debug("Adding DN: %s" % dn, level=5) | |||||
try: | try: | ||||
pw = pwd.getpwnam("dirsrv") | add_attributes = ldap.modlist.addModlist(attributes) | ||||
auth._auth.ldap.add_s(dn, add_attributes) | |||||
except ldap.ALREADY_EXISTS: | |||||
log.warning(_("Schema element already exist: %s") % dn) | |||||
continue | |||||
except ldap.NO_SUCH_ATTRIBUTE: | |||||
log.warning(_("Could not add %s schema element. Force update and retry.") % dn) | |||||
try: | |||||
auth._auth.set_entry_attribute("", "schemaUpdateNow", "1") | |||||
time.sleep(2) | |||||
auth._auth.ldap.add_s(dn, add_attributes) | |||||
except: | except: | ||||
_input['userid'] = "nobody" | log.error(_("Failed to add %s Kolab schema element.") % dn) | ||||
_input['group'] = "nobody" | sys.exit(1) | ||||
except Exception, errorMsg: | |||||
log.error(_("Could not add schema element: %s") % dn) | |||||
log.error(_("Error: %s") % errorMsg ) | |||||
sys.exit(1) | |||||
else: | else: | ||||
_input['userid'] = "dirsrv" | log.error(_("Kolab schema must be installed before you continue.")) | ||||
_input['group'] = "dirsrv" | sys.exit(1) | ||||
# TODO: Verify the user and group exist. | def ldap_data_load(*args, **kwargs): | ||||
""" | |||||
Function to setup LDAP tree | |||||
""" | |||||
conf.ldap_uri = kwargs['ldap_uri'] | |||||
# TODO: This takes the system fqdn, domainname and hostname, rather then | # Create LDAP connection | ||||
# the desired fqdn, domainname and hostname. | auth = Auth(kwargs['domain']) | ||||
# | auth.connect() | ||||
# TODO^2: This should be confirmed. | auth._auth.connect() | ||||
auth._auth._bind(kwargs['bind_dn'], kwargs['bind_pw']) | |||||
if conf.fqdn: | ( | ||||
_protocol, | |||||
_server, | |||||
_port, | |||||
_base_dn, | |||||
_attr, | |||||
_scope, | |||||
_filter | |||||
) = utils.parse_ldap_uri(conf.ldap_uri) | |||||
ad_ldaps = False | |||||
if _protocol == 'ldap' and conf.with_ad: | |||||
log.info(_("Active Directory passwords cannot be set over %s protocol.") % (_protocol)) | |||||
elif _protocol == "ldaps" and conf.with_ad: | |||||
ad_ldaps = True | |||||
if not kwargs['template'] == None: | |||||
log.debug(_("Using template file %r") % (kwargs['template']), level=8) | |||||
fp = open(kwargs['template'], 'r') | |||||
template_definition = fp.read() | |||||
fp.close() | |||||
_template_vars = kwargs | |||||
_template_vars['ad_ldaps'] = ad_ldaps | |||||
_template_vars['cyrus_admin_password_base64'] = base64.b64encode( | |||||
unicode("\"" + kwargs['cyrus_admin_password'] + "\"", "iso-8859-1").encode('utf-16-le') | |||||
) | |||||
_template_vars['service_bind_pw_base64'] = base64.b64encode( | |||||
unicode("\"" + kwargs['service_bind_pw'] + "\"", "iso-8859-1").encode('utf-16-le') | |||||
) | |||||
compiled_template = Template(template_definition) | |||||
log.debug(_("Successfully compiled template %r") % (kwargs['template']), level=1) | |||||
rendered_template = compiled_template.render(**_template_vars).__str__() | |||||
log.debug(_("Importing LDIF %s") % rendered_template, level=8) | |||||
template_ldif = StringIO(rendered_template) | |||||
parser = ldif.LDIFRecordList(template_ldif) | |||||
parser.parse() | |||||
for dn, attributes in parser.all_records: | |||||
log.debug("Adding DN: %s" % dn, level=5) | |||||
try: | |||||
add_attributes = ldap.modlist.addModlist(attributes) | |||||
# Do the actual synchronous add-operation to the ldapserver | |||||
auth._auth.ldap.add_s(dn, add_attributes) | |||||
except ldap.ALREADY_EXISTS: | |||||
log.warning(_("Object already exist: %s") % dn) | |||||
continue | |||||
except Exception, errorMsg: | |||||
log.error(_("Could not add object: %s") % dn) | |||||
log.error(_("Error: %s") % errorMsg ) | |||||
sys.exit(1) | |||||
def ldap_get_supported_controls(*args, **kwargs): | |||||
""" | |||||
Function to find which controls are supported by given LDAP server | |||||
and pykolab. Return the list as a string. | |||||
""" | |||||
auth = Auth(kwargs['domain']) | |||||
auth.connect(immediate=True) | |||||
auth._auth.connect() | |||||
auth._auth._bind(kwargs['bind_dn'], kwargs['bind_pw']) | |||||
_ldap_controls = auth._auth.get_entry_attribute("", "supportedControl") | |||||
supported_controls = [] | |||||
for _ldap_control in _ldap_controls: | |||||
for _control_id, _control_def in SUPPORTED_LDAP_CONTROLS.iteritems(): | |||||
if _control_def['oid'] == _ldap_control: | |||||
log.debug(_("Found control supported by pykolab: Id:%s Def: %s") % (_control_id, _control_def), level=8) | |||||
supported_controls.append(_control_id) | |||||
# Return supported controls as a string | |||||
return ','.join(map(str, supported_controls)) | |||||
def execute(*args, **kw): | |||||
ask_questions = True | |||||
_input = {} | |||||
if not conf.config_file == conf.defaults.config_file: | |||||
log.debug(_("Using supplied config file to answer all questions"), level=5) | |||||
ask_questions = False | |||||
if conf.fqdn is not None: | |||||
log.debug(_("FQDN specified. Setting other dependend values"), level=8) | |||||
_input['fqdn'] = conf.fqdn | _input['fqdn'] = conf.fqdn | ||||
_input['hostname'] = conf.fqdn.split('.')[0] | _input['hostname'] = conf.fqdn.split('.')[0] | ||||
_input['domain'] = '.'.join(conf.fqdn.split('.')[1:]) | _input['domain'] = '.'.join(conf.fqdn.split('.')[1:]) | ||||
else: | else: | ||||
log.debug(_("FQDN not specified. Derriving from defalts"), level=8) | |||||
_input['fqdn'] = fqdn | _input['fqdn'] = fqdn | ||||
_input['hostname'] = hostname.split('.')[0] | _input['hostname'] = hostname.split('.')[0] | ||||
if conf.get('kolab', 'primary_domain') is not None: | |||||
_input['domain'] = conf.get('kolab', 'primary_domain') | |||||
else: | |||||
_input['domain'] = domainname | _input['domain'] = domainname | ||||
_input['nodotdomain'] = _input['domain'].replace('.','_') | |||||
_input['rootdn'] = utils.standard_root_dn(_input['domain']) | if conf.get('ldap', 'base_dn') is not None: | ||||
_input['base_dn'] = conf.get('ldap', 'base_dn') | |||||
else: | |||||
_input['base_dn'] = utils.standard_root_dn(_input['domain']) | |||||
if conf.without_ldap: | |||||
print >> sys.stderr, _("Skipping setup of LDAP, as specified") | |||||
return | |||||
if conf.with_openldap and not conf.with_ad: | |||||
conf.command_set('ldap', 'type', 'openldap') | |||||
conf.command_set('ldap', 'unique_attribute', 'entryuuid') | |||||
fp = open(conf.defaults.config_file, "w+") | |||||
conf.cfg_parser.write(fp) | |||||
fp.close() | |||||
return | |||||
elif conf.with_ad and not conf.with_openldap: | |||||
if ask_questions: | if ask_questions: | ||||
print >> sys.stderr, utils.multiline_message( | _input = get_answers() | ||||
_(""" | else: | ||||
This setup procedure plans to set up Kolab Groupware for | # Get all the information from config file supplied as CLI -c param | ||||
the following domain name space. This domain name is | _input['ldap_uri'] = conf.get('ldap', 'ldap_uri') | ||||
obtained from the reverse DNS entry on your network | _input['bind_dn'] = conf.get('ldap', 'bind_dn') | ||||
interface. Please confirm this is the appropriate domain | _input['bind_pw'] = conf.get('ldap', 'bind_pw') | ||||
name space. | _input['service_bind_dn'] = conf.get('ldap', 'service_bind_dn') | ||||
""") | _input['service_bind_pw'] = conf.get('ldap', 'service_bind_pw') | ||||
) | _input['user_base_dn'] = conf.get('ldap', 'user_base_dn') | ||||
_input['kolab_user_base_dn'] = conf.get('ldap', 'kolab_user_base_dn') | |||||
_input['group_base_dn'] = conf.get('ldap', 'group_base_dn') | |||||
_input['sharedfolder_base_dn'] = conf.get('ldap', 'sharedfolder_base_dn') | |||||
_input['resource_base_dn'] = conf.get('ldap', 'resource_base_dn') | |||||
_input['domain_base_dn'] = conf.get('ldap', 'domain_base_dn') | |||||
_input['cyrus_admin_password'] = conf.get('cyrus-imap', 'admin_password') | |||||
# Things which are specific to AD and are not in config file | |||||
_input['kolab_tree_dn'] = "OU=Kolab,%s" % _input['base_dn'] | |||||
_input['specialuser_base_dn'] = "OU=Special Users,%s" % _input['kolab_tree_dn'] | |||||
_input['cyrus_admin_dn'] = "CN=Cyrus Admin,%s" % _input['specialuser_base_dn'] | |||||
conf.command_set('ldap', 'type', 'ad') | |||||
conf.command_set('ldap', 'auth_attributes', 'mail, kolabAlias, uid, samaccountname') | |||||
conf.command_set('ldap', 'mail_attributes', 'mail, kolabAlias') | |||||
conf.command_set('ldap', 'modifytimestamp_format', '%Y%m%d%H%M%S.0Z') | |||||
conf.command_set('ldap', 'unique_attribute', 'objectguid') | |||||
conf.command_set('ldap', 'sharedfolder_acl_entry_attribute', 'kolabImapACL') | |||||
conf.command_set('ldap', 'mailserver_attribute', 'kolabMailhost') | |||||
conf.command_set('ldap', 'quota_attribute', 'kolabMailquota') | |||||
conf.command_set('ldap', 'group_objectclass', 'group') | |||||
conf.command_set('ldap', 'group_member_attr', 'member') | |||||
# TODO: These attributes need to be checked | |||||
conf.command_set('ldap', 'ldap_uri', _input['ldap_uri']) | |||||
conf.command_set('ldap', 'supported_controls', ldap_get_supported_controls(**_input)) | |||||
conf.command_set('ldap', 'base_dn', _input['base_dn']) | |||||
conf.command_set('ldap', 'bind_dn', _input['bind_dn']) | |||||
conf.command_set('ldap', 'bind_pw', _input['bind_pw']) | |||||
conf.command_set('ldap', 'service_bind_dn', _input['service_bind_dn']) | |||||
conf.command_set('ldap', 'service_bind_pw', _input['service_bind_pw']) | |||||
conf.command_set('ldap', 'user_base_dn', _input['user_base_dn']) | |||||
conf.command_set('ldap', 'kolab_user_base_dn', _input['kolab_user_base_dn']) | |||||
conf.command_set('ldap', 'group_base_dn', _input['group_base_dn']) | |||||
conf.command_set('ldap', 'sharedfolder_base_dn', _input['sharedfolder_base_dn']) | |||||
conf.command_set('ldap', 'resource_base_dn', _input['resource_base_dn']) | |||||
conf.command_set('ldap', 'domain_base_dn', _input['domain_base_dn']) | |||||
conf.command_set('kolab', 'primary_domain', _input['domain']) | |||||
conf.command_set('cyrus-imap', 'admin_password', _input['cyrus_admin_password']) | |||||
answer = utils.ask_confirmation("%s" % (_input['domain'])) | _input['confirm'] = ask_questions | ||||
if not answer: | ad_schema_import(**_input) | ||||
positive_answer = False | |||||
while not positive_answer: | templates = ['kolab-ad-tree.ldif.j2', 'kolab-ad-special-users.ldif.j2', 'kolab-ad-domain.ldif.j2'] | ||||
_input['domain'] = utils.ask_question(_("Domain name to use")) | for template in templates: | ||||
if not _input['domain'] == None and not _input['domain'] == "": | _input['template'] = utils.find_template(file_name=template) | ||||
positive_answer = True | |||||
if _input['template'] is not None: | |||||
ldap_data_load(**_input) | |||||
else: | else: | ||||
continue | |||||
return | |||||
elif conf.with_ad and conf.with_openldap: | |||||
print >> sys.stderr, utils.multiline_message( | print >> sys.stderr, utils.multiline_message( | ||||
_(""" | _(""" | ||||
Invalid input. Please try again. | You can not configure Kolab to run against OpenLDAP | ||||
and Active Directory simultaneously. | |||||
""") | """) | ||||
) | ) | ||||
_input['nodotdomain'] = _input['domain'].replace('.','_') | sys.exit(1) | ||||
_input['rootdn'] = utils.standard_root_dn(_input['domain']) | |||||
# This is a point where setup starts cofigure local Directory Server | |||||
# Pre-execution checks | |||||
for path, directories, files in os.walk('/etc/dirsrv/'): | |||||
for direct in directories: | |||||
if direct.startswith('slapd-'): | |||||
print >> sys.stderr, utils.multiline_message( | print >> sys.stderr, utils.multiline_message( | ||||
_(""" | _(""" | ||||
The standard root dn we composed for you follows. Please | It seems 389 Directory Server has an existing | ||||
confirm this is the root dn you wish to use. | instance configured. This setup script does not | ||||
intend to destroy or overwrite your data. Please | |||||
make sure /etc/dirsrv/ and /var/lib/dirsrv/ are | |||||
clean so that this setup does not have to worry. | |||||
""") | """) | ||||
) | ) | ||||
answer = utils.ask_confirmation("%s" % (_input['rootdn'])) | sys.exit(1) | ||||
if not answer: | if ask_questions: | ||||
positive_answer = False | _input = get_answers() | ||||
while not positive_answer: | |||||
_input['rootdn'] = utils.ask_question(_("Root DN to use")) | |||||
if not _input['rootdn'] == None and not _input['rootdn'] == "": | |||||
positive_answer = True | |||||
else: | else: | ||||
print >> sys.stderr, utils.multiline_message( | _input['admin_pass'] = conf.get('ldap', 'bind_pw') | ||||
_(""" | _input['bind_pw'] = conf.get('ldap', 'bind_pw') | ||||
Invalid input. Please try again. | try: | ||||
""") | pw = pwd.getpwnam("dirsrv") | ||||
) | except: | ||||
_input['userid'] = "nobody" | |||||
_input['group'] = "nobody" | |||||
else: | |||||
_input['userid'] = "dirsrv" | |||||
_input['group'] = "dirsrv" | |||||
# TODO: Verify the user and group exist. | |||||
# TODO: This takes the system fqdn, domainname and hostname, rather then | |||||
# the desired fqdn, domainname and hostname. | |||||
# | |||||
# TODO^2: This should be confirmed. | |||||
_input['nodotdomain'] = _input['domain'].replace('.','_') | |||||
_input['ldap_uri'] = 'ldap://localhost:389/' | |||||
# TODO: Loudly complain if the fqdn does not resolve back to this system. | # TODO: Loudly complain if the fqdn does not resolve back to this system. | ||||
data = """ | template_file = utils.find_template(file_name='kolab-ds-setup.inf.j2') | ||||
[General] | |||||
FullMachineName = %(fqdn)s | if template_file is not None: | ||||
SuiteSpotUserID = %(userid)s | log.debug(_("Setup Directory server using %s template") % (template_file), level=8) | ||||
SuiteSpotGroup = %(group)s | |||||
AdminDomain = %(domain)s | fpr = open(template_file, 'r') | ||||
ConfigDirectoryLdapURL = ldap://%(fqdn)s:389/o=NetscapeRoot | template_definition = fpr.read() | ||||
ConfigDirectoryAdminID = admin | fpr.close() | ||||
ConfigDirectoryAdminPwd = %(admin_pass)s | |||||
setup_inf_template = Template(template_definition) | |||||
[slapd] | |||||
SlapdConfigForMC = Yes | log.debug( | ||||
UseExistingMC = 0 | _("Successfully compiled template %r, ready to add schema to AD server") % (template_file), | ||||
ServerPort = 389 | level=8 | ||||
ServerIdentifier = %(hostname)s | ) | ||||
Suffix = %(rootdn)s | |||||
RootDN = cn=Directory Manager | data = setup_inf_template.render(**_input).__str__() | ||||
RootDNPwd = %(dirmgr_pass)s | |||||
ds_bename = %(nodotdomain)s | (fpw, filename) = tempfile.mkstemp(dir="/tmp/") | ||||
AddSampleEntries = No | os.write(fpw, data) | ||||
os.close(fpw) | |||||
[admin] | |||||
Port = 9830 | |||||
ServerAdminID = admin | |||||
ServerAdminPwd = %(admin_pass)s | |||||
""" % (_input) | |||||
(fp, filename) = tempfile.mkstemp(dir="/tmp/") | |||||
os.write(fp, data) | |||||
os.close(fp) | |||||
if os.path.isfile("/usr/sbin/setup-ds-admin.pl"): | if os.path.isfile("/usr/sbin/setup-ds-admin.pl"): | ||||
setup_ds_admin = "/usr/sbin/setup-ds-admin.pl" | setup_ds_admin = "/usr/sbin/setup-ds-admin.pl" | ||||
#elif os.path.isfile("/usr/sbin/setup-ds-admin"): | #elif os.path.isfile("/usr/sbin/setup-ds-admin"): | ||||
#setup_ds_admin = "/usr/sbin/setup-ds-admin" | #setup_ds_admin = "/usr/sbin/setup-ds-admin" | ||||
elif os.path.isfile("/usr/sbin/setup-ds.pl"): | elif os.path.isfile("/usr/sbin/setup-ds.pl"): | ||||
setup_ds_admin = "/usr/sbin/setup-ds.pl" | setup_ds_admin = "/usr/sbin/setup-ds.pl" | ||||
elif os.path.isfile("/usr/sbin/setup-ds"): | elif os.path.isfile("/usr/sbin/setup-ds"): | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | def execute(*args, **kw): | ||||
elif os.path.isfile('/sbin/chkconfig'): | elif os.path.isfile('/sbin/chkconfig'): | ||||
subprocess.call(['/sbin/chkconfig', 'dirsrv', 'on']) | subprocess.call(['/sbin/chkconfig', 'dirsrv', 'on']) | ||||
elif os.path.isfile('/usr/sbin/update-rc.d'): | elif os.path.isfile('/usr/sbin/update-rc.d'): | ||||
subprocess.call(['/usr/sbin/update-rc.d', 'dirsrv', 'defaults']) | subprocess.call(['/usr/sbin/update-rc.d', 'dirsrv', 'defaults']) | ||||
else: | else: | ||||
log.error(_("Could not configure to start on boot, the " + \ | log.error(_("Could not configure to start on boot, the " + \ | ||||
"directory server service.")) | "directory server service.")) | ||||
if ask_questions: | if not ask_questions: | ||||
print >> sys.stderr, utils.multiline_message( | _input['cyrus_admin_password'] = conf.get('cyrus-imap', 'admin_password') | ||||
_(""" | _input['service_bind_pw'] = conf.get('ldap', 'service_bind_pw') | ||||
Please supply a Cyrus Administrator password. This | |||||
password is used by Kolab to execute administrative | |||||
tasks in Cyrus IMAP. You may also need the password | |||||
yourself to troubleshoot Cyrus IMAP and/or perform | |||||
other administrative tasks against Cyrus IMAP directly. | |||||
""") | |||||
) | |||||
_input['cyrus_admin_pass'] = utils.ask_question( | |||||
_("Cyrus Administrator password"), | |||||
default=utils.generate_password(), | |||||
password=True, | |||||
confirm=True | |||||
) | |||||
print >> sys.stderr, utils.multiline_message( | |||||
_(""" | |||||
Please supply a Kolab Service account password. This | |||||
account is used by various services such as Postfix, | |||||
and Roundcube, as anonymous binds to the LDAP server | |||||
will not be allowed. | |||||
""") | |||||
) | |||||
_input['kolab_service_pass'] = utils.ask_question( | |||||
_("Kolab Service password"), | |||||
default=utils.generate_password(), | |||||
password=True, | |||||
confirm=True | |||||
) | |||||
else: | |||||
_input['cyrus_admin_pass'] = conf.get('cyrus-imap', 'admin_password') | |||||
_input['kolab_service_pass'] = conf.get('ldap', 'service_bind_pw') | |||||
log.info(_("Writing out configuration to kolab.conf")) | log.info(_("Writing out configuration to kolab.conf")) | ||||
# Write out kolab configuration | # Write out kolab configuration | ||||
conf.command_set('kolab', 'primary_domain', _input['domain']) | conf.command_set('kolab', 'primary_domain', _input['domain']) | ||||
conf.command_set('ldap', 'base_dn', _input['rootdn']) | conf.command_set('ldap', 'ldap_uri', _input['ldap_uri']) | ||||
conf.command_set('ldap', 'base_dn', _input['base_dn']) | |||||
conf.command_set('ldap', 'bind_dn', 'cn=Directory Manager') | conf.command_set('ldap', 'bind_dn', 'cn=Directory Manager') | ||||
conf.command_set('ldap', 'bind_pw', _input['dirmgr_pass']) | conf.command_set('ldap', 'bind_pw', _input['bind_pw']) | ||||
conf.command_set('ldap', 'service_bind_dn', 'uid=kolab-service,ou=Special Users,%s' % (_input['rootdn'])) | conf.command_set('ldap', 'service_bind_dn', 'uid=kolab-service,ou=Special Users,%s' % (_input['base_dn'])) | ||||
conf.command_set('ldap', 'service_bind_pw', _input['kolab_service_pass']) | conf.command_set('ldap', 'service_bind_pw', _input['service_bind_pw']) | ||||
fp = open(conf.defaults.config_file, "w+") | fp = open(conf.defaults.config_file, "w+") | ||||
conf.cfg_parser.write(fp) | conf.cfg_parser.write(fp) | ||||
fp.close() | fp.close() | ||||
log.info(_("Inserting service users into LDAP.")) | log.info(_("Inserting service users into LDAP.")) | ||||
# Insert service users | # Insert service users | ||||
auth = Auth(_input['domain']) | auth = Auth(_input['domain']) | ||||
auth.connect() | auth.connect() | ||||
auth._auth.connect() | auth._auth.connect() | ||||
auth._auth._bind(bind_dn='cn=Directory Manager', bind_pw=_input['dirmgr_pass']) | auth._auth._bind(bind_dn='cn=Directory Manager', bind_pw=_input['bind_pw']) | ||||
dn = 'uid=%s,ou=Special Users,%s' % (conf.get('cyrus-imap', 'admin_login'), _input['rootdn']) | dn = 'uid=%s,ou=Special Users,%s' % (conf.get('cyrus-imap', 'admin_login'), _input['base_dn']) | ||||
# A dict to help build the "body" of the object | # A dict to help build the "body" of the object | ||||
attrs = {} | attrs = {} | ||||
attrs['objectclass'] = ['top','person','inetorgperson','organizationalperson'] | attrs['objectclass'] = ['top','person','inetorgperson','organizationalperson'] | ||||
attrs['uid'] = conf.get('cyrus-imap', 'admin_login') | attrs['uid'] = conf.get('cyrus-imap', 'admin_login') | ||||
attrs['givenname'] = "Cyrus" | attrs['givenname'] = "Cyrus" | ||||
attrs['surname'] = "Administrator" | attrs['surname'] = "Administrator" | ||||
attrs['cn'] = "Cyrus Administrator" | attrs['cn'] = "Cyrus Administrator" | ||||
attrs['userPassword'] = _input['cyrus_admin_pass'] | attrs['userPassword'] = _input['cyrus_admin_password'] | ||||
# Convert our dict to nice syntax for the add-function using modlist-module | # Convert our dict to nice syntax for the add-function using modlist-module | ||||
ldif = ldap.modlist.addModlist(attrs) | ldif = ldap.modlist.addModlist(attrs) | ||||
# Do the actual synchronous add-operation to the ldapserver | # Do the actual synchronous add-operation to the ldapserver | ||||
auth._auth.ldap.add_s(dn, ldif) | auth._auth.ldap.add_s(dn, ldif) | ||||
conf.command_set('cyrus-imap', 'admin_password', _input['cyrus_admin_pass']) | conf.command_set('cyrus-imap', 'admin_password', _input['cyrus_admin_password']) | ||||
dn = 'uid=kolab-service,ou=Special Users,%s' % (_input['rootdn']) | dn = 'uid=kolab-service,ou=Special Users,%s' % (_input['base_dn']) | ||||
# A dict to help build the "body" of the object | # A dict to help build the "body" of the object | ||||
attrs = {} | attrs = {} | ||||
attrs['objectclass'] = ['top','person','inetorgperson','organizationalperson'] | attrs['objectclass'] = ['top','person','inetorgperson','organizationalperson'] | ||||
attrs['uid'] = "kolab-service" | attrs['uid'] = "kolab-service" | ||||
attrs['givenname'] = "Kolab" | attrs['givenname'] = "Kolab" | ||||
attrs['surname'] = "Service" | attrs['surname'] = "Service" | ||||
attrs['cn'] = "Kolab Service" | attrs['cn'] = "Kolab Service" | ||||
attrs['userPassword'] = _input['kolab_service_pass'] | attrs['userPassword'] = _input['service_bind_pw'] | ||||
attrs['nslookthroughlimit'] = '-1' | attrs['nslookthroughlimit'] = '-1' | ||||
attrs['nssizelimit'] = '-1' | attrs['nssizelimit'] = '-1' | ||||
attrs['nstimelimit'] = '-1' | attrs['nstimelimit'] = '-1' | ||||
attrs['nsidletimeout'] = '-1' | attrs['nsidletimeout'] = '-1' | ||||
# Convert our dict to nice syntax for the add-function using modlist-module | # Convert our dict to nice syntax for the add-function using modlist-module | ||||
ldif = ldap.modlist.addModlist(attrs) | ldif = ldap.modlist.addModlist(attrs) | ||||
# Do the actual synchronous add-operation to the ldapserver | # Do the actual synchronous add-operation to the ldapserver | ||||
auth._auth.ldap.add_s(dn, ldif) | auth._auth.ldap.add_s(dn, ldif) | ||||
dn = 'ou=Resources,%s' % (_input['rootdn']) | dn = 'ou=Resources,%s' % (_input['base_dn']) | ||||
# A dict to help build the "body" of the object | # A dict to help build the "body" of the object | ||||
attrs = {} | attrs = {} | ||||
attrs['objectclass'] = ['top','organizationalunit'] | attrs['objectclass'] = ['top','organizationalunit'] | ||||
attrs['ou'] = "Resources" | attrs['ou'] = "Resources" | ||||
# Convert our dict to nice syntax for the add-function using modlist-module | # Convert our dict to nice syntax for the add-function using modlist-module | ||||
ldif = ldap.modlist.addModlist(attrs) | ldif = ldap.modlist.addModlist(attrs) | ||||
# Do the actual synchronous add-operation to the ldapserver | # Do the actual synchronous add-operation to the ldapserver | ||||
auth._auth.ldap.add_s(dn, ldif) | auth._auth.ldap.add_s(dn, ldif) | ||||
dn = 'ou=Shared Folders,%s' % (_input['rootdn']) | dn = 'ou=Shared Folders,%s' % (_input['base_dn']) | ||||
# A dict to help build the "body" of the object | # A dict to help build the "body" of the object | ||||
attrs = {} | attrs = {} | ||||
attrs['objectclass'] = ['top','organizationalunit'] | attrs['objectclass'] = ['top','organizationalunit'] | ||||
attrs['ou'] = "Shared Folders" | attrs['ou'] = "Shared Folders" | ||||
# Convert our dict to nice syntax for the add-function using modlist-module | # Convert our dict to nice syntax for the add-function using modlist-module | ||||
ldif = ldap.modlist.addModlist(attrs) | ldif = ldap.modlist.addModlist(attrs) | ||||
# Do the actual synchronous add-operation to the ldapserver | # Do the actual synchronous add-operation to the ldapserver | ||||
auth._auth.ldap.add_s(dn, ldif) | auth._auth.ldap.add_s(dn, ldif) | ||||
log.info(_("Writing out cn=kolab,cn=config")) | log.info(_("Writing out cn=kolab,cn=config")) | ||||
dn = 'cn=kolab,cn=config' | dn = 'cn=kolab,cn=config' | ||||
# A dict to help build the "body" of the object | # A dict to help build the "body" of the object | ||||
attrs = {} | attrs = {} | ||||
attrs['objectclass'] = ['top','extensibleobject'] | attrs['objectclass'] = ['top','extensibleobject'] | ||||
attrs['cn'] = "kolab" | attrs['cn'] = "kolab" | ||||
attrs['aci'] = '(targetattr = "*") (version 3.0;acl "Kolab Services";allow (read,compare,search)(userdn = "ldap:///uid=kolab-service,ou=Special Users,%s");)' % (_input['rootdn']) | attrs['aci'] = '(targetattr = "*") (version 3.0;acl "Kolab Services";allow (read,compare,search)(userdn = "ldap:///uid=kolab-service,ou=Special Users,%s");)' % (_input['base_dn']) | ||||
# Convert our dict to nice syntax for the add-function using modlist-module | # Convert our dict to nice syntax for the add-function using modlist-module | ||||
ldif = ldap.modlist.addModlist(attrs) | ldif = ldap.modlist.addModlist(attrs) | ||||
# Do the actual synchronous add-operation to the ldapserver | # Do the actual synchronous add-operation to the ldapserver | ||||
auth._auth.ldap.add_s(dn, ldif) | auth._auth.ldap.add_s(dn, ldif) | ||||
log.info(_("Adding domain %s to list of domains for this deployment") % (_input['domain'])) | log.info(_("Adding domain %s to list of domains for this deployment") % (_input['domain'])) | ||||
dn = "associateddomain=%s,cn=kolab,cn=config" % (_input['domain']) | dn = "associateddomain=%s,cn=kolab,cn=config" % (_input['domain']) | ||||
attrs = {} | attrs = {} | ||||
attrs['objectclass'] = ['top','domainrelatedobject'] | attrs['objectclass'] = ['top','domainrelatedobject'] | ||||
attrs['associateddomain'] = [ | attrs['associateddomain'] = [ | ||||
'%s' % (_input['domain']), | '%s' % (_input['domain']), | ||||
'%s' % (_input['fqdn']), | '%s' % (_input['fqdn']), | ||||
'localhost.localdomain', | 'localhost.localdomain', | ||||
'localhost' | 'localhost' | ||||
] | ] | ||||
# De-duplicate attribute values before attempting to insert the object (#2205) | # De-duplicate attribute values before attempting to insert the object (#2205) | ||||
attrs['associateddomain'] = list(set(attrs['associateddomain'])) | attrs['associateddomain'] = list(set(attrs['associateddomain'])) | ||||
attrs['associateddomain'].pop(attrs['associateddomain'].index(_input['domain'])) | attrs['associateddomain'].pop(attrs['associateddomain'].index(_input['domain'])) | ||||
attrs['associateddomain'] = [ _input['domain'] ] + attrs['associateddomain'] | attrs['associateddomain'] = [ _input['domain'] ] + attrs['associateddomain'] | ||||
attrs['aci'] = '(targetattr = "*") (version 3.0;acl "Read Access for %(domain)s Users";allow (read,compare,search)(userdn = "ldap:///%(rootdn)s??sub?(objectclass=*)");)' % (_input) | attrs['aci'] = '(targetattr = "*") (version 3.0;acl "Read Access for %(domain)s Users";allow (read,compare,search)(userdn = "ldap:///%(base_dn)s??sub?(objectclass=*)");)' % (_input) | ||||
# Add inetdomainbasedn in case the configured root dn is not the same as the | # Add inetdomainbasedn in case the configured root dn is not the same as the | ||||
# standard root dn for the domain name configured | # standard root dn for the domain name configured | ||||
if not _input['rootdn'] == utils.standard_root_dn(_input['domain']): | if not _input['base_dn'] == utils.standard_root_dn(_input['domain']): | ||||
attrs['objectclass'].append('inetdomain') | attrs['objectclass'].append('inetdomain') | ||||
attrs['inetdomainbasedn'] = _input['rootdn'] | attrs['inetdomainbasedn'] = _input['base_dn'] | ||||
ldif = ldap.modlist.addModlist(attrs) | ldif = ldap.modlist.addModlist(attrs) | ||||
auth._auth.ldap.add_s(dn, ldif) | auth._auth.ldap.add_s(dn, ldif) | ||||
if not conf.anonymous: | if not conf.anonymous: | ||||
log.info(_("Disabling anonymous binds")) | log.info(_("Disabling anonymous binds")) | ||||
dn = "cn=config" | dn = "cn=config" | ||||
modlist = [] | modlist = [] | ||||
Show All 25 Lines | def execute(*args, **kw): | ||||
modlist = [] | modlist = [] | ||||
modlist.append((ldap.MOD_REPLACE, "alwaysrecordlogin", "yes")) | modlist.append((ldap.MOD_REPLACE, "alwaysrecordlogin", "yes")) | ||||
modlist.append((ldap.MOD_ADD, "stateattrname", "lastLoginTime")) | modlist.append((ldap.MOD_ADD, "stateattrname", "lastLoginTime")) | ||||
modlist.append((ldap.MOD_ADD, "altstateattrname", "createTimestamp")) | modlist.append((ldap.MOD_ADD, "altstateattrname", "createTimestamp")) | ||||
auth._auth.ldap.modify_s(dn, modlist) | auth._auth.ldap.modify_s(dn, modlist) | ||||
# Add kolab-admin role | # Add kolab-admin role | ||||
log.info(_("Adding the kolab-admin role")) | log.info(_("Adding the kolab-admin role")) | ||||
dn = "cn=kolab-admin,%s" % (_input['rootdn']) | dn = "cn=kolab-admin,%s" % (_input['base_dn']) | ||||
attrs = {} | attrs = {} | ||||
attrs['description'] = "Kolab Administrator" | attrs['description'] = "Kolab Administrator" | ||||
attrs['objectClass'] = ['top','ldapsubentry','nsroledefinition','nssimpleroledefinition','nsmanagedroledefinition'] | attrs['objectClass'] = ['top','ldapsubentry','nsroledefinition','nssimpleroledefinition','nsmanagedroledefinition'] | ||||
attrs['cn'] = "kolab-admin" | attrs['cn'] = "kolab-admin" | ||||
ldif = ldap.modlist.addModlist(attrs) | ldif = ldap.modlist.addModlist(attrs) | ||||
auth._auth.ldap.add_s(dn, ldif) | auth._auth.ldap.add_s(dn, ldif) | ||||
# User writeable attributes on root_dn | # User writeable attributes on root_dn | ||||
log.info(_("Setting access control to %s") % (_input['rootdn'])) | log.info(_("Setting access control to %s") % (_input['base_dn'])) | ||||
dn = _input['rootdn'] | dn = _input['base_dn'] | ||||
aci = [] | aci = [] | ||||
if schema_error: | if schema_error: | ||||
aci.append('(targetattr = "carLicense || description || displayName || facsimileTelephoneNumber || homePhone || homePostalAddress || initials || jpegPhoto || l || labeledURI || mobile || o || pager || photo || postOfficeBox || postalAddress || postalCode || preferredDeliveryMethod || preferredLanguage || registeredAddress || roomNumber || secretary || seeAlso || st || street || telephoneNumber || telexNumber || title || userCertificate || userPassword || userSMIMECertificate || x500UniqueIdentifier") (version 3.0; acl "Enable self write for common attributes"; allow (read,compare,search,write)(userdn = "ldap:///self");)') | aci.append('(targetattr = "carLicense || description || displayName || facsimileTelephoneNumber || homePhone || homePostalAddress || initials || jpegPhoto || l || labeledURI || mobile || o || pager || photo || postOfficeBox || postalAddress || postalCode || preferredDeliveryMethod || preferredLanguage || registeredAddress || roomNumber || secretary || seeAlso || st || street || telephoneNumber || telexNumber || title || userCertificate || userPassword || userSMIMECertificate || x500UniqueIdentifier") (version 3.0; acl "Enable self write for common attributes"; allow (read,compare,search,write)(userdn = "ldap:///self");)') | ||||
else: | else: | ||||
aci.append('(targetattr = "carLicense || description || displayName || facsimileTelephoneNumber || homePhone || homePostalAddress || initials || jpegPhoto || l || labeledURI || mobile || o || pager || photo || postOfficeBox || postalAddress || postalCode || preferredDeliveryMethod || preferredLanguage || registeredAddress || roomNumber || secretary || seeAlso || st || street || telephoneNumber || telexNumber || title || userCertificate || userPassword || userSMIMECertificate || x500UniqueIdentifier || kolabDelegate || kolabInvitationPolicy || kolabAllowSMTPSender") (version 3.0; acl "Enable self write for common attributes"; allow (read,compare,search,write)(userdn = "ldap:///self");)') | aci.append('(targetattr = "carLicense || description || displayName || facsimileTelephoneNumber || homePhone || homePostalAddress || initials || jpegPhoto || l || labeledURI || mobile || o || pager || photo || postOfficeBox || postalAddress || postalCode || preferredDeliveryMethod || preferredLanguage || registeredAddress || roomNumber || secretary || seeAlso || st || street || telephoneNumber || telexNumber || title || userCertificate || userPassword || userSMIMECertificate || x500UniqueIdentifier || kolabDelegate || kolabInvitationPolicy || kolabAllowSMTPSender") (version 3.0; acl "Enable self write for common attributes"; allow (read,compare,search,write)(userdn = "ldap:///self");)') | ||||
aci.append('(targetattr = "*") (version 3.0;acl "Directory Administrators Group";allow (all)(groupdn = "ldap:///cn=Directory Administrators,%(rootdn)s" or roledn = "ldap:///cn=kolab-admin,%(rootdn)s");)' % (_input)) | aci.append('(targetattr = "*") (version 3.0;acl "Directory Administrators Group";allow (all)(groupdn = "ldap:///cn=Directory Administrators,%(base_dn)s" or roledn = "ldap:///cn=kolab-admin,%(base_dn)s");)' % (_input)) | ||||
aci.append('(targetattr="*")(version 3.0; acl "Configuration Administrators Group"; allow (all) groupdn="ldap:///cn=Configuration Administrators,ou=Groups,ou=TopologyManagement,o=NetscapeRoot";)') | aci.append('(targetattr="*")(version 3.0; acl "Configuration Administrators Group"; allow (all) groupdn="ldap:///cn=Configuration Administrators,ou=Groups,ou=TopologyManagement,o=NetscapeRoot";)') | ||||
aci.append('(targetattr="*")(version 3.0; acl "Configuration Administrator"; allow (all) userdn="ldap:///uid=admin,ou=Administrators,ou=TopologyManagement,o=NetscapeRoot";)') | aci.append('(targetattr="*")(version 3.0; acl "Configuration Administrator"; allow (all) userdn="ldap:///uid=admin,ou=Administrators,ou=TopologyManagement,o=NetscapeRoot";)') | ||||
aci.append('(targetattr = "*")(version 3.0; acl "SIE Group"; allow (all) groupdn = "ldap:///cn=slapd-%(hostname)s,cn=389 Directory Server,cn=Server Group,cn=%(fqdn)s,ou=%(domain)s,o=NetscapeRoot";)' % (_input)) | aci.append('(targetattr = "*")(version 3.0; acl "SIE Group"; allow (all) groupdn = "ldap:///cn=slapd-%(hostname)s,cn=389 Directory Server,cn=Server Group,cn=%(fqdn)s,ou=%(domain)s,o=NetscapeRoot";)' % (_input)) | ||||
aci.append('(targetattr != "userPassword") (version 3.0;acl "Search Access";allow (read,compare,search)(userdn = "ldap:///all");)') | aci.append('(targetattr != "userPassword") (version 3.0;acl "Search Access";allow (read,compare,search)(userdn = "ldap:///all");)') | ||||
modlist = [] | modlist = [] | ||||
modlist.append((ldap.MOD_REPLACE, "aci", aci)) | modlist.append((ldap.MOD_REPLACE, "aci", aci)) | ||||
auth._auth.ldap.modify_s(dn, modlist) | auth._auth.ldap.modify_s(dn, modlist) | ||||
Show All 12 Lines |