ac7d03
From e5491b62d3ec21feb7809f7f65797151d256c580 Mon Sep 17 00:00:00 2001
ac7d03
From: Jan Cholasta <jcholast@redhat.com>
ac7d03
Date: Wed, 3 May 2017 06:48:57 +0000
ac7d03
Subject: [PATCH] client install: fix client PKINIT configuration
ac7d03
ac7d03
Set `pkinit_anchors` in `krb5.conf` to a CA certificate bundle of CAs
ac7d03
trusted to issue KDC certificates rather than `/etc/ipa/ca.crt`.
ac7d03
ac7d03
Set `pkinit_pool` in `krb5.conf` to a CA certificate bundle of all CAs
ac7d03
known to IPA.
ac7d03
ac7d03
Make sure both bundles are exported in all installation code paths.
ac7d03
ac7d03
https://pagure.io/freeipa/issue/6831
ac7d03
ac7d03
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
ac7d03
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
ac7d03
---
ac7d03
 client/Makefile.am                         |  1 +
ac7d03
 freeipa.spec.in                            | 10 ++++++++++
ac7d03
 install/share/krb5.conf.template           |  3 ++-
ac7d03
 ipaclient/install/client.py                | 15 ++++++++++++++-
ac7d03
 ipaclient/install/ipa_certupdate.py        |  2 ++
ac7d03
 ipaplatform/base/paths.py                  |  2 ++
ac7d03
 ipaserver/install/cainstance.py            | 11 +++++++----
ac7d03
 ipaserver/install/ipa_backup.py            |  2 ++
ac7d03
 ipaserver/install/krbinstance.py           |  4 +++-
ac7d03
 ipaserver/install/server/install.py        | 10 ++++++++++
ac7d03
 ipaserver/install/server/replicainstall.py |  4 ++++
ac7d03
 ipaserver/install/server/upgrade.py        |  4 +++-
ac7d03
 12 files changed, 60 insertions(+), 8 deletions(-)
ac7d03
ac7d03
diff --git a/client/Makefile.am b/client/Makefile.am
ac7d03
index b6c9dea437460b0f912854a6a2fb9d1f30f3b1e7..e354cb41a4ee0d7da04197abe0e750c5d727bb4d 100644
ac7d03
--- a/client/Makefile.am
ac7d03
+++ b/client/Makefile.am
ac7d03
@@ -101,4 +101,5 @@ EXTRA_DIST =			\
ac7d03
 
ac7d03
 install-data-hook:
ac7d03
 	$(INSTALL) -d -m 755 $(DESTDIR)$(IPA_SYSCONF_DIR)/nssdb
