Esempio n. 1
0
def authenticate(username=None, password=None, domain=None):
    global session_id

    conf_username = conf.get('ldap', 'service_bind_dn')
    conf_password = conf.get('ldap', 'service_bind_pw')

    if username == None:
        username = utils.ask_question("Login", default=conf_username)

    if username == conf_username:
        password = conf_password

    if username == conf.get('ldap', 'bind_dn'):
        password = conf.get('ldap', 'bind_pw')

    if password == None:
        password = utils.ask_question("Password", default=conf_password, password=True)

    if domain == None:
        domain = conf.get('kolab', 'primary_domain')

    params = json.dumps(
            {
                    'username': username,
                    'password': password,
                    'domain': domain
                }
        )

    response = request('POST', "system.authenticate", params)

    if response.has_key('session_token'):
        session_id = response['session_token']
Esempio n. 2
0
def execute(*args, **kw):
    try:
        folder = conf.cli_args.pop(0)
        try:
            identifier = conf.cli_args.pop(0)
        except IndexError, errmsg:
            identifier = utils.ask_question(_("ACI Subject"))

    except IndexError, errmsg:
        folder = utils.ask_question(_("Folder name"))
        quota = utils.ask_question(_("ACI Subject"))
Esempio n. 3
0
def execute(*args, **kw):
    try:
        folder = conf.cli_args.pop(0)
        try:
            quota = conf.cli_args.pop(0)
        except IndexError, errmsg:
            quota = utils.ask_question(_("New quota"))

    except IndexError, errmsg:
        folder = utils.ask_question(_("Folder name"))
        quota = utils.ask_question(_("New quota"))
Esempio n. 4
0
def execute(*args, **kw):
    try:
        folder = conf.cli_args.pop(0)
        try:
            identifier = conf.cli_args.pop(0)
        except IndexError, errmsg:
            identifier = utils.ask_question(_("ACI Subject"))

    except IndexError, errmsg:
        folder = utils.ask_question(_("Folder name"))
        quota = utils.ask_question(_("ACI Subject"))
Esempio n. 5
0
def execute(*args, **kw):
    try:
        folder = conf.cli_args.pop(0)
        try:
            quota = conf.cli_args.pop(0)
        except IndexError, errmsg:
            quota = utils.ask_question(_("New quota"))

    except IndexError, errmsg:
        folder = utils.ask_question(_("Folder name"))
        quota = utils.ask_question(_("New quota"))
def execute(*args, **kw):
    folder_pattern = "*"

    try:
        user = conf.cli_args.pop(0)
        try:
            folder_pattern = conf.cli_args.pop(0)
        except IndexError, errmsg:
            folder_pattern = utils.ask_question(_("Folder pattern"))

    except IndexError, errmsg:
        user = utils.ask_question(_("User ID"))
        folder_pattern = utils.ask_question(_("Folder pattern"))
def execute(*args, **kw):
    folder_pattern = "*"

    try:
        user = conf.cli_args.pop(0)
        try:
            folder_pattern = conf.cli_args.pop(0)
        except IndexError, errmsg:
            folder_pattern = utils.ask_question(_("Folder pattern"))

    except IndexError, errmsg:
        user = utils.ask_question(_("User ID"))
        folder_pattern = utils.ask_question(_("Folder pattern"))
Esempio n. 8
0
def sharedfolder_delete(params=None):
    if params == None:
        params = {
            'id': utils.ask_question("Shared Folder DN to delete", "sharedfolder")
        }

    return request('POST', 'sharedfolder.delete', post=json.dumps(params))
Esempio n. 9
0
def resource_delete(params=None):
    if params == None:
        params = {
            'id': utils.ask_question("Resource DN to delete", "resource")
        }

    return request('POST', 'resource.delete', post=json.dumps(params))
Esempio n. 10
0
def system_select_domain(domain=None):
    if domain == None:
        domain = utils.ask_question("Domain name")

    get = { 'domain': domain }

    return request('GET', 'system.select_domain', get=get)
Esempio n. 11
0
def execute(*args, **kw):
    from pykolab import wap_client

    try:
        user = conf.cli_args.pop(0)
    except IndexError, errmsg:
        user = utils.ask_question(_("Email address"))
Esempio n. 12
0
def execute(*args, **kw):
    from pykolab import wap_client

    try:
        role = conf.cli_args.pop(0)
    except IndexError, errmsg:
        role = utils.ask_question(_("Role"))
Esempio n. 13
0
def execute(*args, **kw):
    """
        List deleted mailboxes
    """

    try:
        domain = conf.cli_args.pop(0)
    except:
        domain = utils.ask_question(_("Domain"))

    imap = IMAP()
    imap.connect()

    auth = Auth()
    auth.connect()

    domains = auth.list_domains()

    folders = []
    for primary,secondaries in domains:
        if not domain == primary and not domain in secondaries:
            continue

        folders.extend(imap.lm("user/%%@%s" % (primary)))
        for secondary in secondaries:
            folders.extend(imap.lm("user/%%@%s" % (secondary)))

    print "Deleted folders:"

    for folder in folders:
        if not conf.raw:
            print imap_utf7.decode(folder)
        else:
            print folder
Esempio n. 14
0
def execute(*args, **kw):
    from pykolab import wap_client

    try:
        user = conf.cli_args.pop(0)
    except IndexError, errmsg:
        user = utils.ask_question(_("Email address"))
Esempio n. 15
0
def user_delete(params=None):
    if params == None:
        params = {
                'user': utils.ask_question("Username for user to delete", "user")
            }

    params = json.dumps(params)

    return request('POST', 'user.delete', params)
Esempio n. 16
0
def group_delete(params=None):
    if params == None:
        params = {
                'id': utils.ask_question("Name of group to delete", "group")
            }

    post = json.dumps(params)

    return request('POST', 'group.delete', post=post)
Esempio n. 17
0
def role_find_by_attribute(params=None):
    if params == None:
        role_name = utils.ask_question("Role name")
    else:
        role_name = params['cn']

    role = request('GET', 'role.find_by_attribute?cn=%s' % (role_name))

    return role
Esempio n. 18
0
def user_info(user=None):
    if user == None:
        user = utils.ask_question("User email address")

    _params = { 'id': user }

    user = request('GET', 'user.info', get=_params)

    return user
Esempio n. 19
0
def user_delete(params=None):
    if params == None:
        params = {
                'id': utils.ask_question("Username for user to delete", "user")
            }

    post = json.dumps(params)

    return request('POST', 'user.delete', post=post)
Esempio n. 20
0
def role_add(params=None):
    if params == None:
        role_name = utils.ask_question("Role name")
        params = {
                'cn': role_name
            }

    params = json.dumps(params)

    return request('POST', 'role.add', params)
Esempio n. 21
0
def role_add(params=None):
    if params == None:
        role_name = utils.ask_question("Role name")
        params = {
                'cn': role_name
            }

    params = json.dumps(params)

    return request('POST', 'role.add', params)
Esempio n. 22
0
def role_find_by_attribute(params=None):
    if params == None:
        role_name = utils.ask_question("Role name")
    else:
        role_name = params['cn']

    get = { 'cn': role_name }
    role = request('GET', 'role.find_by_attribute', get=get)

    return role
Esempio n. 23
0
def user_edit(params=None):
    if params == None:
        params = {
                'user': utils.ask_question("Username for user to edit", "user")
            }

    params = json.dumps(params)

    user = request('GET', 'user.info', params)

    return user
Esempio n. 24
0
def user_find(attribs=None):
    if attribs == None:
        post = {
                'search': {
                        'params': {
                                utils.ask_question("Attribute") : {
                                        'value': utils.ask_question("value"),
                                        'type': 'exact'
                                    }
                            }
                    }
            }
    else:
        post = { 'search': { 'params': {} } }

        for (k,v) in attribs.iteritems():
            post['search']['params'][k] = { 'value': v, 'type': 'exact' }

    post = json.dumps(post)

    user = request('POST', 'user.find', post=post)

    return user
Esempio n. 25
0
def get_group_input():
    group_types = group_types_list()

    if len(group_types.keys()) > 1:
        for key in group_types.keys():
            if not key == "status":
                print "%s) %s" % (key,group_types[key]['name'])

        group_type_id = utils.ask_question("Please select the group type")

    elif len(group_types.keys()) > 0:
        print "Automatically selected the only group type available"
        group_type_id = group_types.keys()[0]

    else:
        print "No group types available"
        sys.exit(1)

    if group_types.has_key(group_type_id):
        group_type_info = group_types[group_type_id]['attributes']
    else:
        print "No such group type"
        sys.exit(1)

    params = {
            'group_type_id': group_type_id
        }

    for attribute in group_type_info['form_fields'].keys():
        params[attribute] = utils.ask_question(attribute)

    for attribute in group_type_info['auto_form_fields'].keys():
        exec("retval = group_form_value_generate_%s(params)" % (attribute))
        params[attribute] = retval[attribute]

    return params
Esempio n. 26
0
def get_group_input():
    group_types = group_types_list()

    if len(group_types.keys()) > 1:
        for key in group_types.keys():
            if not key == "status":
                print "%s) %s" % (key,group_types[key]['name'])

        group_type_id = utils.ask_question("Please select the group type")

    elif len(group_types.keys()) > 0:
        print "Automatically selected the only group type available"
        group_type_id = group_types.keys()[0]

    else:
        print "No group types available"
        sys.exit(1)

    if group_types.has_key(group_type_id):
        group_type_info = group_types[group_type_id]['attributes']
    else:
        print "No such group type"
        sys.exit(1)

    params = {
            'group_type_id': group_type_id
        }

    for attribute in group_type_info['form_fields'].keys():
        params[attribute] = utils.ask_question(attribute)

    for attribute in group_type_info['auto_form_fields'].keys():
        exec("retval = group_form_value_generate_%s(params)" % (attribute))
        params[attribute] = retval[attribute]

    return params
Esempio n. 27
0
def get_user_input():
    user_types = user_types_list()

    if user_types['count'] > 1:
        for key in user_types['list'].keys():
            if not key == "status":
                print "%s) %s" % (key,user_types['list'][key]['name'])

        user_type_id = utils.ask_question("Please select the user type")

    elif user_types['count'] > 0:
        print "Automatically selected the only user type available"
        user_type_id = user_types['list'].keys()[0]

    else:
        print "No user types available"
        sys.exit(1)

    if user_types['list'].has_key(user_type_id):
        user_type_info = user_types['list'][user_type_id]['attributes']
    else:
        print "No such user type"
        sys.exit(1)

    params = {
            'user_type_id': user_type_id
        }

    for attribute in user_type_info['form_fields'].keys():
        params[attribute] = utils.ask_question(attribute)

    for attribute in user_type_info['auto_form_fields'].keys():
        exec("retval = form_value_generate_%s(params)" % (attribute))
        params[attribute] = retval[attribute]

    return params
Esempio n. 28
0
def execute(*args, **kw):
    if conf.timezone == None:
        print >> sys.stderr, utils.multiline_message(
                _("""
                        Please supply the timezone PHP should be using.
                        You have to use a Continent or Country / City locality name
                        like 'Europe/Berlin', but not just 'CEST'.
                    """)
            )

        conf.timezone = utils.ask_question(
                _("Timezone ID"),
                default="UTC"
            )

    if not conf.php_ini_path == None:
        if not os.path.isfile(conf.php_ini_path):
            log.error(_("Cannot configure PHP through %r (No such file or directory)") % (conf.php_ini_path))
            return
        php_ini = conf.php_ini_path

    else:
        # Search and destroy
        php_ini = "/etc/php.ini"
        if not os.path.isfile(php_ini):
            php_ini = "/etc/php5/apache2/php.ini"

        if not os.path.isfile(php_ini):
            log.error(_("Could not find PHP configuration file php.ini"))
            return

    myaugeas = Augeas()

    setting_base = '/files%s/' % (php_ini)

    setting = os.path.join(setting_base, 'Date', 'date.timezone')
    current_value = myaugeas.get(setting)

    if current_value == None:
        insert_paths = myaugeas.match('/files%s/Date/*' % (php_ini))
        insert_path = insert_paths[(len(insert_paths)-1)]
        myaugeas.insert(insert_path, 'date.timezone', False)

    log.debug(_("Setting key %r to %r") % ('Date/date.timezone', conf.timezone), level=8)
    myaugeas.set(setting, conf.timezone)

    myaugeas.save()
