Beispiel #1
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()
Beispiel #2
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()
Beispiel #3
0
def execute(*args, **kw):

    group_filter = conf.get('ldap', 'kolab_group_filter')
    if group_filter == None:
        group_filter = conf.get('ldap', 'group_filter')

    user_filter = conf.get('ldap', 'kolab_user_filter')
    if user_filter == None:
        user_filter = conf.get('ldap', 'user_filter')

    resource_filter = conf.get('ldap', 'resource_filter')

    sharedfolder_filter = conf.get('ldap', 'sharedfolder_filter')

    server_host = utils.parse_ldap_uri(conf.get('ldap', 'ldap_uri'))[1]

    files = {
        "/etc/postfix/ldap/local_recipient_maps.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mail=%%s)(alias=%%s))(|%(kolab_user_filter)s%(kolab_group_filter)s%(resource_filter)s%(sharedfolder_filter)s))
result_attribute = mail
""" % {
            "base_dn": conf.get('ldap', 'base_dn'),
            "server_host": server_host,
            "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
            "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
            "kolab_user_filter": user_filter,
            "kolab_group_filter": group_filter,
            "resource_filter": resource_filter,
            "sharedfolder_filter": sharedfolder_filter,
        },
        "/etc/postfix/ldap/mydestination.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(domain_base_dn)s
scope = sub

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = %(domain_filter)s
result_attribute = %(domain_name_attribute)s
""" % {
            "server_host": server_host,
            "domain_base_dn": conf.get('ldap', 'domain_base_dn'),
            "domain_filter": conf.get('ldap', 'domain_filter').replace(
                '*', '%s'),
            "domain_name_attribute": conf.get('ldap', 'domain_name_attribute'),
            "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
            "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
        },
        "/etc/postfix/ldap/mailenabled_distgroups.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(group_base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

# This finds the mail enabled distribution group LDAP entry
query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectclass=groupofuniquenames)(!(objectclass=groupofurls)))
# From this type of group, get all uniqueMember DNs
special_result_attribute = uniqueMember
# Only from those DNs, get the mail
result_attribute =
leaf_result_attribute = mail
""" % {
            "server_host": server_host,
            "group_base_dn": conf.get('ldap', 'group_base_dn'),
            "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
            "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
        },
        "/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(group_base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

# This finds the mail enabled dynamic distribution group LDAP entry
query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectClass=groupOfURLs))
# From this type of group, get all memberURL searches/references
special_result_attribute = memberURL
# Only from those DNs, get the mail
result_attribute =
leaf_result_attribute = mail
""" % {
            "server_host": server_host,
            "group_base_dn": conf.get('ldap', 'group_base_dn'),
            "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
            "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
        },
        "/etc/postfix/ldap/transport_maps.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mailAlternateAddress=%%s)(alias=%%s)(mail=%%s))(objectclass=kolabinetorgperson))
result_attribute = mail
result_format = lmtp:unix:/var/lib/imap/socket/lmtp
""" % {
            "base_dn": conf.get('ldap', 'base_dn'),
            "server_host": server_host,
            "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
            "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
        },
        "/etc/postfix/ldap/virtual_alias_maps.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabinetorgperson))
result_attribute = mail
""" % {
            "base_dn": conf.get('ldap', 'base_dn'),
            "server_host": server_host,
            "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
            "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
        },
        "/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=mailrecipient)(objectclass=inetorgperson)(mailforwardingaddress=*))