ac7d03
+	$(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/lib/ipa-client/pki
ac7d03
 	$(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/lib/ipa-client/sysrestore
ac7d03
diff --git a/freeipa.spec.in b/freeipa.spec.in
ac7d03
index 0335a9970be82e80e98696f3d7fd4ec64894ef5f..6cb37ae53b039aa1d0e0509f62a3237504be6555 100644
ac7d03
--- a/freeipa.spec.in
ac7d03
+++ b/freeipa.spec.in
ac7d03
@@ -1097,6 +1097,15 @@ if [ $1 -gt 1 ] ; then
ac7d03
         fi
ac7d03
     fi
ac7d03
 
ac7d03
+    if [ $restore -ge 2 ]; then
ac7d03
+        if grep -E -q '\s*pkinit_anchors = FILE:/etc/ipa/ca.crt$' /etc/krb5.conf 2>/dev/null; then
ac7d03
+            sed -E 's|(\s*)pkinit_anchors = FILE:/etc/ipa/ca.crt$|\1pkinit_anchors = FILE:/var/lib/ipa-client/pki/kdc-ca-bundle.pem\n\1pkinit_pool = FILE:/var/lib/ipa-client/pki/ca-bundle.pem|' /etc/krb5.conf >/etc/krb5.conf.ipanew
ac7d03
+            mv -Z /etc/krb5.conf.ipanew /etc/krb5.conf
ac7d03
+            cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/kdc-ca-bundle.pem
ac7d03
+            cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/ca-bundle.pem
ac7d03
+        fi
ac7d03
+    fi
ac7d03
+
ac7d03
     if [ -f '/etc/sysconfig/ntpd' -a $restore -ge 2 ]; then
ac7d03
         if grep -E -q 'OPTIONS=.*-u ntp:ntp' /etc/sysconfig/ntpd 2>/dev/null; then
ac7d03
             sed -r '/OPTIONS=/ { s/\s+-u ntp:ntp\s+/ /; s/\s*-u ntp:ntp\s*// }' /etc/sysconfig/ntpd >/etc/sysconfig/ntpd.ipanew
ac7d03
@@ -1468,6 +1477,7 @@ fi
ac7d03
 %ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/pwdfile.txt
ac7d03
 %ghost %config(noreplace) %{_sysconfdir}/pki/ca-trust/source/ipa.p11-kit
ac7d03
 %dir %{_localstatedir}/lib/ipa-client
ac7d03
+%dir %{_localstatedir}/lib/ipa-client/pki
ac7d03
 %dir %{_localstatedir}/lib/ipa-client/sysrestore
ac7d03
 %{_mandir}/man5/default.conf.5*
ac7d03
 
ac7d03
diff --git a/install/share/krb5.conf.template b/install/share/krb5.conf.template
ac7d03
index e8b2ad8dace8264cd9345285f55c42422bf81ca3..1f18ff90d34ccccb42c4b64d188e7d70e9892b71 100644
ac7d03
--- a/install/share/krb5.conf.template
ac7d03
+++ b/install/share/krb5.conf.template
ac7d03
@@ -21,7 +21,8 @@ $OTHER_LIBDEFAULTS
ac7d03
   master_kdc = $FQDN:88
ac7d03
   admin_server = $FQDN:749
ac7d03
   default_domain = $DOMAIN
ac7d03
-  pkinit_anchors = FILE:/etc/ipa/ca.crt
ac7d03
+  pkinit_anchors = FILE:$KDC_CA_BUNDLE_PEM
ac7d03
+  pkinit_pool = FILE:$CA_BUNDLE_PEM
ac7d03
 }
ac7d03
 
ac7d03
 [domain_realm]
ac7d03
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
ac7d03
index e78be904dd6bad491d9f3c1bb1e1410bc1779d45..6f10f5258747881b9af8c6b70b499f9ff7d577ff 100644
ac7d03
--- a/ipaclient/install/client.py
ac7d03
+++ b/ipaclient/install/client.py
ac7d03
@@ -710,7 +710,11 @@ def configure_krb5_conf(
ac7d03
         kropts.append(krbconf.setOption('default_domain', cli_domain))
ac7d03
 
ac7d03
     kropts.append(
ac7d03
-        krbconf.setOption('pkinit_anchors', 'FILE:%s' % paths.IPA_CA_CRT))
ac7d03
+        krbconf.setOption('pkinit_anchors',
ac7d03
+                          'FILE:%s' % paths.KDC_CA_BUNDLE_PEM))
ac7d03
+    kropts.append(
ac7d03
+        krbconf.setOption('pkinit_pool',
ac7d03
+                          'FILE:%s' % paths.CA_BUNDLE_PEM))
ac7d03
     ropts = [{
ac7d03
         'name': cli_realm,
ac7d03
         'type': 'subsection',
ac7d03
@@ -2770,6 +2774,13 @@ def _install(options):
ac7d03
     ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u))
ac7d03
                       for (c, n, t, u) in ca_certs]
ac7d03
 
ac7d03
+    x509.write_certificate_list(
ac7d03
+        [c for c, n, t, u in ca_certs if t is not False],
ac7d03
+        paths.KDC_CA_BUNDLE_PEM)
ac7d03
+    x509.write_certificate_list(
ac7d03
+        [c for c, n, t, u in ca_certs if t is not False],
ac7d03
+        paths.CA_BUNDLE_PEM)
ac7d03
+
ac7d03
     # Add the CA certificates to the IPA NSS database
ac7d03
     root_logger.debug("Adding CA certificates to the IPA NSS database.")
ac7d03
     ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
ac7d03
@@ -3317,6 +3328,8 @@ def uninstall(options):
ac7d03
 
ac7d03
     # Remove the CA cert
ac7d03
     remove_file(paths.IPA_CA_CRT)
ac7d03
+    remove_file(paths.KDC_CA_BUNDLE_PEM)
ac7d03
+    remove_file(paths.CA_BUNDLE_PEM)
ac7d03
 
ac7d03
     root_logger.info("Client uninstall complete.")
ac7d03
 