Esempio n. 29
0
def execute(*args, **kw):
    if conf.timezone == None:
        print >> sys.stderr, utils.multiline_message(
            _("""
                        Please supply the timezone PHP should be using.
                        You have to use a Continent or Country / City locality name
                        like 'Europe/Berlin', but not just 'CEST'.
                    """))

        conf.timezone = utils.ask_question(_("Timezone ID"), default="UTC")

    if not conf.php_ini_path == None:
        if not os.path.isfile(conf.php_ini_path):
            log.error(
                _("Cannot configure PHP through %r (No such file or directory)"
                  ) % (conf.php_ini_path))
            return
        php_ini = conf.php_ini_path

    else:
        # Search and destroy
        php_ini = "/etc/php.ini"
        if not os.path.isfile(php_ini):
            php_ini = "/etc/php5/apache2/php.ini"

        if not os.path.isfile(php_ini):
            log.error(_("Could not find PHP configuration file php.ini"))
            return

    myaugeas = Augeas()

    setting_base = '/files%s/' % (php_ini)

    setting = os.path.join(setting_base, 'Date', 'date.timezone')
    current_value = myaugeas.get(setting)

    if current_value == None:
        insert_paths = myaugeas.match('/files%s/Date/*' % (php_ini))
        insert_path = insert_paths[(len(insert_paths) - 1)]
        myaugeas.insert(insert_path, 'date.timezone', False)

    log.debug(_("Setting key %r to %r") %
              ('Date/date.timezone', conf.timezone),
              level=8)
    myaugeas.set(setting, conf.timezone)

    myaugeas.save()
Esempio n. 30
0
def role_delete(params=None):
    if params == None:
        role_name = utils.ask_question("Role name")
        role = role_find_by_attribute({'cn': role_name})
        params = {
                'role': role.keys()[0]
            }

    if not params.has_key('role'):
        role = role_find_by_attribute(params)
        params = {
                'role': role.keys()[0]
            }

    post = json.dumps(params)

    return request('POST', 'role.delete', post=post)
Esempio n. 31
0
def role_info(params=None):
    if params == None:
        role_name = utils.ask_question("Role name")
        role = role_find_by_attribute({'cn': role_name})
        params = {
                'role': role
            }

    if not params.has_key('role'):
        role = role_find_by_attribute(params)
        params = {
                'role': role
            }

    role = request('GET', 'role.info?role=%s' % (params['role'].keys()[0]))

    return role
Esempio n. 32
0
def role_delete(params=None):
    if params == None:
        role_name = utils.ask_question("Role name")
        role = role_find_by_attribute({'cn': role_name})
        params = {
                'role': role.keys()[0]
            }

    if not params.has_key('role'):
        role = role_find_by_attribute(params)
        params = {
                'role': role.keys()[0]
            }

    params = json.dumps(params)

    return request('POST', 'role.delete', params)
Esempio n. 33
0
def execute(*args, **kw):
    from pykolab import wap_client

    # Use uber-administrative privileges
    username = conf.get('ldap', 'bind_dn')
    if username == None:
        log.error(_("Could not find credentials with sufficient permissions" + \
                "to add a domain name space."))

        sys.exit(1)

    wap_client.authenticate(username=username)

    dna = conf.get('ldap', 'domain_name_attribute')

    try:
        domain = conf.cli_args.pop(0)
    except IndexError, errmsg:
        domain = utils.ask_question(_("Domain name"))
Esempio n. 34
0
def execute(*args, **kw):
    from pykolab import wap_client

    # Use uber-administrative privileges
    username = conf.get('ldap', 'bind_dn')
    if username == None:
        log.error(_("Could not find credentials with sufficient permissions" + \
                "to add a domain name space."))

        sys.exit(1)

    wap_client.authenticate(username=username)

    dna = conf.get('ldap', 'domain_name_attribute')

    try:
        domain = conf.cli_args.pop(0)
    except IndexError, errmsg:
        domain = utils.ask_question(_("Domain name"))
Esempio n. 35
0
def user_edit(user = None, attributes={}):
    if user == None:
        get = {
                'id': utils.ask_question("Username for user to edit", "user")
            }
    else:
        get = {
                'id': user
            }

    user_info = request('GET', 'user.info', get=get)

    for attribute in attributes.keys():
        user_info[attribute] = attributes[attribute]

    post = json.dumps(user_info)

    user_edit = request('POST', 'user.edit', get=get, post=post)

    return user_edit
Esempio n. 36
0
def execute(*args, **kw):
    from pykolab import wap_client

    # Use uber-administrative privileges
    username = conf.get('ldap', 'bind_dn')
    if username == None:
        log.error(_("Could not find credentials with sufficient permissions" + \
                "to add a domain name space."))

        sys.exit(1)

    wap_client.authenticate(username=username)
    domains = wap_client.domains_list()

    dna = conf.get('ldap', 'domain_name_attribute')

    if not conf.parent_domain == None:
        parent_found = False
        if isinstance(domains['list'], dict):
            for _domain in domains['list'].keys():
                if parent_found:
                    continue

                if isinstance(domains['list'][_domain][dna], basestring):
                    if conf.parent_domain == domains['list'][_domain][dna]:
                        parent_found = True
                elif isinstance(domains['list'][_domain], list):
                    if conf.parent_domain in domains['list'][_domain][dna]:
                        parent_found = True

        if not parent_found:
            log.error(_("Invalid parent domain"))
            sys.exit(1)

    try:
        domain = conf.cli_args.pop(0)
    except IndexError, errmsg:
        domain = utils.ask_question(_("Domain name"))
Esempio n. 37
0
def execute(*args, **kw):
    try:
        folder = conf.cli_args.pop(0)
        try:
            metadata_path = conf.cli_args.pop(0)
            try:
                metadata_value = conf.cli_args.pop(0)
            except IndexError, errmsg:
                metadata_value = utils.ask_question(_("Metadata value"))

        except IndexError, errmsg:
            metadata_path = utils.ask_question(_("Metadata path"))
            metadata_value = utils.ask_question(_("Metadata value"))

    except IndexError, errmsg:
        folder = utils.ask_question(_("Folder name"))
        metadata_path = utils.ask_question(_("Metadata path"))
        metadata_value = utils.ask_question(_("Metadata value"))
Esempio n. 38
0
def execute(*args, **kw):
    try:
        folder = conf.cli_args.pop(0)
        try:
            metadata_path = conf.cli_args.pop(0)
            try:
                metadata_value = conf.cli_args.pop(0)
            except IndexError, errmsg:
                metadata_value = utils.ask_question(_("Metadata value"))

        except IndexError, errmsg:
            metadata_path = utils.ask_question(_("Metadata path"))
            metadata_value = utils.ask_question(_("Metadata value"))

    except IndexError, errmsg:
        folder = utils.ask_question(_("Folder name"))
        metadata_path = utils.ask_question(_("Metadata path"))
        metadata_value = utils.ask_question(_("Metadata value"))
Esempio n. 39
0
def execute(*args, **kw):
    ask_questions = True

    if not conf.config_file == conf.defaults.config_file:
        ask_questions = False

    _input = {}

    if ask_questions:
        print >> sys.stderr, utils.multiline_message(
                _("""
                        Please supply a password for the LDAP administrator user
                        'admin', used to login to the graphical console of 389
                        Directory server.
                    """)
            )

        _input['admin_pass'] = utils.ask_question(
                _("Administrator password"),
                default=utils.generate_password(),
                password=True,
                confirm=True
            )

        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.
                    """)
            )

        _input['dirmgr_pass'] = utils.ask_question(
                _("Directory Manager password"),
                default=utils.generate_password(),
                password=True,
                confirm=True
            )

        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:
            _input['userid'] = utils.ask_question(_("User"), default="nobody")
            _input['group'] = utils.ask_question(_("Group"), default="nobody")
        else:
            _input['userid'] = utils.ask_question(_("User"), default="dirsrv")
            _input['group'] = utils.ask_question(_("Group"), default="dirsrv")

    else:
        _input['admin_pass'] = conf.get('ldap', 'bind_pw')
        _input['dirmgr_pass'] = conf.get('ldap', 'bind_pw')
        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.

    if conf.fqdn:
        _input['fqdn'] = conf.fqdn
        _input['hostname'] = conf.fqdn.split('.')[0]
        _input['domain'] = '.'.join(conf.fqdn.split('.')[1:])
    else:
        _input['fqdn'] = fqdn
        _input['hostname'] = hostname.split('.')[0]
        _input['domain'] = domainname

    _input['nodotdomain'] = _input['domain'].replace('.','_')

    _input['rootdn'] = utils.standard_root_dn(_input['domain'])

    if ask_questions:
        print >> sys.stderr, utils.multiline_message(
                _("""
                        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.
                    """)
            )

        answer = utils.ask_confirmation("%s" % (_input['domain']))

        if not answer:
            positive_answer = False
            while not positive_answer:
                _input['domain'] = utils.ask_question(_("Domain name to use"))
                if not _input['domain'] == None and not _input['domain'] == "":
                    positive_answer = True
                else:
                    print >> sys.stderr, utils.multiline_message(
                            _("""
                                    Invalid input. Please try again.
                                """)
                        )

        _input['nodotdomain'] = _input['domain'].replace('.','_')
        _input['rootdn'] = utils.standard_root_dn(_input['domain'])

        print >> sys.stderr, utils.multiline_message(
                _("""
                        The standard root dn we composed for you follows. Please
                        confirm this is the root dn you wish to use.
                    """)
            )

        answer = utils.ask_confirmation("%s" % (_input['rootdn']))

        if not answer:
            positive_answer = False
            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:
                    print >> sys.stderr, utils.multiline_message(
                            _("""
                                    Invalid input. Please try again.
                                """)
                        )

    # TODO: Loudly complain if the fqdn does not resolve back to this system.

    data = """
[General]
FullMachineName = %(fqdn)s
SuiteSpotUserID = %(userid)s
SuiteSpotGroup = %(group)s
AdminDomain = %(domain)s
ConfigDirectoryLdapURL = ldap://%(fqdn)s:389/o=NetscapeRoot
ConfigDirectoryAdminID = admin
ConfigDirectoryAdminPwd = %(admin_pass)s

[slapd]
SlapdConfigForMC = Yes
UseExistingMC = 0
ServerPort = 389
ServerIdentifier = %(hostname)s
Suffix = %(rootdn)s
RootDN = cn=Directory Manager
RootDNPwd = %(dirmgr_pass)s
ds_bename = %(nodotdomain)s
AddSampleEntries = No