result_attribute = mailForwardingAddress
""" % {
            "base_dn": conf.get('ldap', 'base_dn'),
            "server_host": server_host,
            "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
            "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
        },
        "/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabsharedfolder)(kolabFolderType=mail))
result_attribute = kolabtargetfolder
result_format = "shared+%%s"
""" % {
            "base_dn": conf.get('ldap', 'base_dn'),
            "server_host": server_host,
            "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
            "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
        },
    }

    if not os.path.isdir('/etc/postfix/ldap'):
        os.mkdir('/etc/postfix/ldap/', 0770)

    for filename in files.keys():
        fp = open(filename, 'w')
        fp.write(files[filename])
        fp.close()

    fp = open('/etc/postfix/transport', 'a')
    fp.write(
        "\n# Shared Folder Delivery for %(domain)s:\nshared@%(domain)s\t\tlmtp:unix:/var/lib/imap/socket/lmtp\n"
        % {'domain': conf.get('kolab', 'primary_domain')})
    fp.close()

    subprocess.call(["postmap", "/etc/postfix/transport"])

    postfix_main_settings = {
        "inet_interfaces": "all",
        "recipient_delimiter": "+",
        "local_recipient_maps":
        "ldap:/etc/postfix/ldap/local_recipient_maps.cf",
        "mydestination": "ldap:/etc/postfix/ldap/mydestination.cf",
        "transport_maps":
        "ldap:/etc/postfix/ldap/transport_maps.cf, hash:/etc/postfix/transport",
        "virtual_alias_maps":
        "$alias_maps, ldap:/etc/postfix/ldap/virtual_alias_maps.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf, ldap:/etc/postfix/ldap/mailenabled_distgroups.cf, ldap:/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf",
        "smtpd_tls_auth_only": "yes",
        "smtpd_tls_security_level": "may",
        "smtp_tls_security_level": "may",
        "smtpd_sasl_auth_enable": "yes",
        "smtpd_sender_login_maps": "$local_recipient_maps",
        "smtpd_data_restrictions":
        "permit_mynetworks, check_policy_service unix:private/recipient_policy_incoming",
        "smtpd_recipient_restrictions":
        "permit_mynetworks, reject_unauth_pipelining, reject_rbl_client zen.spamhaus.org, reject_non_fqdn_recipient, reject_invalid_helo_hostname, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service unix:private/recipient_policy_incoming, permit",
        "smtpd_sender_restrictions":
        "permit_mynetworks, reject_sender_login_mismatch, check_policy_service unix:private/sender_policy_incoming",
        "submission_recipient_restrictions":
        "check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject",
        "submission_sender_restrictions":
        "reject_non_fqdn_sender, check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject",
        "submission_data_restrictions":
        "check_policy_service unix:private/submission_policy",
        "content_filter": "smtp-amavis:[127.0.0.1]:10024"
    }

    if os.path.isfile(
            '/etc/pki/tls/certs/make-dummy-cert'
    ) and not os.path.isfile('/etc/pki/tls/private/localhost.pem'):
        subprocess.call([
            '/etc/pki/tls/certs/make-dummy-cert',
            '/etc/pki/tls/private/localhost.pem'
        ])

    if os.path.isfile('/etc/pki/tls/private/localhost.pem'):
        postfix_main_settings[
            'smtpd_tls_cert_file'] = "/etc/pki/tls/private/localhost.pem"
        postfix_main_settings[
            'smtpd_tls_key_file'] = "/etc/pki/tls/private/localhost.pem"

    if not os.path.isfile('/etc/postfix/main.cf'):
        if os.path.isfile('/usr/share/postfix/main.cf.debian'):
            shutil.copy('/usr/share/postfix/main.cf.debian',
                        '/etc/postfix/main.cf')

    # Copy header checks files
    for hc_file in ['inbound', 'internal', 'submission']:
        if not os.path.isfile("/etc/postfix/header_checks.%s" % (hc_file)):
            if os.path.isfile('/etc/kolab/templates/header_checks.%s' %
                              (hc_file)):
                input_file = '/etc/kolab/templates/header_checks.%s' % (
                    hc_file)
            elif os.path.isfile('/usr/share/kolab/templates/header_checks.%s' %
                                (hc_file)):
                input_file = '/usr/share/kolab/templates/header_checks.%s' % (
                    hc_file)
            elif os.path.isfile(
                    os.path.abspath(
                        os.path.join(__file__, '..', '..', '..', 'share',
                                     'templates',
                                     'header_checks.%s' % (hc_file)))):
                input_file = os.path.abspath(
                    os.path.join(__file__, '..', '..', '..', 'share',
                                 'templates', 'header_checks.%s' % (hc_file)))

            shutil.copy(input_file,
                        "/etc/postfix/header_checks.%s" % (hc_file))
            subprocess.call(
                ["postmap",
                 "/etc/postfix/header_checks.%s" % (hc_file)])

    myaugeas = Augeas()

    setting_base = '/files/etc/postfix/main.cf/'

    for setting_key in postfix_main_settings.keys():
        setting = os.path.join(setting_base, setting_key)
        current_value = myaugeas.get(setting)

        if current_value == None:
            try:
                myaugeas.set(setting, postfix_main_settings[setting_key])
            except:
                insert_paths = myaugeas.match('/files/etc/postfix/main.cf/*')
                insert_path = insert_paths[(len(insert_paths) - 1)]
                myaugeas.insert(insert_path, setting_key, False)

        log.debug(_("Setting key %r to %r") %
                  (setting_key, postfix_main_settings[setting_key]),
                  level=8)
        myaugeas.set(setting, postfix_main_settings[setting_key])

    myaugeas.save()

    postfix_master_settings = {}

    if os.path.exists('/usr/lib/postfix/kolab_smtp_access_policy'):
        postfix_master_settings[
            'kolab_sap_executable_path'] = '/usr/lib/postfix/kolab_smtp_access_policy'
    else:
        postfix_master_settings[
            'kolab_sap_executable_path'] = '/usr/libexec/postfix/kolab_smtp_access_policy'

    template_file = None

    if os.path.isfile('/etc/kolab/templates/master.cf.tpl'):
        template_file = '/etc/kolab/templates/master.cf.tpl'
    elif os.path.isfile('/usr/share/kolab/templates/master.cf.tpl'):
        template_file = '/usr/share/kolab/templates/master.cf.tpl'
    elif os.path.isfile(
            os.path.abspath(
                os.path.join(__file__, '..', '..', '..', 'share', 'templates',
                             'master.cf.tpl'))):
        template_file = os.path.abspath(
            os.path.join(__file__, '..', '..', '..', 'share', 'templates',
                         'master.cf.tpl'))

    if not template_file == None:
        fp = open(template_file, 'r')
        template_definition = fp.read()
        fp.close()

        t = Template(template_definition, searchList=[postfix_master_settings])
        fp = open('/etc/postfix/master.cf', 'w')
        fp.write(t.__str__())
        fp.close()

    else:
        log.error(
            _("Could not write out Postfix configuration file /etc/postfix/master.cf"
              ))
        return

    if os.path.isdir('/etc/postfix/sasl/'):
        fp = open('/etc/postfix/sasl/smtpd.conf', 'w')
        fp.write("pwcheck_method: saslauthd\n")
        fp.write("mech_list: plain login\n")
        fp.close()

    amavisd_settings = {
        'ldap_server': '%(server_host)s',
        'ldap_bind_dn': conf.get('ldap', 'service_bind_dn'),
        'ldap_bind_pw': conf.get('ldap', 'service_bind_pw'),
        'primary_domain': conf.get('kolab', 'primary_domain'),
        'ldap_filter': "(|(mail=%m)(alias=%m))",
        'ldap_base_dn': conf.get('ldap', 'base_dn'),
        'clamdsock': '/var/spool/amavisd/clamd.sock',
    }

    template_file = None

    # On RPM installations, Amavis configuration is contained within a single file.
    amavisconf_paths = [
        "/etc/amavisd.conf", "/etc/amavis/amavisd.conf",
        "/etc/amavisd/amavisd.conf"
    ]

    amavis_conf = ''
    for amavisconf_path in amavisconf_paths:
        if os.path.isfile(amavisconf_path):
            amavis_conf = amavisconf_path
            break

    if os.path.isfile(amavis_conf):
        if os.path.isfile('/etc/kolab/templates/amavisd.conf.tpl'):
            template_file = '/etc/kolab/templates/amavisd.conf.tpl'
        elif os.path.isfile('/usr/share/kolab/templates/amavisd.conf.tpl'):
            template_file = '/usr/share/kolab/templates/amavisd.conf.tpl'
        elif os.path.isfile(
                os.path.abspath(
                    os.path.join(__file__, '..', '..', '..', 'share',
                                 'templates', 'amavisd.conf.tpl'))):
            template_file = os.path.abspath(
                os.path.join(__file__, '..', '..', '..', 'share', 'templates',
                             'amavisd.conf.tpl'))

        if not template_file == None:
            fp = open(template_file, 'r')
            template_definition = fp.read()
            fp.close()

            if os.path.isfile('/etc/clamd.d/amavisd.conf'):
                amavisdconf_content = file('/etc/clamd.d/amavisd.conf')
                for line in amavisdconf_content:
                    if line.startswith('LocalSocket'):
                        amavisd_settings['clamdsock'] = line[len('LocalSocket '
                                                                 ):].strip()

            t = Template(template_definition, searchList=[amavisd_settings])

        fp = None
        fp = open(amavis_conf, 'w')

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

        else:
            log.error(
                _("Could not write out Amavis configuration file amavisd.conf")
            )
            return

    # On APT installations, /etc/amavis/conf.d/ is a directory with many more files.
    #
    # Somebody could work on enhancement request #1080 to configure LDAP lookups,
    # while really it isn't required.
    else:
        log.info(_("Not writing out any configuration for Amavis."))

    # On debian wheezy amavisd-new expects '/etc/mailname' - possibly remediable through
    # the #1080 enhancement mentioned above, but here's a quick fix.
    f = open('/etc/mailname', 'w')
    f.writelines(conf.get('kolab', 'primary_domain'))
    f.close()

    if os.path.isfile('/etc/default/spamassassin'):
        myaugeas = Augeas()
        setting = os.path.join('/files/etc/default/spamassassin', 'ENABLED')
        if not myaugeas.get(setting) == '1':
            myaugeas.set(setting, '1')
            myaugeas.save()
        myaugeas.close()

    if os.path.isfile('/etc/default/wallace'):
        myaugeas = Augeas()
        setting = os.path.join('/files/etc/default/wallace', 'START')
        if not myaugeas.get(setting) == 'yes':
            myaugeas.set(setting, 'yes')
            myaugeas.save()
        myaugeas.close()

    if os.path.isfile('/usr/lib/systemd/system/[email protected]'):
        from ConfigParser import SafeConfigParser
        unitfile = SafeConfigParser()
        unitfile.optionxform = str
        unitfile.read('/usr/lib/systemd/system/[email protected]')
        if not unitfile.has_section('Install'):
            unitfile.add_section('Install')

        if not unitfile.has_option('Install', 'WantedBy'):
            unitfile.set('Install', 'WantedBy', 'multi-user.target')

        with open('/etc/systemd/system/[email protected]', 'wb') as f:
            unitfile.write(f)

    log.info(_("Configuring and refreshing Anti-Virus..."))

    if os.path.isfile('/etc/kolab/templates/freshclam.conf.tpl'):
        shutil.copy('/etc/kolab/templates/freshclam.conf.tpl',
                    '/etc/freshclam.conf')
    elif os.path.isfile('/usr/share/kolab/templates/freshclam.conf.tpl'):
        shutil.copy('/usr/share/kolab/templates/freshclam.conf.tpl',
                    '/etc/freshclam.conf')
    else:
        log.error(_("Could not find a ClamAV update configuration file"))

    if os.path.isfile('/etc/freshclam.conf'):
        subprocess.call(
            ['/usr/bin/freshclam', '--quiet', '--datadir="/var/lib/clamav"'])

    amavisservice = 'amavisd.service'
    clamavservice = '*****@*****.**'

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

    if os.path.isfile('/lib/systemd/system/amavis.service'):
        amavisservice = 'amavis.service'

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

    if os.path.isfile('/lib/systemd/system/clamd.service'):
        clamavservice = 'clamd.service'

    if os.path.isfile('/lib/systemd/system/clamav-daemon.service'):
        clamavservice = 'clamav-daemon.service'

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['systemctl', 'restart', 'postfix.service'])
        subprocess.call(['systemctl', 'restart', amavisservice])
        subprocess.call(['systemctl', 'restart', clamavservice])
        subprocess.call(['systemctl', 'restart', 'wallace.service'])
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['service', 'postfix', 'restart'])
        subprocess.call(['service', 'amavisd', 'restart'])
        subprocess.call(['service', 'clamd.amavisd', 'restart'])
        subprocess.call(['service', 'wallace', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service', 'postfix', 'restart'])
        subprocess.call(['/usr/sbin/service', 'amavis', 'restart'])
        subprocess.call(['/usr/sbin/service', 'clamav-daemon', 'restart'])
        subprocess.call(['/usr/sbin/service', 'wallace', 'restart'])
    else:
        log.error(
            _("Could not start the postfix, clamav and amavisd services services."
              ))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['systemctl', 'enable', 'postfix.service'])
        subprocess.call(['systemctl', 'enable', amavisservice])
        subprocess.call(['systemctl', 'enable', clamavservice])
        subprocess.call(['systemctl', 'enable', 'wallace.service'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['chkconfig', 'postfix', 'on'])
        subprocess.call(['chkconfig', 'amavisd', 'on'])
        subprocess.call(['chkconfig', 'clamd.amavisd', 'on'])
        subprocess.call(['chkconfig', 'wallace', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'postfix', 'defaults'])
        subprocess.call(['/usr/sbin/update-rc.d', 'amavis', 'defaults'])
        subprocess.call(['/usr/sbin/update-rc.d', 'clamav-daemon', 'defaults'])
        subprocess.call(['/usr/sbin/update-rc.d', 'wallace', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "postfix, clamav and amavisd services."))
Beispiel #4
0
def execute(*args, **kw):

    group_filter = conf.get('ldap','kolab_group_filter')
    if group_filter == None:
        group_filter = conf.get('ldap','group_filter')

    user_filter = conf.get('ldap','kolab_user_filter')
    if user_filter == None:
        user_filter = conf.get('ldap','user_filter')

    resource_filter = conf.get('ldap', 'resource_filter')

    sharedfolder_filter = conf.get('ldap', 'sharedfolder_filter')

    server_host = utils.parse_ldap_uri(conf.get('ldap', 'ldap_uri'))[1]

    files = {
            "/etc/postfix/ldap/local_recipient_maps.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mail=%%s)(alias=%%s))(|%(kolab_user_filter)s%(kolab_group_filter)s%(resource_filter)s%(sharedfolder_filter)s))
result_attribute = mail
""" % {
                        "base_dn": conf.get('ldap', 'base_dn'),
                        "server_host": server_host,
                        "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
                        "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
                        "kolab_user_filter": user_filter,
                        "kolab_group_filter": group_filter,
                        "resource_filter": resource_filter,
                        "sharedfolder_filter": sharedfolder_filter,
                    },
            "/etc/postfix/ldap/mydestination.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(domain_base_dn)s
scope = sub

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = %(domain_filter)s
result_attribute = %(domain_name_attribute)s
""" % {
                        "server_host": server_host,
                        "domain_base_dn": conf.get('ldap', 'domain_base_dn'),
                        "domain_filter": conf.get('ldap', 'domain_filter').replace('*', '%s'),
                        "domain_name_attribute": conf.get('ldap', 'domain_name_attribute'),
                        "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
                        "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
                    },
            "/etc/postfix/ldap/mailenabled_distgroups.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(group_base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

# This finds the mail enabled distribution group LDAP entry
query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectclass=groupofuniquenames)(!(objectclass=groupofurls)))
# From this type of group, get all uniqueMember DNs
special_result_attribute = uniqueMember
# Only from those DNs, get the mail
result_attribute =
leaf_result_attribute = mail
""" % {
                        "server_host": server_host,
                        "group_base_dn": conf.get('ldap', 'group_base_dn'),
                        "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
                        "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
                    },
            "/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(group_base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

# This finds the mail enabled dynamic distribution group LDAP entry
query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectClass=groupOfURLs))
# From this type of group, get all memberURL searches/references
special_result_attribute = memberURL
# Only from those DNs, get the mail
result_attribute =
leaf_result_attribute = mail
""" % {
                        "server_host": server_host,
                        "group_base_dn": conf.get('ldap', 'group_base_dn'),
                        "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
                        "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
                    },
            "/etc/postfix/ldap/transport_maps.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mailAlternateAddress=%%s)(alias=%%s)(mail=%%s))(objectclass=kolabinetorgperson))
result_attribute = mail
result_format = lmtp:unix:/var/lib/imap/socket/lmtp
""" % {
                        "base_dn": conf.get('ldap', 'base_dn'),
                        "server_host": server_host,
                        "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
                        "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
                    },
            "/etc/postfix/ldap/virtual_alias_maps.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabinetorgperson))
result_attribute = mail
""" % {
                        "base_dn": conf.get('ldap', 'base_dn'),
                        "server_host": server_host,
                        "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
                        "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
                    },
            "/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=mailrecipient)(objectclass=inetorgperson)(mailforwardingaddress=*))
result_attribute = mailForwardingAddress
""" % {
                        "base_dn": conf.get('ldap', 'base_dn'),
                        "server_host": server_host,
                        "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
                        "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
                    },
            "/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf": """
server_host = %(server_host)s
server_port = 389
version = 3
search_base = %(base_dn)s
scope = sub

domain = ldap:/etc/postfix/ldap/mydestination.cf

bind_dn = %(service_bind_dn)s
bind_pw = %(service_bind_pw)s

query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabsharedfolder)(kolabFolderType=mail))
result_attribute = kolabtargetfolder
result_format = shared+%%s
""" % {
                        "base_dn": conf.get('ldap', 'base_dn'),
                        "server_host": server_host,
                        "service_bind_dn": conf.get('ldap', 'service_bind_dn'),
                        "service_bind_pw": conf.get('ldap', 'service_bind_pw'),
                    },
        }

    if not os.path.isdir('/etc/postfix/ldap'):
        os.mkdir('/etc/postfix/ldap/', 0770)

    for filename in files.keys():
        fp = open(filename, 'w')
        fp.write(files[filename])
        fp.close()

    fp = open('/etc/postfix/transport', 'a')
    fp.write("\n# Shared Folder Delivery for %(domain)s:\nshared@%(domain)s\t\tlmtp:unix:/var/lib/imap/socket/lmtp\n" % {'domain': conf.get('kolab', 'primary_domain')})
    fp.close()

    subprocess.call(["postmap", "/etc/postfix/transport"])

    postfix_main_settings = {
            "inet_interfaces": "all",
            "recipient_delimiter": "+",
            "local_recipient_maps": "ldap:/etc/postfix/ldap/local_recipient_maps.cf",
            "mydestination": "ldap:/etc/postfix/ldap/mydestination.cf",
            "transport_maps": "ldap:/etc/postfix/ldap/transport_maps.cf, hash:/etc/postfix/transport",
            "virtual_alias_maps": "$alias_maps, ldap:/etc/postfix/ldap/virtual_alias_maps.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf, ldap:/etc/postfix/ldap/mailenabled_distgroups.cf, ldap:/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf",
            "smtpd_tls_auth_only": "yes",
            "smtpd_tls_security_level": "may",
            "smtp_tls_security_level": "may",
            "smtpd_sasl_auth_enable": "yes",
            "smtpd_sender_login_maps": "$local_recipient_maps",
            "smtpd_sender_restrictions": "permit_mynetworks, reject_sender_login_mismatch",
            "smtpd_recipient_restrictions": "permit_mynetworks, reject_unauth_pipelining, reject_rbl_client zen.spamhaus.org, reject_non_fqdn_recipient, reject_invalid_helo_hostname, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service unix:private/recipient_policy_incoming, permit",
            "smtpd_sender_restrictions": "permit_mynetworks, check_policy_service unix:private/sender_policy_incoming",
            "submission_recipient_restrictions": "check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject",
            "submission_sender_restrictions": "reject_non_fqdn_sender, check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject",
            "submission_data_restrictions": "check_policy_service unix:private/submission_policy",
            "content_filter": "smtp-amavis:[127.0.0.1]:10024"

        }

    if os.path.isfile('/etc/pki/tls/certs/make-dummy-cert') and not os.path.isfile('/etc/pki/tls/private/localhost.pem'):
        subprocess.call(['/etc/pki/tls/certs/make-dummy-cert', '/etc/pki/tls/private/localhost.pem'])

    if os.path.isfile('/etc/pki/tls/private/localhost.pem'):
        postfix_main_settings['smtpd_tls_cert_file'] = "/etc/pki/tls/private/localhost.pem"
        postfix_main_settings['smtpd_tls_key_file'] = "/etc/pki/tls/private/localhost.pem"

    if not os.path.isfile('/etc/postfix/main.cf'):
        if os.path.isfile('/usr/share/postfix/main.cf.debian'):
            shutil.copy(
                    '/usr/share/postfix/main.cf.debian',
                    '/etc/postfix/main.cf'
                )

    # Copy header checks files
    for hc_file in [ 'inbound', 'internal', 'submission' ]:
        if not os.path.isfile("/etc/postfix/header_checks.%s" % (hc_file)):
            if os.path.isfile('/etc/kolab/templates/header_checks.%s' % (hc_file)):
                input_file = '/etc/kolab/templates/header_checks.%s' % (hc_file)
            elif os.path.isfile('/usr/share/kolab/templates/header_checks.%s' % (hc_file)):
                input_file = '/usr/share/kolab/templates/header_checks.%s' % (hc_file)
            elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'header_checks.%s' % (hc_file)))):
                input_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'header_checks.%s' % (hc_file)))

            shutil.copy(input_file, "/etc/postfix/header_checks.%s" % (hc_file))
            subprocess.call(["postmap", "/etc/postfix/header_checks.%s" % (hc_file)])

    myaugeas = Augeas()

    setting_base = '/files/etc/postfix/main.cf/'

    for setting_key in postfix_main_settings.keys():
        setting = os.path.join(setting_base,setting_key)
        current_value = myaugeas.get(setting)

        if current_value == None:
            try:
                myaugeas.set(setting, postfix_main_settings[setting_key])
            except:
                insert_paths = myaugeas.match('/files/etc/postfix/main.cf/*')
                insert_path = insert_paths[(len(insert_paths)-1)]
                myaugeas.insert(insert_path, setting_key, False)

        log.debug(_("Setting key %r to %r") % (setting_key, postfix_main_settings[setting_key]), level=8)
        myaugeas.set(setting, postfix_main_settings[setting_key])

    myaugeas.save()

    postfix_master_settings = {
        }

    if os.path.exists('/usr/lib/postfix/kolab_smtp_access_policy'):
        postfix_master_settings['kolab_sap_executable_path'] = '/usr/lib/postfix/kolab_smtp_access_policy'
    else:
        postfix_master_settings['kolab_sap_executable_path'] = '/usr/libexec/postfix/kolab_smtp_access_policy'

    template_file = None

    if os.path.isfile('/etc/kolab/templates/master.cf.tpl'):
        template_file = '/etc/kolab/templates/master.cf.tpl'
    elif os.path.isfile('/usr/share/kolab/templates/master.cf.tpl'):
        template_file = '/usr/share/kolab/templates/master.cf.tpl'
    elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'master.cf.tpl'))):
        template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'master.cf.tpl'))

    if not template_file == None:
        fp = open(template_file, 'r')
        template_definition = fp.read()
        fp.close()

        t = Template(template_definition, searchList=[postfix_master_settings])
        fp = open('/etc/postfix/master.cf', 'w')
        fp.write(t.__str__())
        fp.close()

    else:
        log.error(_("Could not write out Postfix configuration file /etc/postfix/master.cf"))
        return

    if os.path.isdir('/etc/postfix/sasl/'):
        fp = open('/etc/postfix/sasl/smtpd.conf', 'w')
        fp.write("pwcheck_method: saslauthd\n")
        fp.write("mech_list: plain login\n")
        fp.close()

    amavisd_settings = {
            'ldap_server': '%(server_host)s',
            'ldap_bind_dn': conf.get('ldap', 'service_bind_dn'),
            'ldap_bind_pw': conf.get('ldap', 'service_bind_pw'),
            'primary_domain': conf.get('kolab', 'primary_domain'),
            'ldap_filter': "(|(mail=%m)(alias=%m))",
            'ldap_base_dn': conf.get('ldap', 'base_dn'),
        }

    template_file = None

    # On RPM installations, Amavis configuration is contained within a single file.
    if os.path.isfile("/etc/amavisd/amavisd.conf"):
        if os.path.isfile('/etc/kolab/templates/amavisd.conf.tpl'):
            template_file = '/etc/kolab/templates/amavisd.conf.tpl'
        elif os.path.isfile('/usr/share/kolab/templates/amavisd.conf.tpl'):
            template_file = '/usr/share/kolab/templates/amavisd.conf.tpl'
        elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'amavisd.conf.tpl'))):
            template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'amavisd.conf.tpl'))

        if not template_file == None:
            fp = open(template_file, 'r')
            template_definition = fp.read()
            fp.close()

            t = Template(template_definition, searchList=[amavisd_settings])

        fp = None
        if os.path.isdir('/etc/amavisd'):
            fp = open('/etc/amavisd/amavisd.conf', 'w')
        elif os.path.isdir('/etc/amavis'):
            fp = open('/etc/amavis/amavisd.conf', 'w')
        elif os.path.isfile('/etc/amavisd.conf'):
            fp = open('/etc/amavisd.conf', 'w')

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

        else:
            log.error(_("Could not write out Amavis configuration file amavisd.conf"))
            return

    # On APT installations, /etc/amavis/conf.d/ is a directory with many more files.
    #
    # Somebody could work on enhancement request #1080 to configure LDAP lookups,
    # while really it isn't required.
    else:
        log.info(_("Not writing out any configuration for Amavis."))

    # On debian wheezy amavisd-new expects '/etc/mailname' - possibly remediable through
    # the #1080 enhancement mentioned above, but here's a quick fix.
    f = open('/etc/mailname','w')
    f.writelines(conf.get('kolab', 'primary_domain'))
    f.close()

    if os.path.isfile('/etc/default/spamassassin'):
        myaugeas = Augeas()
        setting = os.path.join('/files/etc/default/spamassassin','ENABLED')
        if not myaugeas.get(setting) == '1':
            myaugeas.set(setting,'1')
            myaugeas.save()
        myaugeas.close()

    if os.path.isfile('/etc/default/wallace'):
        myaugeas = Augeas()
        setting = os.path.join('/files/etc/default/wallace','START')
        if not myaugeas.get(setting) == 'yes':
            myaugeas.set(setting,'yes')
            myaugeas.save()
        myaugeas.close()

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['systemctl', 'restart', 'postfix.service'])
        subprocess.call(['systemctl', 'restart', 'amavisd.service'])
        subprocess.call(['systemctl', 'restart', '*****@*****.**'])
        subprocess.call(['systemctl', 'restart', 'wallace.service'])
    elif os.path.isfile('/sbin/service'):
        subprocess.call(['service', 'postfix', 'restart'])
        subprocess.call(['service', 'amavisd', 'restart'])
        subprocess.call(['service', 'clamd.amavisd', 'restart'])
        subprocess.call(['service', 'wallace', 'restart'])
    elif os.path.isfile('/usr/sbin/service'):
        subprocess.call(['/usr/sbin/service','postfix','restart'])
        subprocess.call(['/usr/sbin/service','amavis','restart'])
        subprocess.call(['/usr/sbin/service','clamav-daemon','restart'])
        subprocess.call(['/usr/sbin/service','wallace','restart'])
    else:
        log.error(_("Could not start the postfix, clamav and amavisd services services."))

    if os.path.isfile('/bin/systemctl'):
        subprocess.call(['systemctl', 'enable', 'postfix.service'])
        subprocess.call(['systemctl', 'enable', 'amavisd.service'])
        subprocess.call(['systemctl', 'enable', '*****@*****.**'])
        subprocess.call(['systemctl', 'enable', 'wallace.service'])
    elif os.path.isfile('/sbin/chkconfig'):
        subprocess.call(['chkconfig', 'postfix', 'on'])
        subprocess.call(['chkconfig', 'amavisd', 'on'])
        subprocess.call(['chkconfig', 'clamd.amavisd', 'on'])
        subprocess.call(['chkconfig', 'wallace', 'on'])
    elif os.path.isfile('/usr/sbin/update-rc.d'):
        subprocess.call(['/usr/sbin/update-rc.d', 'postfix', 'defaults'])
        subprocess.call(['/usr/sbin/update-rc.d', 'amavis', 'defaults'])
        subprocess.call(['/usr/sbin/update-rc.d', 'clamav-daemon', 'defaults'])
        subprocess.call(['/usr/sbin/update-rc.d', 'wallace', 'defaults'])
    else:
        log.error(_("Could not configure to start on boot, the " + \
                "postfix, clamav and amavisd services."))
Beispiel #5
0
class HAProxyConfManager(object):
    conf_path = 'etc/haproxy/haproxy.cfg'

    def __init__(self, root_path=None):
        if root_path is None:
            root_path = '/'
        self.conf_path = root_path + self.conf_path
        self._conf_xpath = '/files' + self.conf_path + '/'
        self._augeas = Augeas(root=root_path, loadpath=HAPROXY_LENS_DIR)

    def load(self):
        LOG.debug('Loading haproxy.conf')
        self._augeas.load()

    def save(self):
        LOG.debug('Saving haproxy.conf')
        self._augeas.save()

    def get(self, xpath):
        """
        Returns values of label at given xpath. If label is presented but has no value,
        returns True
        xpath is relative to haproxy.cfg file
        """
        if self._augeas.match(self._conf_xpath + xpath) == []:
            return None
        value = self._augeas.get(self._conf_xpath + xpath)
        return value if value is not None else True

    def _find_xpath_gen(self, base_xpath, sublabel, value_pattern):
        section_xpaths = self._augeas.match(self._conf_xpath + base_xpath)
        for xpath in section_xpaths:
            match = re.search(value_pattern,
                              self._augeas.get(xpath + '/' + sublabel))
            if match != None:
                yield xpath.replace(self._conf_xpath, '')

    def find_all_xpaths(self, base_xpath, sublabel, value_pattern):
        """
        Returns list of all labels from given base_xpath which sublabel
        matches `value_pattern`

        `value_pattern` is regexp

        This metod is useful when you need to find certain section from config
        that contains number of such sections (listen[1], listen[2]...)

        ..Example:
            cnf.get_matched_xpaths('listen', 'name', 'test*')
            this will find every listen whose name begins with 'test'
        """
        return list(self._find_xpath_gen(base_xpath, sublabel, value_pattern))

    def find_one_xpath(self, base_xpath, sublabel, value_pattern):
        """
        Returns label xpath by given value_pattern of sublabel. Returns None if no label is found.

        This metod is useful when you need to find certain section from config
        that contains number of such sections (listen[1], listen[2]...)
        """
        try:
            return self._find_xpath_gen(base_xpath, sublabel,
                                        value_pattern).next()
        except StopIteration:
            return None

    def get_all_xpaths(self, base_xpath):
        return [
            x.replace(self._conf_xpath, '')
            for x in self._augeas.match(self._conf_xpath + base_xpath)
        ]

    def set(self, xpath, value=None, save_conf=True):
        """
        Sets label at given xpath with given value. If there is no label - creates one.
        If there is - updates its value.

        `value` can be None/True to set label without actual value
        or string
        or iterable
        or dict to set number of sublabels at once.

        `xpath` is relative to haproxy.cfg file.
        """
        LOG.debug('Setting %s with value: %s' % (xpath, value))
        if isinstance(value, dict):
            self._augeas.set(self._conf_xpath + xpath, None)
            for k, v in value.items():
                self.set(xpath + '/' + k, v, save_conf=False)
        elif hasattr(value, '__iter__'):
            for v in value:
                self.add(xpath, v, save_conf=False)
        else:
            if value == True:
                value = None
            elif value == False:
                return self.remove(xpath)
            elif value is not None:
                value = str(value)
            self._augeas.set(self._conf_xpath + xpath, value)
        if save_conf:
            self.save()

    def add(self, xpath, value=None, save_conf=True):
        """
        Adds node at given xpath. New nodes are appended
        xpath is relative to haproxy.cfg file
        Returns xpath of created node
        """
        nodes_qty = len(self._augeas.match(self._conf_xpath + xpath))

        if nodes_qty != 0:
            xpath += '[%s]' % (nodes_qty + 1)
        self.set(xpath, value, save_conf)
        return xpath

    def insert(self, xpath, label, value=None, before=True):
        """
        Inserts label before or after given in xpath
        xpath is relative to haproxy.cfg file
        """
        xpath = self._conf_xpath + xpath
        self._augeas.insert(xpath, label, before)
        if value is not None:
            labels = self._augeas.match(os.path.dirname(xpath))
            base_label = os.path.basename(xpath)
            inserted_xpath = None
            if label == base_label:
                if xpath.endswith(']'):
                    inserted_xpath = xpath if before else labels[
                        labels.index(xpath) + 1]
                else:
                    inserted_xpath += '[1]' if before else '[2]'
            else:
                index = labels.index(xpath) + (-1 if before else 1)
                inserted_xpath = labels[index]

            self.set(inserted_xpath.replace(self._conf_xpath, ''), value)

    def add_conf(self, conf, append=False):
        """
        Append raw conf to the end of haproxy.conf file
        or insert at the beginning before everything
        """
        LOG.debug('Adding raw conf part to haproxy.conf:\n%s' % conf)
        raw = None
        with open(self.conf_path, 'r') as conf_file:
            raw = conf_file.read()
        if not conf.endswith('\n'):
            conf += '\n'
        raw = '\n'.join((raw, conf) if append else (conf, raw))
        with open(self.conf_path, 'w') as conf_file:
            conf_file.write(raw)
        self.load()

    def extend_section(self, conf, section_name):
        """
        Appends raw conf to the section with given name
        """
        LOG.debug(
            'Adding raw conf part to section of haproxy.conf with name %s :\n%s'
            % (section_name, conf))
        raw = None
        with open(self.conf_path, 'r') as conf_file:
            raw = conf_file.read()
        if conf.endswith('\n'):
            conf = conf[:-1]
        # reindenting conf
        conf = dedent(conf)
        conf = '    ' + conf.replace('\n', '\n    ')
        raw = re.sub(section_name + r'\s*\n',
                     '%s\n%s\n' % (section_name, conf), raw)
        with open(self.conf_path, 'w') as conf_file:
            conf_file.write(raw)
        self.load()

    def remove(self, xpath):
        LOG.debug('Removing %s' % xpath)
        return self._augeas.remove(self._conf_xpath + xpath)