URL: https://github.com/freeipa/freeipa/pull/919
Author: Tiboris
 Title: #919: client.py: Using Augeas to configure krb5.conf
Action: opened

PR body:
"""
Using Augeas should avoid issues like https://pagure.io/freeipa/issue/5912.

Resolves: https://pagure.io/freeipa/issue/5913
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/919/head:pr919
git checkout pr919
From b4b5d45e41b94781dfef5fa85fa21cf2be90928c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tibor=20Dudl=C3=A1k?= <tdud...@redhat.com>
Date: Mon, 10 Jul 2017 15:21:08 +0200
Subject: [PATCH] client.py: Using Augeas to configure krb5.conf

Using Augeas should avoid issues like #5912.

Resolves: https://pagure.io/freeipa/issue/5913
---
 ipaclient/install/client.py | 210 ++++++++++++++++++++------------------------
 1 file changed, 95 insertions(+), 115 deletions(-)

diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
index 7a908f5409..f7e23e7c45 100644
--- a/ipaclient/install/client.py
+++ b/ipaclient/install/client.py
@@ -26,6 +26,9 @@
 import tempfile
 import time
 import traceback
+import shutil
+
+from augeas import Augeas
 
 from cryptography.hazmat.primitives import serialization
 # pylint: disable=import-error
@@ -630,131 +633,108 @@ def configure_krb5_conf(
         filename, client_domain, client_hostname, force=False,
         configure_sssd=True):
 
-    krbconf = IPAChangeConf("IPA Installer")
-    krbconf.setOptionAssignment((" = ", " "))
-    krbconf.setSectionNameDelimiters(("[", "]"))
-    krbconf.setSubSectionDelimiters(("{", "}"))
-    krbconf.setIndent(("", "  ", "    "))
+    aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD,
+                 loadpath=paths.USR_SHARE_IPA_DIR)
 
-    opts = [
-        {
-            'name': 'comment',
-            'type': 'comment',
-            'value': 'File modified by ipa-client-install'
-        },
-        krbconf.emptyLine(),
-    ]
+    try:
+        aug.transform('IPAKrb5', paths.KRB5_CONF)
+        path = '/files{path}'.format(path=paths.KRB5_CONF)
+        aug.load()
 
-    if os.path.exists(paths.COMMON_KRB5_CONF_DIR):
-        opts.extend([
-            {
-                'name': 'includedir',
-                'type': 'option',
-                'value': paths.COMMON_KRB5_CONF_DIR,
-                'delim': ' '
-            }
-        ])
+        value = 'File modified by ipa-client-install'
+        aug.set('{}/#comment[last()+1]'.format(path), value)
 
-    # SSSD include dir
-    if configure_sssd:
-        opts.extend([
-            {
-                'name': 'includedir',
-                'type': 'option',
-                'value': paths.SSSD_PUBCONF_KRB5_INCLUDE_D_DIR,
-                'delim': ' '
-            },
-            krbconf.emptyLine()])
-
-    # [libdefaults]
-    libopts = [
-        krbconf.setOption('default_realm', cli_realm)
-    ]
-    if not dnsok or not cli_kdc or force:
-        libopts.extend([
-            krbconf.setOption('dns_lookup_realm', 'false'),
-            krbconf.setOption('dns_lookup_kdc', 'false')
-        ])
-    else:
-        libopts.extend([
-            krbconf.setOption('dns_lookup_realm', 'true'),
-            krbconf.setOption('dns_lookup_kdc', 'true')
-        ])
-    libopts.extend([
-        krbconf.setOption('rdns', 'false'),
-        krbconf.setOption('dns_canonicalize_hostname', 'false'),
-        krbconf.setOption('ticket_lifetime', '24h'),
-        krbconf.setOption('forwardable', 'true'),
-        krbconf.setOption('udp_preference_limit', '0')
-    ])
+        common_exists = os.path.exists(paths.COMMON_KRB5_CONF_DIR)
 
-    # Configure KEYRING CCACHE if supported
-    if kernel_keyring.is_persistent_keyring_supported():
-        logger.debug("Enabling persistent keyring CCACHE")
-        libopts.append(krbconf.setOption('default_ccache_name',
-                                         'KEYRING:persistent:%{uid}'))
+        if common_exists:
+            include = '{}'.format(paths.COMMON_KRB5_CONF_DIR)
+            aug.set('{}/includedir[1]'.format(path), include)
 
-    opts.extend([
-        krbconf.setSection('libdefaults', libopts),
-        krbconf.emptyLine()
-    ])
+        if configure_sssd:
+            include = '{}'.format(paths.SSSD_PUBCONF_KRB5_INCLUDE_D_DIR)
+            aug.set('{}/includedir[2]'.format(path), include)
 
-    # the following are necessary only if DNS discovery does not work
-    kropts = []
-    if not dnsok or not cli_kdc or force:
-        # [realms]
-        for server in cli_server:
-            kropts.extend([
-                krbconf.setOption('kdc', ipautil.format_netloc(server, 88)),
-                krbconf.setOption('master_kdc',
-                                  ipautil.format_netloc(server, 88)),
-                krbconf.setOption('admin_server',
-                                  ipautil.format_netloc(server, 749)),
-                krbconf.setOption('kpasswd_server',
-                                  ipautil.format_netloc(server, 464))
-            ])
-        kropts.append(krbconf.setOption('default_domain', cli_domain))
-
-    kropts.append(
-        krbconf.setOption('pkinit_anchors',
-                          'FILE:%s' % paths.KDC_CA_BUNDLE_PEM))
-    kropts.append(
-        krbconf.setOption('pkinit_pool',
-                          'FILE:%s' % paths.CA_BUNDLE_PEM))
-    ropts = [{
-        'name': cli_realm,
-        'type': 'subsection',
-        'value': kropts
-    }]
-
-    opts.append(krbconf.setSection('realms', ropts))
-    opts.append(krbconf.emptyLine())
-
-    # [domain_realm]
-    dropts = [
-        krbconf.setOption('.{}'.format(cli_domain), cli_realm),
-        krbconf.setOption(cli_domain, cli_realm),
-        krbconf.setOption(client_hostname, cli_realm)
-    ]
+        libdef_path = '{}/libdefaults'.format(path)
 
-    # add client domain mapping if different from server domain
-    if cli_domain != client_domain:
-        dropts.extend([
-            krbconf.setOption('.{}'.format(client_domain), cli_realm),
-            krbconf.setOption(client_domain, cli_realm)
-        ])
+        aug.set('{}/default_realm'.format(libdef_path), cli_realm)
 
-    opts.extend([
-        krbconf.setSection('domain_realm', dropts),
-        krbconf.emptyLine()
-    ])
+        if not dnsok or not cli_kdc or force:
+            aug.set('{}/dns_lookup_realm'.format(libdef_path), 'false')
+            aug.set('{}/dns_lookup_kdc'.format(libdef_path), 'false')
+        else:
+            aug.set('{}/dns_lookup_realm'.format(libdef_path), 'true')
+            aug.set('{}/dns_lookup_kdc'.format(libdef_path), 'true')
+
+        aug.set('{}/rdns'.format(libdef_path), 'false')
+        aug.set('{}/dns_canonicalize_hostname'.format(libdef_path), 'false')
+        aug.set('{}/ticket_lifetime'.format(libdef_path), '24h')
+        aug.set('{}/forwardable'.format(libdef_path), 'true')
+        aug.set('{}/udp_preference_limit'.format(libdef_path), '0')
+
+        # Configure KEYRING CCACHE if supported
+        if kernel_keyring.is_persistent_keyring_supported():
+            logger.debug("Enabling persistent keyring CCACHE")
+            aug.set('{}/default_ccache_name'.format(path),
+                    'KEYRING:persistent:%{uid}')
+
+        realms_path = '{}/realms/{realm}'.format(path, realm=cli_realm)
+        # the following are necessary only if DNS discovery does not work
+        kropts = '{{\n\t'
+        if not dnsok or not cli_kdc or force:
+
+            for server in cli_server:
+                kropts = '{}kdc = {server}\n\t'.format(
+                    kropts, server=ipautil.format_netloc(server, 88))
+                kropts = '{}master_kdc = {server}\n\t'.format(
+                    kropts, server=ipautil.format_netloc(server, 88)),
+                kropts = '{}admin_server = {server}\n\t'.format(
+                    kropts, server=ipautil.format_netloc(server, 749)),
+                kropts = '{}kpasswd_server = {server}\n\t'.format(
+                    kropts, server=ipautil.format_netloc(server, 464))
+
+            kropts = '{}default_domain = {domain}\n\t'.format(
+                kropts, domain=cli_domain)
+
+        kropts = '{}pkinit_anchors = {value}\n\t'.format(
+            kropts, value='FILE:{}'.format(paths.KDC_CA_BUNDLE_PEM))
+
+        kropts = '{}pkinit_pool = {value}\n'.format(
+            kropts, value='FILE:{}'.format(paths.CA_BUNDLE_PEM))
+
+        kropts = '{opts}}}'.format(opts=kropts)
+        aug.set('{}'.format(realms_path), kropts)
+
+        # [domain_realm]
+        dom_realm_path = '{}/domain_realm/'.format(path)
+
+        aug.set('{path}/.{key}'.format(path=dom_realm_path,
+                key=cli_domain), cli_realm)
+        aug.set('{path}/{key}'.format(path=dom_realm_path,
+                key=cli_domain), cli_realm)
+        aug.set('{path}/{key}'.format(path=dom_realm_path,
+                key=client_hostname), cli_realm)
+
+        # add client domain mapping if different from server domain
+        if cli_domain != client_domain:
+            aug.set('.{path}/{key}'.format(path=dom_realm_path,
+                    key=client_domain), cli_realm)
+            aug.set('{path}/{key}'.format(path=dom_realm_path,
+                    key=client_domain), cli_realm)
+
+        logger.debug("Writing Kerberos configuration to %s:", filename)
+
+        # backup oginal file
+        try:
+            shutil.copy2(filename, (filename + ".ipabkp"))
+        except IOError as err:
+            if err.errno == 2:
+                # The original file did not exist
+                pass
 
-    logger.debug("Writing Kerberos configuration to %s:", filename)
-    logger.debug("%s", krbconf.dump(opts))
+        aug.save()
 
-    krbconf.newConf(filename, opts)
-    # umask applies when creating a new file but we want 0o644 here
-    os.chmod(filename, 0o644)
+    finally:
+        aug.close()
 
 
 def configure_certmonger(
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to