[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"):
        setup_ds_admin = "/usr/sbin/setup-ds-admin.pl"
    elif os.path.isfile("/usr/sbin/setup-ds"):
        setup_ds_admin = "/usr/sbin/setup-ds"
    else:
        log.error(_("No directory server setup tool available."))

    command = [
            setup_ds_admin,
            '--debug',
            '--silent',
            '--force',
            '--file=%s' % (filename)
        ]

    print >> sys.stderr, utils.multiline_message(
            _("""
                    Setup is now going to set up the 389 Directory Server. This
                    may take a little while (during which period there is no
                    output and no progress indication).
                """)
        )

    log.info(_("Setting up 389 Directory Server"))

    setup_389 = subprocess.Popen(
            command,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )

    (stdoutdata, stderrdata) = setup_389.communicate()

    # TODO: Get the return code and display output if not successful.

    log.debug(_("Setup DS stdout:"), level=8)
    log.debug(stdoutdata, level=8)

    log.debug(_("Setup DS stderr:"), level=8)
    log.debug(stderrdata, level=8)

    # TODO: Fails when ran a second time.

    # TODO: When fail, fail gracefully.

    # Find the kolab schema. It's installed as %doc in the kolab-schema package.
    # TODO: Chown nobody, nobody, chmod 440
    schema_file = None
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        for filename in filenames:
            if filename.startswith('kolab') and filename.endswith('.ldif') and schema_file == None:
                schema_file = os.path.join(root,filename)

    if not schema_file == None:
        try:
            shutil.copy(
                    schema_file,
                    '/etc/dirsrv/slapd-%s/schema/99%s' % (
                            _input['hostname'],
                            os.path.basename(schema_file)
                        )
                )
            schema_error = False
        except:
            log.error(_("Could not copy the LDAP extensions for Kolab"))
            schema_error = True
    else:
        log.error(_("Could not find the ldap Kolab schema file"))
        schema_error = True

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'restart', 'dirsrv.target'])
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['/sbin/service', 'dirsrv', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service','dirsrv','stop'])
        time.sleep(20)
        subprocess.call(['/usr/sbin/service','dirsrv','start'])
    else:
        log.error(_("Could not start the directory server service."))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'enable', 'dirsrv.target'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'dirsrv', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'dirsrv', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "directory server service."))

    if ask_questions:
        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.
                    """)
            )

        _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"))

    # Write out kolab configuration
    conf.command_set('kolab', 'primary_domain', _input['domain'])
    conf.command_set('ldap', 'base_dn', _input['rootdn'])
    conf.command_set('ldap', 'bind_dn', 'cn=Directory Manager')
    conf.command_set('ldap', 'bind_pw', _input['dirmgr_pass'])
    conf.command_set('ldap', 'service_bind_dn', 'uid=kolab-service,ou=Special Users,%s' % (_input['rootdn']))
    conf.command_set('ldap', 'service_bind_pw', _input['kolab_service_pass'])

    fp = open(conf.defaults.config_file, "w+")
    conf.cfg_parser.write(fp)
    fp.close()

    log.info(_("Inserting service users into LDAP."))

    # Insert service users
    auth = Auth(_input['domain'])
    auth.connect()
    auth._auth.connect()
    auth._auth._bind()

    dn = 'uid=%s,ou=Special Users,%s' % (conf.get('cyrus-imap', 'admin_login'), _input['rootdn'])

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = ['top','person','inetorgperson','organizationalperson']
    attrs['uid'] = conf.get('cyrus-imap', 'admin_login')
    attrs['givenname'] = "Cyrus"
    attrs['surname'] = "Administrator"
    attrs['cn'] = "Cyrus Administrator"
    attrs['userPassword'] = _input['cyrus_admin_pass']

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    conf.command_set('cyrus-imap', 'admin_password', _input['cyrus_admin_pass'])

    dn = 'uid=kolab-service,ou=Special Users,%s' % (_input['rootdn'])

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = ['top','person','inetorgperson','organizationalperson']
    attrs['uid'] = "kolab-service"
    attrs['givenname'] = "Kolab"
    attrs['surname'] = "Service"
    attrs['cn'] = "Kolab Service"
    attrs['userPassword'] = _input['kolab_service_pass']
    attrs['nslookthroughlimit'] = '-1'
    attrs['nssizelimit'] = '-1'
    attrs['nstimelimit'] = '-1'
    attrs['nsidletimeout'] = '-1'

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    dn = 'ou=Resources,%s' % (_input['rootdn'])

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = ['top','organizationalunit']
    attrs['ou'] = "Resources"

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    dn = 'ou=Shared Folders,%s' % (_input['rootdn'])

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = ['top','organizationalunit']
    attrs['ou'] = "Shared Folders"

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    log.info(_("Writing out cn=kolab,cn=config"))

    dn = 'cn=kolab,cn=config'

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = ['top','extensibleobject']
    attrs['cn'] = "kolab"

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    auth._auth.set_entry_attribute(
            dn,
            'aci',
            '(targetattr = "*") (version 3.0;acl "Kolab Services";allow (read,compare,search)(userdn = "ldap:///%s");)' % ('uid=kolab-service,ou=Special Users,%s' % (_input['rootdn']))
        )

    # TODO: Add kolab-admin role
    # TODO: Assign kolab-admin admin ACLs

    log.info(_("Adding domain %s to list of domains for this deployment") % (_input['domain']))
    dn = "associateddomain=%s,cn=kolab,cn=config" % (_input['domain'])
    attrs = {}
    attrs['objectclass'] = ['top','domainrelatedobject']
    attrs['associateddomain'] = '%s' % (_input['domain'])
    attrs['aci'] = '(targetattr = "*") (version 3.0;acl "Read Access for %(domain)s Users";allow (read,compare,search)(userdn = "ldap:///%(rootdn)s??sub?(objectclass=*)");)' % (_input)

    # Add inetdomainbasedn in case the configured root dn is not the same as the
    # standard root dn for the domain name configured
    if not _input['rootdn'] == utils.standard_root_dn(_input['domain']):
        attrs['objectclass'].append('inetdomain')
        attrs['inetdomainbasedn'] = _input['rootdn']

    ldif = ldap.modlist.addModlist(attrs)
    auth._auth.ldap.add_s(dn, ldif)

    if not conf.anonymous:
        log.info(_("Disabling anonymous binds"))
        dn = "cn=config"
        modlist = []
        modlist.append((ldap.MOD_REPLACE, "nsslapd-allow-anonymous-access", "off"))
        auth._auth.ldap.modify_s(dn, modlist)

    # TODO: Ensure the uid attribute is unique
    # TODO^2: Consider renaming the general "attribute uniqueness to "uid attribute uniqueness"
    log.info(_("Enabling attribute uniqueness plugin"))
    dn = "cn=attribute uniqueness,cn=plugins,cn=config"
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "nsslapd-pluginEnabled", "on"))
    auth._auth.ldap.modify_s(dn, modlist)

    log.info(_("Enabling referential integrity plugin"))
    dn = "cn=referential integrity postoperation,cn=plugins,cn=config"
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "nsslapd-pluginEnabled", "on"))
    auth._auth.ldap.modify_s(dn, modlist)

    log.info(_("Enabling and configuring account policy plugin"))
    dn = "cn=Account Policy Plugin,cn=plugins,cn=config"
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "nsslapd-pluginEnabled", "on"))
    modlist.append((ldap.MOD_ADD, "nsslapd-pluginarg0", "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config"))
    auth._auth.ldap.modify_s(dn, modlist)

    dn = "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config"
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "alwaysrecordlogin", "yes"))
    modlist.append((ldap.MOD_ADD, "stateattrname", "lastLoginTime"))
    modlist.append((ldap.MOD_ADD, "altstateattrname", "createTimestamp"))
    auth._auth.ldap.modify_s(dn, modlist)

    # TODO: Add kolab-admin role
    log.info(_("Adding the kolab-admin role"))
    dn = "cn=kolab-admin,%s" % (_input['rootdn'])
    attrs = {}
    attrs['description'] = "Kolab Administrator"
    attrs['objectClass'] = ['top','ldapsubentry','nsroledefinition','nssimpleroledefinition','nsmanagedroledefinition']
    attrs['cn'] = "kolab-admin"
    ldif = ldap.modlist.addModlist(attrs)

    auth._auth.ldap.add_s(dn, ldif)

    # TODO: User writeable attributes on root_dn
    log.info(_("Setting access control to %s") % (_input['rootdn']))
    dn = _input['rootdn']
    aci = []

    if not schema_error:
        aci.append('(targetattr = "homePhone || preferredDeliveryMethod || jpegPhoto || postalAddress || carLicense || userPassword || mobile || displayName || description || labeledURI || homePostalAddress || postOfficeBox || registeredAddress || postalCode || photo || title || street || pager || o || l || initials || telephoneNumber || preferredLanguage || facsimileTelephoneNumber") (version 3.0;acl "Enable self write for common attributes";allow (read,compare,search,write)(userdn = "ldap:///self");)')
    else:
        aci.append('(targetattr = "homePhone || preferredDeliveryMethod || jpegPhoto || postalAddress || carLicense || userPassword || mobile || kolabAllowSMTPRecipient || displayName || kolabDelegate || description || labeledURI || homePostalAddress || postOfficeBox || registeredAddress || postalCode || photo || title || street || kolabInvitationPolicy || pager || o || l || initials || kolabAllowSMTPSender || telephoneNumber || preferredLanguage || facsimileTelephoneNumber") (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 "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 "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 "Search Access";allow (read,compare,search)(userdn = "ldap:///all");)')
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "aci", aci))
    auth._auth.ldap.modify_s(dn, modlist)

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'enable', 'dirsrv-admin.service'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'dirsrv-admin', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'dirsrv-admin', 'defaults'])
    else:
        log.error(_("Could not start and configure to start on boot, the " + \
                "directory server admin service."))
Esempio n. 40
0
def execute(*args, **kw):

    socket_paths = [
            "/var/lib/mysql/mysql.sock",
            "/var/run/mysqld/mysqld.sock",
            "/var/run/mysql/mysql.sock",
            "/var/run/mysqld/mysqld.pid"
        ]

    # on CentOS7, there is MariaDB instead of MySQL
    mysqlservice = 'mysqld.service'
    if os.path.isfile('/usr/lib/systemd/system/mariadb.service'):
        mysqlservice = 'mariadb.service'
    elif os.path.isfile('/usr/lib/systemd/system/mysql.service'):
        mysqlservice = 'mysql.service'
    if not os.path.isfile('/usr/lib/systemd/system/' + mysqlservice):
        # on Debian Jessie, systemctl restart mysql
        mysqlservice = 'mysql'

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'restart', mysqlservice])
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['/sbin/service', 'mysqld', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service','mysql','restart'])
    else:
        log.error(_("Could not start the MySQL database service."))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'enable', mysqlservice])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'mysqld', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'mysql', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "MySQL database service."))

    log.info(_("Waiting for at most 30 seconds for MySQL/MariaDB to settle..."))
    max_wait = 30
    while max_wait > 0:
        for socket_path in socket_paths:
            if os.path.exists(socket_path):
                max_wait = 0

        if max_wait > 0:
            max_wait = max_wait - 1
            time.sleep(1)

    options = {
            1: "Existing MySQL server (with root password already set).",
            2: "New MySQL server (needs to be initialized)."
        }

    answer = 0
    if len([x for x in socket_paths if os.path.exists(x)]) > 0:
        if conf.mysqlserver:
            if conf.mysqlserver == 'existing':
                answer = 1
            elif conf.mysqlserver == 'new':
                answer = 2
        if answer == 0:
            answer = utils.ask_menu(_("What MySQL server are we setting up?"), options)

    if answer == "1" or answer == 1:
        print >> sys.stderr, utils.multiline_message(
                _("""
                        Please supply the root password for MySQL, so we can set
                        up user accounts for other components that use MySQL.
                    """)
            )

        mysql_root_password = utils.ask_question(
                _("MySQL root password"),
                password=True
            )

    else:
        print >> sys.stderr, utils.multiline_message(
                _("""
                        Please supply a root password for MySQL. This password
                        will be the administrative user for this MySQL server,
                        and it should be kept a secret. After this setup process
                        has completed, Kolab is going to discard and forget
                        about this password, but you will need it for
                        administrative tasks in MySQL.
                    """)
            )

        mysql_root_password = utils.ask_question(
                _("MySQL root password"),
                default=utils.generate_password(),
                password=True,
                confirm=True
            )

        p1 = subprocess.Popen(['echo', 'UPDATE mysql.user SET Password=PASSWORD(\'%s\') WHERE User=\'root\';' % (mysql_root_password)], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

        p1 = subprocess.Popen(['echo', 'FLUSH PRIVILEGES;'], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

    data = """