ac7d03
diff --git a/ipaclient/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py
ac7d03
index 7dc88f07ae14e5416f6fe3dc8400b7d4bcabef72..7e8527e1fcb575844e8f4c90016435124b70e381 100644
ac7d03
--- a/ipaclient/install/ipa_certupdate.py
ac7d03
+++ b/ipaclient/install/ipa_certupdate.py
ac7d03
@@ -113,6 +113,8 @@ class CertUpdate(admintool.AdminTool):
ac7d03
 
ac7d03
     def update_client(self, certs):
ac7d03
         self.update_file(paths.IPA_CA_CRT, certs)
ac7d03
+        self.update_file(paths.KDC_CA_BUNDLE_PEM, certs)
ac7d03
+        self.update_file(paths.CA_BUNDLE_PEM, certs)
ac7d03
 
ac7d03
         ipa_db = certdb.NSSDatabase(api.env.nss_dir)
ac7d03
 
ac7d03
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
ac7d03
index f80c9e95ab875222887e3692ab80151f84345469..804fddee60f787e161947bbe4b1914995257ceb4 100644
ac7d03
--- a/ipaplatform/base/paths.py
ac7d03
+++ b/ipaplatform/base/paths.py
ac7d03
@@ -331,6 +331,8 @@ class BasePathNamespace(object):
ac7d03
     VAR_RUN_DIRSRV_DIR = "/var/run/dirsrv"
ac7d03
     IPA_CCACHES = "/var/run/ipa/ccaches"
ac7d03
     HTTP_CCACHE = "/var/lib/ipa/gssproxy/http.ccache"
ac7d03
+    CA_BUNDLE_PEM = "/var/lib/ipa-client/pki/ca-bundle.pem"
ac7d03
+    KDC_CA_BUNDLE_PEM = "/var/lib/ipa-client/pki/kdc-ca-bundle.pem"
ac7d03
     IPA_RENEWAL_LOCK = "/var/run/ipa/renewal.lock"
ac7d03
     SVC_LIST_FILE = "/var/run/ipa/services.list"
ac7d03
     KRB5CC_SAMBA = "/var/run/samba/krb5cc_samba"
ac7d03
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
ac7d03
index a4aa4f2069277181501ebd92f3795c452b10acd0..b8c8cc4fc4532fc2c911ec174d363f8280ce863b 100644
ac7d03
--- a/ipaserver/install/cainstance.py
ac7d03
+++ b/ipaserver/install/cainstance.py
ac7d03
@@ -794,10 +794,13 @@ class CAInstance(DogtagInstance):
ac7d03
         certlist = x509.pkcs7_to_pems(data, x509.DER)
ac7d03
 
ac7d03
         # We have all the certificates in certlist, write them to a PEM file
ac7d03
-        with open(paths.IPA_CA_CRT, 'w') as ipaca_pem:
ac7d03
-            for cert in certlist:
ac7d03
-                ipaca_pem.write(cert)
ac7d03
-                ipaca_pem.write('\n')
ac7d03
+        for path in [paths.IPA_CA_CRT,
ac7d03
+                     paths.KDC_CA_BUNDLE_PEM,
ac7d03
+                     paths.CA_BUNDLE_PEM]:
ac7d03
+            with open(path, 'w') as ipaca_pem:
ac7d03
+                for cert in certlist:
ac7d03
+                    ipaca_pem.write(cert)
ac7d03
+                    ipaca_pem.write('\n')
ac7d03
 
ac7d03
     def __request_ra_certificate(self):
ac7d03
         # create a temp file storing the pwd
ac7d03
diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
ac7d03
index 40f08d7d727a8b97b5996f15d27c1e20788e1473..f8cdd56d26636678279ba5afb423c5eef10c33d0 100644
ac7d03
--- a/ipaserver/install/ipa_backup.py
ac7d03
+++ b/ipaserver/install/ipa_backup.py
ac7d03
@@ -150,6 +150,8 @@ class Backup(admintool.AdminTool):
ac7d03
         paths.SSHD_CONFIG,
ac7d03
         paths.SSH_CONFIG,
ac7d03
         paths.KRB5_CONF,
ac7d03
+        paths.KDC_CA_BUNDLE_PEM,
ac7d03
+        paths.CA_BUNDLE_PEM,
ac7d03
         paths.IPA_CA_CRT,
ac7d03
         paths.IPA_DEFAULT_CONF,
ac7d03
         paths.DS_KEYTAB,