[mysql]
user=root
password='******'
""" % (mysql_root_password)

    fp = open('/tmp/kolab-setup-my.cnf', 'w')
    os.chmod('/tmp/kolab-setup-my.cnf', 0600)
    fp.write(data)
    fp.close()

    schema_file = None
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        for filename in filenames:
            if filename.startswith('kolab_wap') and filename.endswith('.sql'):
                # Skip the Oracle file
                if filename.endswith('oracle.sql'):
                    continue

                schema_file = os.path.join(root,filename)

    if not schema_file == None:
        p1 = subprocess.Popen(['echo', 'create database kolab;'], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

        print >> sys.stderr, utils.multiline_message(
                _("""
                        Please supply a password for the MySQL user 'kolab'.
                        This password will be used by Kolab services, such as
                        the Web Administration Panel.
                    """)
            )

        mysql_kolab_password = utils.ask_question(
                _("MySQL kolab password"),
                default=utils.generate_password(),
                password=True,
                confirm=True
            )

        p1 = subprocess.Popen(['echo', 'GRANT ALL PRIVILEGES ON kolab.* TO \'kolab\'@\'localhost\' IDENTIFIED BY \'%s\';' % (mysql_kolab_password)], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

        p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'kolab'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

        conf.command_set('kolab_wap', 'sql_uri', 'mysql://*****:*****@localhost/kolab' % (mysql_kolab_password))
        conf.command_set('kolab_smtp_access_policy', 'cache_uri', 'mysql://*****:*****@localhost/kolab' % (mysql_kolab_password))
    else:
        log.warning(_("Could not find the MySQL Kolab schema file"))
Esempio n. 41
0
def group_members_list(group=None):
    if group == None:
        group = utils.ask_question("Group email address")
    group = request('GET', 'group.members_list?group=%s' % (group))
    return group
Esempio n. 42
0
def system_select_domain(domain=None):
    if domain == None:
        domain = utils.ask_question("Domain name")
    return request('GET', 'system.select_domain?domain=%s' % (domain))
Esempio n. 43
0
def execute(*args, **kw):
    ask_questions = True

    if not conf.config_file == conf.defaults.config_file:
        ask_questions = False

    if conf.without_ldap:
        print >> sys.stderr, _("Skipping setup of LDAP, as specified")
        return

    _input = {}

    if conf.with_openldap and not conf.with_ad:

        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:
        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
        conf.command_set('ldap', 'mail_attributes', 'mail')
        conf.command_set('ldap', 'mailserver_attributes', 'mailhost')
        conf.command_set('ldap', 'quota_attribute', 'mailquota')

        return

    elif conf.with_ad and conf.with_openldap:
        print >> sys.stderr, utils.multiline_message(
            _("""
                        You can not configure Kolab to run against OpenLDAP
                        and Active Directory simultaneously.
                    """))

        sys.exit(1)

    # 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(
                    _("""
                                It seems 389 Directory Server has an existing
                                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.
                            """))

                sys.exit(1)

    _input = {}

    if ask_questions:
        print >> sys.stderr, utils.multiline_message(
            _("""
                        Please supply a password for the LDAP administrator user
                        'admin', used to login to the graphical console of 389
                        Directory server.
                    """))

        _input['admin_pass'] = utils.ask_question(
            _("Administrator password"),
            default=utils.generate_password(),
            password=True,
            confirm=True)

        if conf.directory_manager_pwd is not None:
            _input['dirmgr_pass'] = conf.directory_manager_pwd
        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.
                    """))

            _input['dirmgr_pass'] = utils.ask_question(
                _("Directory Manager password"),
                default=utils.generate_password(),
                password=True,
                confirm=True)

        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:
            _input['userid'] = utils.ask_question(_("User"), default="nobody")
            _input['group'] = utils.ask_question(_("Group"), default="nobody")
        else:
            _input['userid'] = utils.ask_question(_("User"), default="dirsrv")
            _input['group'] = utils.ask_question(_("Group"), default="dirsrv")

    else:
        _input['admin_pass'] = conf.get('ldap', 'bind_pw')
        _input['dirmgr_pass'] = conf.get('ldap', 'bind_pw')
        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.

    if conf.fqdn:
        _input['fqdn'] = conf.fqdn
        _input['hostname'] = conf.fqdn.split('.')[0]
        _input['domain'] = '.'.join(conf.fqdn.split('.')[1:])
    else:
        _input['fqdn'] = fqdn
        _input['hostname'] = hostname.split('.')[0]
        _input['domain'] = domainname
    _input['nodotdomain'] = _input['domain'].replace('.', '_')

    _input['rootdn'] = utils.standard_root_dn(_input['domain'])

    if ask_questions:
        print >> sys.stderr, utils.multiline_message(
            _("""
                        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.
                    """))

        answer = utils.ask_confirmation("%s" % (_input['domain']))

        if not answer:
            positive_answer = False
            while not positive_answer:
                _input['domain'] = utils.ask_question(_("Domain name to use"))
                if not _input['domain'] == None and not _input['domain'] == "":
                    positive_answer = True
                else:
                    print >> sys.stderr, utils.multiline_message(
                        _("""
                                    Invalid input. Please try again.
                                """))

        _input['nodotdomain'] = _input['domain'].replace('.', '_')
        _input['rootdn'] = utils.standard_root_dn(_input['domain'])

        print >> sys.stderr, utils.multiline_message(
            _("""
                        The standard root dn we composed for you follows. Please
                        confirm this is the root dn you wish to use.
                    """))

        answer = utils.ask_confirmation("%s" % (_input['rootdn']))

        if not answer:
            positive_answer = False
            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:
                    print >> sys.stderr, utils.multiline_message(
                        _("""
                                    Invalid input. Please try again.
                                """))

    # TODO: Loudly complain if the fqdn does not resolve back to this system.

    data = """
[General]
FullMachineName = %(fqdn)s
SuiteSpotUserID = %(userid)s
SuiteSpotGroup = %(group)s
AdminDomain = %(domain)s
ConfigDirectoryLdapURL = ldap://%(fqdn)s:389/o=NetscapeRoot
ConfigDirectoryAdminID = admin
ConfigDirectoryAdminPwd = %(admin_pass)s

[slapd]
SlapdConfigForMC = Yes
UseExistingMC = 0
ServerPort = 389
ServerIdentifier = %(hostname)s
Suffix = %(rootdn)s
RootDN = cn=Directory Manager
RootDNPwd = %(dirmgr_pass)s
ds_bename = %(nodotdomain)s
AddSampleEntries = No

[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"):
        setup_ds_admin = "/usr/sbin/setup-ds-admin.pl"
    #elif os.path.isfile("/usr/sbin/setup-ds-admin"):
    #setup_ds_admin = "/usr/sbin/setup-ds-admin"
    elif os.path.isfile("/usr/sbin/setup-ds.pl"):
        setup_ds_admin = "/usr/sbin/setup-ds.pl"
    elif os.path.isfile("/usr/sbin/setup-ds"):
        setup_ds_admin = "/usr/sbin/setup-ds"
    else:
        log.error(_("No directory server setup tool available."))
        sys.exit(1)

    command = [
        setup_ds_admin, '--debug', '--silent', '--force',
        '--file=%s' % (filename)
    ]

    print >> sys.stderr, utils.multiline_message(
        _("""
                    Setup is now going to set up the 389 Directory Server. This
                    may take a little while (during which period there is no
                    output and no progress indication).
                """))

    log.info(_("Setting up 389 Directory Server"))

    setup_389 = subprocess.Popen(command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)

    (stdoutdata, stderrdata) = setup_389.communicate()

    if not setup_389.returncode == 0:
        print >> sys.stderr, utils.multiline_message(
            _("""
                        An error was detected in the setup procedure for 389
                        Directory Server. This setup will write out stderr and
                        stdout to /var/log/kolab/setup.error.log and
                        /var/log/kolab/setup.out.log respectively, before it
                        exits.
                    """))

        fp = open('/var/log/kolab/setup.error.log', 'w')
        fp.write(stderrdata)
        fp.close()

        fp = open('/var/log/kolab/setup.out.log', 'w')
        fp.write(stdoutdata)
        fp.close()

    log.debug(_("Setup DS stdout:"), level=8)
    log.debug(stdoutdata, level=8)

    log.debug(_("Setup DS stderr:"), level=8)
    log.debug(stderrdata, level=8)

    if not setup_389.returncode == 0:
        sys.exit(1)

    # Find the kolab schema. It's installed as %doc in the kolab-schema package.
    # TODO: Chown nobody, nobody, chmod 440
    schema_file = None
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        for filename in filenames:
            if filename.startswith('kolab') and filename.endswith(
                    '.ldif') and schema_file == None:
                schema_file = os.path.join(root, filename)

    if not schema_file == None:
        try:
            shutil.copy(
                schema_file, '/etc/dirsrv/slapd-%s/schema/99%s' %
                (_input['hostname'], os.path.basename(schema_file)))

            schema_error = False
        except:
            log.error(_("Could not copy the LDAP extensions for Kolab"))
            schema_error = True
    else:
        log.error(_("Could not find the ldap Kolab schema file"))
        schema_error = True

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'restart', 'dirsrv.target'])
        time.sleep(20)
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['/sbin/service', 'dirsrv', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service', 'dirsrv', 'stop'])
        time.sleep(20)
        subprocess.call(['/usr/sbin/service', 'dirsrv', 'start'])
    else:
        log.error(_("Could not start the directory server service."))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'enable', 'dirsrv.target'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'dirsrv', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'dirsrv', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "directory server service."))

    if ask_questions:
        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.
                    """))

        _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"))

    # Write out kolab configuration
    conf.command_set('kolab', 'primary_domain', _input['domain'])
    conf.command_set('ldap', 'base_dn', _input['rootdn'])
    conf.command_set('ldap', 'bind_dn', 'cn=Directory Manager')
    conf.command_set('ldap', 'bind_pw', _input['dirmgr_pass'])
    conf.command_set(
        'ldap', 'service_bind_dn',
        'uid=kolab-service,ou=Special Users,%s' % (_input['rootdn']))
    conf.command_set('ldap', 'service_bind_pw', _input['kolab_service_pass'])

    fp = open(conf.defaults.config_file, "w+")
    conf.cfg_parser.write(fp)
    fp.close()

    log.info(_("Inserting service users into LDAP."))

    # Insert service users
    auth = Auth(_input['domain'])
    auth.connect()
    auth._auth.connect()
    auth._auth._bind(bind_dn='cn=Directory Manager',
                     bind_pw=_input['dirmgr_pass'])

    dn = 'uid=%s,ou=Special Users,%s' % (conf.get(
        'cyrus-imap', 'admin_login'), _input['rootdn'])

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = [
        'top', 'person', 'inetorgperson', 'organizationalperson'
    ]
    attrs['uid'] = conf.get('cyrus-imap', 'admin_login')
    attrs['givenname'] = "Cyrus"
    attrs['surname'] = "Administrator"
    attrs['cn'] = "Cyrus Administrator"
    attrs['userPassword'] = _input['cyrus_admin_pass']

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    conf.command_set('cyrus-imap', 'admin_password',
                     _input['cyrus_admin_pass'])

    dn = 'uid=kolab-service,ou=Special Users,%s' % (_input['rootdn'])

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = [
        'top', 'person', 'inetorgperson', 'organizationalperson'
    ]
    attrs['uid'] = "kolab-service"
    attrs['givenname'] = "Kolab"
    attrs['surname'] = "Service"
    attrs['cn'] = "Kolab Service"
    attrs['userPassword'] = _input['kolab_service_pass']
    attrs['nslookthroughlimit'] = '-1'
    attrs['nssizelimit'] = '-1'
    attrs['nstimelimit'] = '-1'
    attrs['nsidletimeout'] = '-1'

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    dn = 'ou=Resources,%s' % (_input['rootdn'])

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = ['top', 'organizationalunit']
    attrs['ou'] = "Resources"

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    dn = 'ou=Shared Folders,%s' % (_input['rootdn'])

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = ['top', 'organizationalunit']
    attrs['ou'] = "Shared Folders"

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    log.info(_("Writing out cn=kolab,cn=config"))

    dn = 'cn=kolab,cn=config'

    # A dict to help build the "body" of the object
    attrs = {}
    attrs['objectclass'] = ['top', 'extensibleobject']
    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'])

    # Convert our dict to nice syntax for the add-function using modlist-module
    ldif = ldap.modlist.addModlist(attrs)

    # Do the actual synchronous add-operation to the ldapserver
    auth._auth.ldap.add_s(dn, ldif)

    log.info(
        _("Adding domain %s to list of domains for this deployment") %
        (_input['domain']))
    dn = "associateddomain=%s,cn=kolab,cn=config" % (_input['domain'])
    attrs = {}
    attrs['objectclass'] = ['top', 'domainrelatedobject']
    attrs['associateddomain'] = [
        '%s' % (_input['domain']),
        '%s' % (_input['fqdn']), 'localhost.localdomain', 'localhost'
    ]

    # De-duplicate attribute values before attempting to insert the object (#2205)
    attrs['associateddomain'] = list(set(attrs['associateddomain']))
    attrs['associateddomain'].pop(attrs['associateddomain'].index(
        _input['domain']))
    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)

    # Add inetdomainbasedn in case the configured root dn is not the same as the
    # standard root dn for the domain name configured
    if not _input['rootdn'] == utils.standard_root_dn(_input['domain']):
        attrs['objectclass'].append('inetdomain')
        attrs['inetdomainbasedn'] = _input['rootdn']

    ldif = ldap.modlist.addModlist(attrs)
    auth._auth.ldap.add_s(dn, ldif)

    if not conf.anonymous:
        log.info(_("Disabling anonymous binds"))
        dn = "cn=config"
        modlist = []
        modlist.append(
            (ldap.MOD_REPLACE, "nsslapd-allow-anonymous-access", "off"))
        auth._auth.ldap.modify_s(dn, modlist)

    # TODO: Ensure the uid attribute is unique
    # TODO^2: Consider renaming the general "attribute uniqueness to "uid attribute uniqueness"
    log.info(_("Enabling attribute uniqueness plugin"))
    dn = "cn=attribute uniqueness,cn=plugins,cn=config"
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "nsslapd-pluginEnabled", "on"))
    auth._auth.ldap.modify_s(dn, modlist)

    log.info(_("Enabling referential integrity plugin"))
    dn = "cn=referential integrity postoperation,cn=plugins,cn=config"
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "nsslapd-pluginEnabled", "on"))
    auth._auth.ldap.modify_s(dn, modlist)

    log.info(_("Enabling and configuring account policy plugin"))
    dn = "cn=Account Policy Plugin,cn=plugins,cn=config"
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "nsslapd-pluginEnabled", "on"))
    modlist.append((ldap.MOD_ADD, "nsslapd-pluginarg0",
                    "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config"))
    auth._auth.ldap.modify_s(dn, modlist)

    dn = "cn=config,cn=Account Policy Plugin,cn=plugins,cn=config"
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "alwaysrecordlogin", "yes"))
    modlist.append((ldap.MOD_ADD, "stateattrname", "lastLoginTime"))
    modlist.append((ldap.MOD_ADD, "altstateattrname", "createTimestamp"))
    auth._auth.ldap.modify_s(dn, modlist)

    # Add kolab-admin role
    log.info(_("Adding the kolab-admin role"))
    dn = "cn=kolab-admin,%s" % (_input['rootdn'])
    attrs = {}
    attrs['description'] = "Kolab Administrator"
    attrs['objectClass'] = [
        'top', 'ldapsubentry', 'nsroledefinition', 'nssimpleroledefinition',
        'nsmanagedroledefinition'
    ]
    attrs['cn'] = "kolab-admin"
    ldif = ldap.modlist.addModlist(attrs)

    auth._auth.ldap.add_s(dn, ldif)

    # User writeable attributes on root_dn
    log.info(_("Setting access control to %s") % (_input['rootdn']))
    dn = _input['rootdn']
    aci = []

    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");)'
        )
    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 = "*") (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 "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 "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");)'
    )
    modlist = []
    modlist.append((ldap.MOD_REPLACE, "aci", aci))
    auth._auth.ldap.modify_s(dn, modlist)

    if os.path.isfile('/bin/systemctl'):
        if not os.path.isfile('/usr/lib/systemd/system/dirsrv-admin.service'):
            log.info(_("directory server admin service not available"))
        else:
            subprocess.call(
                ['/bin/systemctl', 'enable', 'dirsrv-admin.service'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'dirsrv-admin', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'dirsrv-admin', 'defaults'])
    else:
        log.error(_("Could not start and configure to start on boot, the " + \
                "directory server admin service."))
Esempio n. 44
0
def group_info():
    group = utils.ask_question("Group email address")
    group = request('GET', 'group.info?group=%s' % (group))
    return group
Esempio n. 45
0
def execute(*args, **kw):
    try:
        email_address = conf.cli_args.pop(0)
    except IndexError, errmsg:
        email_address = utils.ask_question("Email address to remove")
Esempio n. 46
0
def user_info(user=None):
    if user == None:
        user = utils.ask_question("User email address")
    user = request('GET', 'user.info?user=%s' % (user))
    return user
Esempio n. 47
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve

    sieveclient = sievelib.managesieve.Client(hostname, port, conf.debuglevel > 8)
    sieveclient.connect(None, None, True)
    sieveclient._plain_authentication(admin_login, admin_password, address)
    sieveclient.authenticated = True

    result = sieveclient.listscripts()

    if result == None:
        active = None
        scripts = []
    else:
        active, scripts = result

    log.debug(_("Found the following scripts for user %s: %s") % (address, ','.join(scripts)), level=8)
    log.debug(_("And the following script is active for user %s: %s") % (address, active), level=8)

    mgmt_required_extensions = []

    mgmt_script = """#
# MANAGEMENT
#
"""

    user = auth.get_entry_attributes(domain, user, ['*'])

    #
    # Vacation settings (a.k.a. Out of Office)
    #
    vacation_active = None
    vacation_text = None
    vacation_uce = None
    vacation_noreact_domains = None
    vacation_react_domains = None

    vacation_active_attr = conf.get('sieve', 'vacation_active_attr')
    vacation_text_attr = conf.get('sieve', 'vacation_text_attr')
    vacation_uce_attr = conf.get('sieve', 'vacation_uce_attr')
    vacation_noreact_domains_attr = conf.get('sieve', 'vacation_noreact_domains_attr')
    vacation_react_domains_attr = conf.get('sieve', 'vacation_react_domains_attr')

    if not vacation_text_attr == None:

        if user.has_key(vacation_active_attr):
            vacation_active = utils.true_or_false(user[vacation_active_attr])
        else:
            vacation_active = False

        if user.has_key(vacation_text_attr):
            vacation_text = user[vacation_text_attr]
        else:
            vacation_active = False

        if user.has_key(vacation_uce_attr):
            vacation_uce = utils.true_or_false(user[vacation_uce_attr])
        else:
            vacation_uce = False

        if user.has_key(vacation_react_domains_attr):
            if isinstance(user[vacation_react_domains_attr], list):
                vacation_react_domains = user[vacation_react_domains_attr]
            else:
                vacation_react_domains = [ user[vacation_react_domains_attr] ]
        else:
            if user.has_key(vacation_noreact_domains_attr):
                if isinstance(user[vacation_noreact_domains_attr], list):
                    vacation_noreact_domains = user[vacation_noreact_domains_attr]
                else:
                    vacation_noreact_domains = [ user[vacation_noreact_domains_attr] ]
            else:
                vacation_noreact_domains = []

    #
    # Delivery to Folder
    #
    dtf_active_attr = conf.get('sieve', 'deliver_to_folder_active')
    if not dtf_active_attr == None:
        if user.has_key(dtf_active_attr):
            dtf_active = utils.true_or_false(user[dtf_active_attr])
        else:
            dtf_active = False
    else:
        # TODO: Not necessarily de-activated, the *Active attributes are
        # not supposed to charge this - check the deliver_to_folder_attr
        # attribute value for a value.
        dtf_active = False

    if dtf_active:
        dtf_folder_name_attr = conf.get('sieve', 'deliver_to_folder_attr')
        if not dtf_folder_name_attr == None:
            if user.has_key(dtf_folder_name_attr):
                dtf_folder = user[dtf_folder_name_attr]
            else:
                log.warning(_("Delivery to folder active, but no folder name attribute available for user %r") % (user))
                dtf_active = False
        else:
            log.error(_("Delivery to folder active, but no folder name attribute configured"))
            dtf_active = False

    #
    # Folder name to delivery spam to.
    #
    # Global or local.
    #
    sdf_filter = True
    sdf = conf.get('sieve', 'spam_global_folder')

    if sdf == None:
        sdf = conf.get('sieve', 'spam_personal_folder')
        if sdf == None:
            sdf_filter = False

    #
    # Mail forwarding
    #
    forward_active = None
    forward_addresses = []
    forward_keepcopy = None
    forward_uce = None

    forward_active_attr = conf.get('sieve', 'forward_address_active')
    if not forward_active_attr == None:
        if user.has_key(forward_active_attr):
            forward_active = utils.true_or_false(user[forward_active_attr])
        else:
            forward_active = False

    if not forward_active == False:
        forward_address_attr = conf.get('sieve', 'forward_address_attr')
        if user.has_key(forward_address_attr):
            if isinstance(user[forward_address_attr], basestring):
                forward_addresses = [ user[forward_address_attr] ]
            elif isinstance(user[forward_address_attr], str):
                forward_addresses = [ user[forward_address_attr] ]
            else:
                forward_addresses = user[forward_address_attr]

        if len(forward_addresses) == 0:
            forward_active = False

        forward_keepcopy_attr = conf.get('sieve', 'forward_keepcopy_active')
        if not forward_keepcopy_attr == None:
            if user.has_key(forward_keepcopy_attr):
                forward_keepcopy = utils.true_or_false(user[forward_keepcopy_attr])
            else:
                forward_keepcopy = False

        forward_uce_attr = conf.get('sieve', 'forward_uce_active')
        if not forward_uce_attr == None:
            if user.has_key(forward_uce_attr):
                forward_uce = utils.true_or_false(user[forward_uce_attr])
            else:
                forward_uce = False

    if vacation_active:
        mgmt_required_extensions.append('vacation')
        mgmt_required_extensions.append('envelope')

    if dtf_active:
        mgmt_required_extensions.append('fileinto')

    if forward_active and (len(forward_addresses) > 1 or forward_keepcopy):
        mgmt_required_extensions.append('copy')

    if sdf_filter:
        mgmt_required_extensions.append('fileinto')

    import sievelib.factory

    mgmt_script = sievelib.factory.FiltersSet("MANAGEMENT")

    for required_extension in mgmt_required_extensions:
        mgmt_script.require(required_extension)

    mgmt_script.require('fileinto')

    if vacation_active:
        if not vacation_react_domains == None and len(vacation_react_domains) > 0:
            mgmt_script.addfilter(
                    'vacation',
                    [('envelope', ':domain', ":is", "from", vacation_react_domains)],
                    [
                            (
                                    "vacation",
                                    ":days", 1,
                                    ":subject",
                                    "Out of Office",
                                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                                    # ":mime", to indicate the reason is in fact MIME
                                    vacation_text
                                )
                        ]
                )

        elif not vacation_noreact_domains == None and len(vacation_noreact_domains) > 0:
            mgmt_script.addfilter(
                    'vacation',
                    [('not', ('envelope', ':domain', ":is", "from", vacation_noreact_domains))],
                    [
                            (
                                    "vacation",
                                    ":days", 1,
                                    ":subject",
                                    "Out of Office",
                                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                                    # ":mime", to indicate the reason is in fact MIME
                                    vacation_text
                                )
                        ]
                )

        else:
            mgmt_script.addfilter(
                    'vacation',
                    [('true',)],
                    [
                            (
                                    "vacation",
                                    ":days", 1,
                                    ":subject",
                                    "Out of Office",
                                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                                    # ":mime", to indicate the reason is in fact MIME
                                    vacation_text
                                )
                        ]
                )

    if forward_active:
        forward_rules = []

        # Principle can be demonstrated by:
        #
        # python -c "print ','.join(['a','b','c'][:-1])"
        #
        for forward_copy in forward_addresses[:-1]:
            forward_rules.append(("redirect", ":copy", forward_copy))

        if forward_keepcopy:
            # Principle can be demonstrated by:
            #
            # python -c "print ','.join(['a','b','c'][-1])"
            #
            if forward_uce:
                rule_name = 'forward-uce-keepcopy'
            else:
                rule_name = 'forward-keepcopy'

            forward_rules.append(("redirect", ":copy", forward_addresses[-1]))
        else:
            if forward_uce:
                rule_name = 'forward-uce'
            else:
                rule_name = 'forward'

            forward_rules.append(("redirect", forward_addresses[-1]))
            forward_rules.append(("stop"))

        if forward_uce:
            mgmt_script.addfilter(rule_name, ['true'], forward_rules)

        else:
            # NOTE: Messages with no X-Spam-Status header need to be matched
            # too, and this does exactly that.
            mgmt_script.addfilter(rule_name, [("not", ("X-Spam-Status", ":matches", "Yes,*"))], forward_rules)

    if sdf_filter:
        mgmt_script.addfilter('spam_delivery_folder', [("X-Spam-Status", ":matches", "Yes,*")], [("fileinto", "INBOX/Spam"), ("stop")])

    if dtf_active:
        mgmt_script.addfilter('delivery_to_folder', ['true'], [("fileinto", dtf_folder)])

    mgmt_script = mgmt_script.__str__()

    log.debug(_("MANAGEMENT script for user %s contents: %r") % (address,mgmt_script), level=9)

    result = sieveclient.putscript("MANAGEMENT", mgmt_script)

    if not result:
        log.error(_("Uploading script MANAGEMENT failed for user %s") % (address))
    else:
        log.debug(_("Uploading script MANAGEMENT for user %s succeeded") % (address), level=8)

    user_script = """#
# User
#

require ["include"];
"""

    for script in scripts:
        if not script in [ "MASTER", "MANAGEMENT", "USER" ]:
            log.debug(_("Including script %s in USER (for user %s)") % (script,address) ,level=8)
            user_script = """%s

include :personal "%s";
""" % (user_script, script)

    result = sieveclient.putscript("USER", user_script)

    if not result:
        log.error(_("Uploading script USER failed for user %s") % (address))
    else:
        log.debug(_("Uploading script USER for user %s succeeded") % (address), level=8)

    result = sieveclient.putscript("MASTER", """#
# MASTER
#
# This file is authoritative for your system and MUST BE KEPT ACTIVE.
#
# Altering it is likely to render your account dysfunctional and may
# be violating your organizational or corporate policies.
#
# For more information on the mechanism and the conventions behind
# this script, see http://wiki.kolab.org/KEP:14
#

require ["include"];

# OPTIONAL: Includes for all or a group of users
# include :global "all-users";
# include :global "this-group-of-users";

# The script maintained by the general management system
include :personal "MANAGEMENT";

# The script(s) maintained by one or more editors available to the user
include :personal "USER";
""")

    if not result:
        log.error(_("Uploading script MASTER failed for user %s") % (address))
    else:
        log.debug(_("Uploading script MASTER for user %s succeeded") % (address), level=8)

    sieveclient.setactive("MASTER")