ac7d03
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
ac7d03
index 2f14ff592064d3446f73b31e615b2de88d6d786c..e52577bbaa15064946f9a3c9720aa40ffc3251aa 100644
ac7d03
--- a/ipaserver/install/krbinstance.py
ac7d03
+++ b/ipaserver/install/krbinstance.py
ac7d03
@@ -261,7 +261,9 @@ class KrbInstance(service.Service):
ac7d03
                              KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB,
ac7d03
                              KDC_CERT=paths.KDC_CERT,
ac7d03
                              KDC_KEY=paths.KDC_KEY,
ac7d03
-                             CACERT_PEM=paths.CACERT_PEM)
ac7d03
+                             CACERT_PEM=paths.CACERT_PEM,
ac7d03
+                             KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
ac7d03
+                             CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM)
ac7d03
 
ac7d03
         # IPA server/KDC is not a subdomain of default domain
ac7d03
         # Proper domain-realm mapping needs to be specified
ac7d03
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
ac7d03
index 25c21db721c58388ae8fd6ab1fbc443d513a4324..c1bdce6c8459dfeabd0096d105e535ec4ee56a2a 100644
ac7d03
--- a/ipaserver/install/server/install.py
ac7d03
+++ b/ipaserver/install/server/install.py
ac7d03
@@ -796,6 +796,16 @@ def install(installer):
ac7d03
         x509.write_certificate(http_ca_cert, paths.IPA_CA_CRT)
ac7d03
         os.chmod(paths.IPA_CA_CRT, 0o444)
ac7d03
 
ac7d03
+        if not options.no_pkinit:
ac7d03
+            x509.write_certificate(http_ca_cert, paths.KDC_CA_BUNDLE_PEM)
ac7d03
+        else:
ac7d03
+            with open(paths.KDC_CA_BUNDLE_PEM, 'w'):
ac7d03
+                pass
ac7d03
+        os.chmod(paths.KDC_CA_BUNDLE_PEM, 0o444)
ac7d03
+
ac7d03
+        x509.write_certificate(http_ca_cert, paths.CA_BUNDLE_PEM)
ac7d03
+        os.chmod(paths.CA_BUNDLE_PEM, 0o444)
ac7d03
+
ac7d03
     # we now need to enable ssl on the ds
ac7d03
     ds.enable_ssl()
ac7d03
 
ac7d03
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
ac7d03
index c19edceec42845f3169adc923762f700739232f2..66d7ba44645aed69b12f0e5ea14f5080492fe5ef 100644
ac7d03
--- a/ipaserver/install/server/replicainstall.py
ac7d03
+++ b/ipaserver/install/server/replicainstall.py
ac7d03
@@ -1390,6 +1390,10 @@ def install(installer):
ac7d03
 
ac7d03
         # Update and istall updated CA file
ac7d03
         cafile = install_ca_cert(conn, api.env.basedn, api.env.realm, cafile)
ac7d03
+        install_ca_cert(conn, api.env.basedn, api.env.realm, cafile,
ac7d03
+                        destfile=paths.KDC_CA_BUNDLE_PEM)
ac7d03
+        install_ca_cert(conn, api.env.basedn, api.env.realm, cafile,
ac7d03
+                        destfile=paths.CA_BUNDLE_PEM)
ac7d03
 
ac7d03
         # Configure dirsrv
ac7d03
         ds = install_replica_ds(config, options, ca_enabled,
ac7d03
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
ac7d03
index c244958f4cddba0d1edded5165a295b1e1ee2b8a..648dc1f29c44f89d9fbceb7b50373d93c88b5c1a 100644
ac7d03
--- a/ipaserver/install/server/upgrade.py
ac7d03
+++ b/ipaserver/install/server/upgrade.py
ac7d03
@@ -1831,7 +1831,9 @@ def upgrade_configuration():
ac7d03
                         KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB,
ac7d03
                         KDC_CERT=paths.KDC_CERT,
ac7d03
                         KDC_KEY=paths.KDC_KEY,
ac7d03
-                        CACERT_PEM=paths.CACERT_PEM)
ac7d03
+                        CACERT_PEM=paths.CACERT_PEM,
ac7d03
+                        KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
ac7d03
+                        CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM)
ac7d03
     krb.add_anonymous_principal()
ac7d03
     setup_pkinit(krb)
ac7d03
 
ac7d03
-- 
ac7d03
2.9.4
ac7d03