Esempio n. 48
0
def resource_info(resource=None):
    if resource == None:
        resource = utils.ask_question("Resource DN")
    return request('GET', 'resource.info', get={ 'id': resource })
Esempio n. 49
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve

    sieveclient = sievelib.managesieve.Client(hostname, port,
                                              conf.debuglevel > 8)
    sieveclient.connect(None, None, True)
    sieveclient._plain_authentication(admin_login, admin_password, address)
    sieveclient.authenticated = True

    result = sieveclient.listscripts()

    if result == None:
        active = None
        scripts = []
    else:
        active, scripts = result

    log.debug(_("Found the following scripts for user %s: %s") %
              (address, ','.join(scripts)),
              level=8)
    log.debug(_("And the following script is active for user %s: %s") %
              (address, active),
              level=8)

    mgmt_required_extensions = []

    mgmt_script = """#
# MANAGEMENT
#
"""

    user = auth.get_entry_attributes(domain, user, ['*'])

    #
    # Vacation settings (a.k.a. Out of Office)
    #
    vacation_active = None
    vacation_text = None
    vacation_uce = None
    vacation_noreact_domains = None
    vacation_react_domains = None

    vacation_active_attr = conf.get('sieve', 'vacation_active_attr')
    vacation_text_attr = conf.get('sieve', 'vacation_text_attr')
    vacation_uce_attr = conf.get('sieve', 'vacation_uce_attr')
    vacation_noreact_domains_attr = conf.get('sieve',
                                             'vacation_noreact_domains_attr')
    vacation_react_domains_attr = conf.get('sieve',
                                           'vacation_react_domains_attr')

    if not vacation_text_attr == None:

        if user.has_key(vacation_active_attr):
            vacation_active = utils.true_or_false(user[vacation_active_attr])
        else:
            vacation_active = False

        if user.has_key(vacation_text_attr):
            vacation_text = user[vacation_text_attr]
        else:
            vacation_active = False

        if user.has_key(vacation_uce_attr):
            vacation_uce = utils.true_or_false(user[vacation_uce_attr])
        else:
            vacation_uce = False

        if user.has_key(vacation_react_domains_attr):
            if isinstance(user[vacation_react_domains_attr], list):
                vacation_react_domains = user[vacation_react_domains_attr]
            else:
                vacation_react_domains = [user[vacation_react_domains_attr]]
        else:
            if user.has_key(vacation_noreact_domains_attr):
                if isinstance(user[vacation_noreact_domains_attr], list):
                    vacation_noreact_domains = user[
                        vacation_noreact_domains_attr]
                else:
                    vacation_noreact_domains = [
                        user[vacation_noreact_domains_attr]
                    ]
            else:
                vacation_noreact_domains = []

    #
    # Delivery to Folder
    #
    dtf_active_attr = conf.get('sieve', 'deliver_to_folder_active')
    if not dtf_active_attr == None:
        if user.has_key(dtf_active_attr):
            dtf_active = utils.true_or_false(user[dtf_active_attr])
        else:
            dtf_active = False
    else:
        # TODO: Not necessarily de-activated, the *Active attributes are
        # not supposed to charge this - check the deliver_to_folder_attr
        # attribute value for a value.
        dtf_active = False

    if dtf_active:
        dtf_folder_name_attr = conf.get('sieve', 'deliver_to_folder_attr')
        if not dtf_folder_name_attr == None:
            if user.has_key(dtf_folder_name_attr):
                dtf_folder = user[dtf_folder_name_attr]
            else:
                log.warning(
                    _("Delivery to folder active, but no folder name attribute available for user %r"
                      ) % (user))
                dtf_active = False
        else:
            log.error(
                _("Delivery to folder active, but no folder name attribute configured"
                  ))
            dtf_active = False

    #
    # Folder name to delivery spam to.
    #
    # Global or local.
    #
    sdf_filter = True
    sdf = conf.get('sieve', 'spam_global_folder')

    if sdf == None:
        sdf = conf.get('sieve', 'spam_personal_folder')
        if sdf == None:
            sdf_filter = False

    #
    # Mail forwarding
    #
    forward_active = None
    forward_addresses = []
    forward_keepcopy = None
    forward_uce = None

    forward_active_attr = conf.get('sieve', 'forward_address_active')
    if not forward_active_attr == None:
        if user.has_key(forward_active_attr):
            forward_active = utils.true_or_false(user[forward_active_attr])
        else:
            forward_active = False

    if not forward_active == False:
        forward_address_attr = conf.get('sieve', 'forward_address_attr')
        if user.has_key(forward_address_attr):
            if isinstance(user[forward_address_attr], basestring):
                forward_addresses = [user[forward_address_attr]]
            elif isinstance(user[forward_address_attr], str):
                forward_addresses = [user[forward_address_attr]]
            else:
                forward_addresses = user[forward_address_attr]

        if len(forward_addresses) == 0:
            forward_active = False

        forward_keepcopy_attr = conf.get('sieve', 'forward_keepcopy_active')
        if not forward_keepcopy_attr == None:
            if user.has_key(forward_keepcopy_attr):
                forward_keepcopy = utils.true_or_false(
                    user[forward_keepcopy_attr])
            else:
                forward_keepcopy = False

        forward_uce_attr = conf.get('sieve', 'forward_uce_active')
        if not forward_uce_attr == None:
            if user.has_key(forward_uce_attr):
                forward_uce = utils.true_or_false(user[forward_uce_attr])
            else:
                forward_uce = False

    if vacation_active:
        mgmt_required_extensions.append('vacation')
        mgmt_required_extensions.append('envelope')

    if dtf_active:
        mgmt_required_extensions.append('fileinto')

    if forward_active and (len(forward_addresses) > 1 or forward_keepcopy):
        mgmt_required_extensions.append('copy')

    if sdf_filter:
        mgmt_required_extensions.append('fileinto')

    import sievelib.factory

    mgmt_script = sievelib.factory.FiltersSet("MANAGEMENT")

    for required_extension in mgmt_required_extensions:
        mgmt_script.require(required_extension)

    mgmt_script.require('fileinto')

    if vacation_active:
        if not vacation_react_domains == None and len(
                vacation_react_domains) > 0:
            mgmt_script.addfilter(
                'vacation',
                [('envelope', ':domain', ":is", "from", vacation_react_domains)
                 ],
                [(
                    "vacation",
                    ":days",
                    1,
                    ":subject",
                    "Out of Office",
                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                    # ":mime", to indicate the reason is in fact MIME
                    vacation_text)])

        elif not vacation_noreact_domains == None and len(
                vacation_noreact_domains) > 0:
            mgmt_script.addfilter(
                'vacation',
                [('not', ('envelope', ':domain', ":is", "from",
                          vacation_noreact_domains))],
                [(
                    "vacation",
                    ":days",
                    1,
                    ":subject",
                    "Out of Office",
                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                    # ":mime", to indicate the reason is in fact MIME
                    vacation_text)])

        else:
            mgmt_script.addfilter(
                'vacation',
                [('true', )],
                [(
                    "vacation",
                    ":days",
                    1,
                    ":subject",
                    "Out of Office",
                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                    # ":mime", to indicate the reason is in fact MIME
                    vacation_text)])

    if forward_active:
        forward_rules = []

        # Principle can be demonstrated by:
        #
        # python -c "print ','.join(['a','b','c'][:-1])"
        #
        for forward_copy in forward_addresses[:-1]:
            forward_rules.append(("redirect", ":copy", forward_copy))

        if forward_keepcopy:
            # Principle can be demonstrated by:
            #
            # python -c "print ','.join(['a','b','c'][-1])"
            #
            if forward_uce:
                rule_name = 'forward-uce-keepcopy'
            else:
                rule_name = 'forward-keepcopy'

            forward_rules.append(("redirect", ":copy", forward_addresses[-1]))
        else:
            if forward_uce:
                rule_name = 'forward-uce'
            else:
                rule_name = 'forward'

            forward_rules.append(("redirect", forward_addresses[-1]))
            forward_rules.append(("stop"))

        if forward_uce:
            mgmt_script.addfilter(rule_name, ['true'], forward_rules)

        else:
            # NOTE: Messages with no X-Spam-Status header need to be matched
            # too, and this does exactly that.
            mgmt_script.addfilter(rule_name,
                                  [("not",
                                    ("X-Spam-Status", ":matches", "Yes,*"))],
                                  forward_rules)

    if sdf_filter:
        mgmt_script.addfilter('spam_delivery_folder',
                              [("X-Spam-Status", ":matches", "Yes,*")],
                              [("fileinto", "INBOX/Spam"), ("stop")])

    if dtf_active:
        mgmt_script.addfilter('delivery_to_folder', ['true'],
                              [("fileinto", dtf_folder)])

    mgmt_script = mgmt_script.__str__()

    log.debug(_("MANAGEMENT script for user %s contents: %r") %
              (address, mgmt_script),
              level=9)

    result = sieveclient.putscript("MANAGEMENT", mgmt_script)

    if not result:
        log.error(
            _("Uploading script MANAGEMENT failed for user %s") % (address))
    else:
        log.debug(_("Uploading script MANAGEMENT for user %s succeeded") %
                  (address),
                  level=8)

    user_script = """#
# User
#

require ["include"];
"""

    for script in scripts:
        if not script in ["MASTER", "MANAGEMENT", "USER"]:
            log.debug(_("Including script %s in USER (for user %s)") %
                      (script, address),
                      level=8)
            user_script = """%s

include :personal "%s";
""" % (user_script, script)

    result = sieveclient.putscript("USER", user_script)

    if not result:
        log.error(_("Uploading script USER failed for user %s") % (address))
    else:
        log.debug(_("Uploading script USER for user %s succeeded") % (address),
                  level=8)

    result = sieveclient.putscript(
        "MASTER", """#
# MASTER
#
# This file is authoritative for your system and MUST BE KEPT ACTIVE.
#
# Altering it is likely to render your account dysfunctional and may
# be violating your organizational or corporate policies.
#
# For more information on the mechanism and the conventions behind
# this script, see http://wiki.kolab.org/KEP:14
#

require ["include"];

# OPTIONAL: Includes for all or a group of users
# include :global "all-users";
# include :global "this-group-of-users";

# The script maintained by the general management system
include :personal "MANAGEMENT";

# The script(s) maintained by one or more editors available to the user
include :personal "USER";
""")

    if not result:
        log.error(_("Uploading script MASTER failed for user %s") % (address))
    else:
        log.debug(_("Uploading script MASTER for user %s succeeded") %
                  (address),
                  level=8)

    sieveclient.setactive("MASTER")
Esempio n. 50
0
def group_members_list(group=None):
    if group == None:
        group = utils.ask_question("Group email address")
    group = request('GET', 'group.members_list?group=%s' % (group))
    return group
Esempio n. 51
0
def execute(*args, **kw):
    schema_files = []
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        for directory in directories:
            if directory.startswith("kolab-syncroton"):
                for root, directories, filenames in os.walk(os.path.join(root, directory)):
                    for filename in filenames:
                        if filename.startswith('mysql.initial') and filename.endswith('.sql'):
                            schema_filepath = os.path.join(root,filename)
                            if not schema_filepath in schema_files:
                                schema_files.append(schema_filepath)
                                break

                if len(schema_files) > 0:
                    break
        if len(schema_files) > 0:
            break

    if not os.path.isfile('/tmp/kolab-setup-my.cnf'):
        utils.multiline_message(
                """Please supply the MySQL root password"""
            )

        mysql_root_password = utils.ask_question(
                _("MySQL root password"),
                password=True
            )

        data = """
[mysql]
user=root
password='******'
""" % (mysql_root_password)

        fp = open('/tmp/kolab-setup-my.cnf', 'w')
        os.chmod('/tmp/kolab-setup-my.cnf', 0600)
        fp.write(data)
        fp.close()

    for schema_file in schema_files:
        p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'roundcube'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

    time.sleep(2)

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'restart', 'httpd.service'])
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['/sbin/service', 'httpd', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service','apache2','restart'])
    else:
        log.error(_("Could not start the webserver server service."))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'enable', 'httpd.service'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'httpd', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'apache2', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "webserver server service."))
Esempio n. 52
0
def execute(*args, **kw):
    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'restart', 'mysqld.service'])
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['/sbin/service', 'mysqld', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service','mysql','restart'])
    else:
        log.error(_("Could not start the MySQL database service."))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'enable', 'mysqld.service'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'mysqld', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'mysql', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "MySQL database service."))

    options = {
            1: "Existing MySQL server (with root password already set).",
            2: "New MySQL server (needs to be initialized)."
        }

    answer = 0
    if os.path.exists('/var/run/mysqld/mysqld.sock'):
        answer = utils.ask_menu(_("What MySQL server are we setting up?"), options)

    if answer == "1" or answer == 1:
        print >> sys.stderr, utils.multiline_message(
                _("""
                        Please supply the root password for MySQL, so we can set
                        up user accounts for other components that use MySQL.
                    """)
            )

        mysql_root_password = utils.ask_question(
                _("MySQL root password"),
                password=True
            )

    else:
        print >> sys.stderr, utils.multiline_message(
                _("""
                        Please supply a root password for MySQL. This password
                        will be the administrative user for this MySQL server,
                        and it should be kept a secret. After this setup process
                        has completed, Kolab is going to discard and forget
                        about this password, but you will need it for
                        administrative tasks in MySQL.
                    """)
            )

        mysql_root_password = utils.ask_question(
                _("MySQL root password"),
                default=utils.generate_password(),
                password=True,
                confirm=True
            )

        p1 = subprocess.Popen(['echo', 'UPDATE mysql.user SET Password=PASSWORD(\'%s\') WHERE User=\'root\';' % (mysql_root_password)], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

        p1 = subprocess.Popen(['echo', 'FLUSH PRIVILEGES;'], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

    data = """
[mysql]
user=root
password='******'
""" % (mysql_root_password)

    fp = open('/tmp/kolab-setup-my.cnf', 'w')
    os.chmod('/tmp/kolab-setup-my.cnf', 0600)
    fp.write(data)
    fp.close()

    schema_file = None
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        for filename in filenames:
            if filename.startswith('kolab_wap') and filename.endswith('.sql'):
                schema_file = os.path.join(root,filename)

    if not schema_file == None:
        p1 = subprocess.Popen(['echo', 'create database kolab;'], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

        print >> sys.stderr, utils.multiline_message(
                _("""
                        Please supply a password for the MySQL user 'kolab'.
                        This password will be used by Kolab services, such as
                        the Web Administration Panel.
                    """)
            )

        mysql_kolab_password = utils.ask_question(
                _("MySQL kolab password"),
                default=utils.generate_password(),
                password=True,
                confirm=True
            )

        p1 = subprocess.Popen(['echo', 'GRANT ALL PRIVILEGES ON kolab.* TO \'kolab\'@\'localhost\' IDENTIFIED BY \'%s\';' % (mysql_kolab_password)], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

        p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'kolab'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

        conf.command_set('kolab_wap', 'sql_uri', 'mysql://*****:*****@localhost/kolab' % (mysql_kolab_password))
    else:
        log.warning(_("Could not find the MySQL Kolab schema file"))
Esempio n. 53
0
def execute(*args, **kw):
    print >> sys.stderr, utils.multiline_message(
        _("""
                    Please supply a password for the MySQL user 'roundcube'.
                    This password will be used by the Roundcube webmail
                    interface.
                """))

    mysql_roundcube_password = utils.ask_question(
        _("MySQL roundcube password"),
        default=utils.generate_password(),
        password=True,
        confirm=True)

    conf.mysql_roundcube_password = mysql_roundcube_password

    rc_settings = {
        'des_key':
        re.sub(
            r'[^a-zA-Z0-9]', "", "%s%s" %
            (hashlib.md5("%s" % random.random()).digest().encode("base64"),
             hashlib.md5(
                 "%s" % random.random()).digest().encode("base64")))[:24],
        'imap_admin_login':
        conf.get('cyrus-imap', 'admin_login'),
        'imap_admin_password':
        conf.get('cyrus-imap', 'admin_password'),
        'ldap_base_dn':
        conf.get('ldap', 'base_dn'),
        'ldap_group_base_dn':
        conf.get('ldap', 'group_base_dn'),
        'ldap_group_filter':
        conf.get('ldap', 'group_filter'),
        'ldap_ldap_uri':
        conf.get('ldap', 'ldap_uri'),
        'ldap_resource_base_dn':
        conf.get('ldap', 'resource_base_dn'),
        'ldap_resource_filter':
        conf.get('ldap', 'resource_filter'),
        'ldap_service_bind_dn':
        conf.get('ldap', 'service_bind_dn'),
        'ldap_service_bind_pw':
        conf.get('ldap', 'service_bind_pw'),
        'ldap_user_base_dn':
        conf.get('ldap', 'user_base_dn'),
        'ldap_user_filter':
        conf.get('ldap', 'user_filter'),
        'primary_domain':
        conf.get('kolab', 'primary_domain'),
        'mysql_uri':
        'mysqli://*****:*****@localhost/roundcube' %
        (mysql_roundcube_password),
        'conf':
        conf
    }

    rc_paths = [
        "/usr/share/roundcubemail/", "/usr/share/roundcube/",
        "/srv/www/roundcubemail/", "/var/www/roundcubemail/"
    ]

    rcpath = ''
    for rc_path in rc_paths:
        if os.path.isdir(rc_path):
            rcpath = rc_path
            break

    if not os.path.isdir(rcpath):
        log.error(_("Roundcube installation path not found."))
        return

    if os.access(rcpath + 'skins/enterprise/', os.R_OK):
        rc_settings['skin'] = 'enterprise'
    elif os.access(rcpath + 'skins/chameleon/', os.R_OK):
        rc_settings['skin'] = 'chameleon'
    else:
        rc_settings['skin'] = 'larry'

    want_files = [
        'acl.inc.php', 'calendar.inc.php', 'config.inc.php',
        'kolab_addressbook.inc.php', 'kolab_auth.inc.php',
        'kolab_delegation.inc.php', 'kolab_files.inc.php',
        'kolab_folders.inc.php', 'libkolab.inc.php', 'managesieve.inc.php',
        'owncloud.inc.php', 'password.inc.php', 'recipient_to_contact.inc.php',
        'terms.html', 'terms.inc.php'
    ]

    for want_file in want_files:
        template_file = None
        if os.path.isfile('/etc/kolab/templates/roundcubemail/%s.tpl' %
                          (want_file)):
            template_file = '/etc/kolab/templates/roundcubemail/%s.tpl' % (
                want_file)
        elif os.path.isfile('/usr/share/kolab/templates/roundcubemail/%s.tpl' %
                            (want_file)):
            template_file = '/usr/share/kolab/templates/roundcubemail/%s.tpl' % (
                want_file)
        elif os.path.isfile(
                os.path.abspath(
                    os.path.join(__file__, '..', '..', '..', 'share',
                                 'templates', 'roundcubemail',
                                 '%s.tpl' % (want_file)))):
            template_file = os.path.abspath(
                os.path.join(__file__, '..', '..', '..', 'share', 'templates',
                             'roundcubemail', '%s.tpl' % (want_file)))

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

            t = Template(template_definition, searchList=[rc_settings])
            log.debug(
                _("Successfully compiled template %r, writing out to %r") %
                (template_file, want_file),
                level=8)

            fp = None
            if os.path.isdir('/etc/roundcubemail'):
                fp = open('/etc/roundcubemail/%s' % (want_file), 'w')
            elif os.path.isdir('/etc/roundcube'):
                fp = open('/etc/roundcube/%s' % (want_file), 'w')

            if not fp == None:
                fp.write(t.__str__())
                fp.close()

    schema_files = []
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        directories.sort()
        for directory in directories:
            if directory.startswith("roundcubemail"):
                for nested_root, nested_directories, nested_filenames in os.walk(
                        os.path.join(root, directory)):
                    for filename in nested_filenames:
                        if filename.startswith(
                                'mysql.initial') and filename.endswith('.sql'):
                            schema_filepath = os.path.join(
                                nested_root, filename)
                            if not schema_filepath in schema_files:
                                schema_files.append(schema_filepath)

                if len(schema_files) > 0:
                    break
        if len(schema_files) > 0:
            break

    for root, directories, filenames in os.walk(
            rcpath + 'plugins/calendar/drivers/kolab/'):
        for filename in filenames:
            if filename.startswith('mysql') and filename.endswith('.sql'):
                schema_filepath = os.path.join(root, filename)
                if not schema_filepath in schema_files:
                    schema_files.append(schema_filepath)

    for root, directories, filenames in os.walk(rcpath + 'plugins/libkolab/'):
        for filename in filenames:
            if filename.startswith('mysql') and filename.endswith('.sql'):
                schema_filepath = os.path.join(root, filename)
                if not schema_filepath in schema_files:
                    schema_files.append(schema_filepath)

    for root, directories, filenames in os.walk('/usr/share/doc/'):
        directories.sort()
        for directory in directories:
            if directory.startswith("chwala"):
                for nested_root, nested_directories, nested_filenames in os.walk(
                        os.path.join(root, directory)):
                    for filename in nested_filenames:
                        if filename.startswith(
                                'mysql.initial') and filename.endswith('.sql'):
                            schema_filepath = os.path.join(
                                nested_root, filename)
                            if not schema_filepath in schema_files:
                                schema_files.append(schema_filepath)

                if len(schema_files) > 0:
                    break
        if len(schema_files) > 0:
            break

    if not os.path.isfile('/tmp/kolab-setup-my.cnf'):
        utils.multiline_message("""Please supply the MySQL root password""")

        mysql_root_password = utils.ask_question(_("MySQL root password"),
                                                 password=True)

        data = """
[mysql]
user=root
password='******'
""" % (mysql_root_password)

        fp = open('/tmp/kolab-setup-my.cnf', 'w')
        os.chmod('/tmp/kolab-setup-my.cnf', 0600)
        fp.write(data)
        fp.close()

    p1 = subprocess.Popen(['echo', 'create database roundcube;'],
                          stdout=subprocess.PIPE)
    p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'],
                          stdin=p1.stdout)
    p1.stdout.close()
    p2.communicate()

    p1 = subprocess.Popen([
        'echo',
        'GRANT ALL PRIVILEGES ON roundcube.* TO \'roundcube\'@\'localhost\' IDENTIFIED BY \'%s\';'
        % (mysql_roundcube_password)
    ],
                          stdout=subprocess.PIPE)
    p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'],
                          stdin=p1.stdout)
    p1.stdout.close()
    p2.communicate()

    for schema_file in schema_files:
        p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(
            ['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'roundcube'],
            stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

    p1 = subprocess.Popen(['echo', 'FLUSH PRIVILEGES;'],
                          stdout=subprocess.PIPE)
    p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'],
                          stdin=p1.stdout)
    p1.stdout.close()
    p2.communicate()

    time.sleep(2)

    # Find Roundcube configuration that is not readable by the
    # webserver user/group.
    if os.path.isdir('/etc/roundcubemail/'):
        rccpath = "/etc/roundcubemail/"
    elif os.path.isdir('/etc/roundcube/'):
        rccpath = "/etc/roundcube"
    else:
        log.warning(
            _("Cannot find the configuration directory for roundcube."))
        rccpath = None

    root_uid = 0

    webserver_gid = None

    for webserver_group in ['apache', 'www-data', 'www']:
        try:
            (a, b, webserver_gid, c) = grp.getgrnam(webserver_group)
            break
        except Exception, errmsg:
            pass
Esempio n. 54
0
def group_info(group=None):
    if group == None:
        group = utils.ask_question("group DN")
    return request('GET', 'group.info', get={ 'id': group })
Esempio n. 55
0
def execute(*args, **kw):
    schema_files = []
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        for directory in directories:
            if directory.startswith("kolab-syncroton"):
                for root, directories, filenames in os.walk(os.path.join(root, directory)):
                    for filename in filenames:
                        if filename.startswith('mysql.initial') and filename.endswith('.sql'):
                            schema_filepath = os.path.join(root,filename)
                            if not schema_filepath in schema_files:
                                schema_files.append(schema_filepath)
                                break

                if len(schema_files) > 0:
                    break
        if len(schema_files) > 0:
            break

    if not os.path.isfile('/tmp/kolab-setup-my.cnf'):
        utils.multiline_message(
                """Please supply the MySQL root password"""
            )

        mysql_root_password = utils.ask_question(
                _("MySQL root password"),
                password=True
            )

        data = """
[mysql]
user=root
password='******'
""" % (mysql_root_password)

        fp = open('/tmp/kolab-setup-my.cnf', 'w')
        os.chmod('/tmp/kolab-setup-my.cnf', 0600)
        fp.write(data)
        fp.close()

    for schema_file in schema_files:
        p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'roundcube'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

    time.sleep(2)

    httpservice = 'httpd.service'

    if os.path.isfile('/usr/lib/systemd/system/apache2.service'):
        httpservice = 'apache2.service'

    if os.path.isdir('/lib/systemd/system/apache2.service.d'):
        httpservice = 'apache2.service'

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'restart', httpservice])
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['/sbin/service', 'httpd', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service','apache2','restart'])
    else:
        log.error(_("Could not start the webserver server service."))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'enable', httpservice])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'httpd', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'apache2', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "webserver server service."))
Esempio n. 56
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve

    sieveclient = sievelib.managesieve.Client(hostname, port,
                                              conf.debuglevel > 8)

    sieveclient.connect(None, None, True)

    result = sieveclient._plain_authentication(admin_login, admin_password,
                                               address)

    if not result:
        print "LOGIN FAILED??"

    sieveclient.authenticated = True

    result = sieveclient.listscripts()

    if result == None:
        print "No scripts"
        sys.exit(0)

    (active, scripts) = result

    print "%s (active)" % (active)
    for script in scripts:
        print script
Esempio n. 57
0
def execute(*args, **kw):
    print >> sys.stderr, utils.multiline_message(
            _("""
                    Please supply a password for the MySQL user 'roundcube'.
                    This password will be used by the Roundcube webmail
                    interface.
                """)
        )

    mysql_roundcube_password = utils.ask_question(
            _("MySQL roundcube password"),
            default=utils.generate_password(),
            password=True,
            confirm=True
        )

    conf.mysql_roundcube_password = mysql_roundcube_password

    rc_settings = {
            'des_key': re.sub(
                    r'[^a-zA-Z0-9]',
                    "",
                    "%s%s" % (
                            hashlib.md5("%s" % random.random()).digest().encode("base64"),
                            hashlib.md5("%s" % random.random()).digest().encode("base64")
                        )
                )[:24],

            'imap_admin_login': conf.get('cyrus-imap', 'admin_login'),
            'imap_admin_password': conf.get('cyrus-imap', 'admin_password'),
            'ldap_base_dn': conf.get('ldap', 'base_dn'),
            'ldap_group_base_dn': conf.get('ldap', 'group_base_dn'),
            'ldap_group_filter': conf.get('ldap', 'group_filter'),
            'ldap_ldap_uri': conf.get('ldap', 'ldap_uri'),
            'ldap_service_bind_dn': conf.get('ldap', 'service_bind_dn'),
            'ldap_service_bind_pw': conf.get('ldap', 'service_bind_pw'),
            'ldap_user_base_dn': conf.get('ldap', 'user_base_dn'),
            'ldap_user_filter': conf.get('ldap', 'user_filter'),
            'mysql_uri': 'mysqli://*****:*****@localhost/roundcube' % (mysql_roundcube_password),
            'conf': conf
        }


    want_files = [
            'acl.inc.php',
            'calendar.inc.php',
            'db.inc.php',
            'kolab_auth.inc.php',
            'kolab_folders.inc.php',
            'kolab.inc.php',
            'main.inc.php',
            'managesieve.inc.php',
            'owncloud.inc.php',
            'password.inc.php',
            'recipient_to_contact.inc.php',
            'terms.html',
            'terms.inc.php'
        ]

    for want_file in want_files:
        template_file = None
        if os.path.isfile('/etc/kolab/templates/roundcubemail/%s.tpl' % (want_file)):
            template_file = '/etc/kolab/templates/roundcubemail/%s.tpl' % (want_file)
        elif os.path.isfile('/usr/share/kolab/templates/roundcubemail/%s.tpl' % (want_file)):
            template_file = '/usr/share/kolab/templates/roundcubemail/%s.tpl' % (want_file)
        elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'roundcubemail', '%s.tpl' % (want_file)))):
            template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'roundcubemail', '%s.tpl' % (want_file)))

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

            t = Template(template_definition, searchList=[rc_settings])
            log.debug(
                    _("Successfully compiled template %r, writing out to %r") % (template_file, want_file),
                    level=8
                )
            if os.path.isdir('/etc/roundcubemail'):
                fp = open('/etc/roundcubemail/%s' % (want_file), 'w')
            elif os.path.isdir('/etc/roundcube'):
                fp = open('/etc/roundcube/%s' % (want_file), 'w')
            fp.write(t.__str__())
            fp.close()

    schema_files = []
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        for filename in filenames:
            if filename.startswith('mysql.initial') and filename.endswith('.sql'):
                schema_filepath = os.path.join(root,filename)
                if not schema_filepath in schema_files:
                    schema_files.append(schema_filepath)

            if filename.startswith('horde_cache') and filename.endswith('.sql'):
                schema_filepath = os.path.join(root,filename)
                if not schema_filepath in schema_files:
                    schema_files.append(schema_filepath)

    if os.path.isdir('/usr/share/roundcubemail'):
        rcpath = '/usr/share/roundcubemail/'
    elif os.path.isdir('/usr/share/roundcube'):
        rcpath = '/usr/share/roundcube/'
    for root, directories, filenames in os.walk(rcpath + 'plugins/calendar/drivers/kolab/'):
        for filename in filenames:
            if filename.startswith('mysql') and filename.endswith('.sql'):
                schema_filepath = os.path.join(root,filename)
                if not schema_filepath in schema_files:
                    schema_files.append(schema_filepath)

    for root, directories, filenames in os.walk(rcpath + 'plugins/libkolab/'):
        for filename in filenames:
            if filename.startswith('mysql') and filename.endswith('.sql'):
                schema_filepath = os.path.join(root,filename)
                if not schema_filepath in schema_files:
                    schema_files.append(schema_filepath)

    p1 = subprocess.Popen(['echo', 'create database roundcube;'], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
    p1.stdout.close()
    p2.communicate()

    p1 = subprocess.Popen(['echo', 'GRANT ALL PRIVILEGES ON roundcube.* TO \'roundcube\'@\'localhost\' IDENTIFIED BY \'%s\';' % (mysql_roundcube_password)], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
    p1.stdout.close()
    p2.communicate()

    for schema_file in schema_files:
        p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'roundcube'], stdin=p1.stdout)
        p1.stdout.close()
        p2.communicate()

    p1 = subprocess.Popen(['echo', 'FLUSH PRIVILEGES;'], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout)
    p1.stdout.close()
    p2.communicate()

    time.sleep(2)

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'restart', 'httpd.service'])
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['/sbin/service', 'httpd', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service','apache2','restart'])
    else:
        log.error(_("Could not start the webserver server service."))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['/bin/systemctl', 'enable', 'httpd.service'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['/sbin/chkconfig', 'httpd', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'apache2', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "webserver server service."))