[Freeipa-devel] [PATCH] 0100 Track lightweight CAs on replica installation

Fraser Tweedale ftweedal at redhat.com
Tue Aug 23 06:40:43 UTC 2016


Hi folks,

Please review attached patch which fixes
https://fedorahosted.org/freeipa/ticket/6019.

Thanks,
Fraser
-------------- next part --------------
From 558ec02053154b472b0505e6c2279095f296cb9c Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Tue, 23 Aug 2016 16:14:30 +1000
Subject: [PATCH] Track lightweight CAs on replica installation

Add Certmonger tracking requests for lightweight CAs on replica
installation.  As part of this change, extract most of the
lightweight CA tracking code out of ipa-certupdate and into
cainstance.

Fixes: https://fedorahosted.org/freeipa/ticket/6019
---
 ipaclient/ipa_certupdate.py     | 53 +++++----------------------
 ipalib/constants.py             |  2 ++
 ipaserver/install/cainstance.py | 80 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 44 deletions(-)

diff --git a/ipaclient/ipa_certupdate.py b/ipaclient/ipa_certupdate.py
index e59047a2705eb8ccb98b5213c4c8771f55a29bc5..2b33934619aa69e941fb292660ede5f925799142 100644
--- a/ipaclient/ipa_certupdate.py
+++ b/ipaclient/ipa_certupdate.py
@@ -29,10 +29,7 @@ from ipaplatform import services
 from ipaplatform.paths import paths
 from ipaplatform.tasks import tasks
 from ipalib import api, errors, x509, certstore
-from ipalib.constants import IPA_CA_CN
-
-IPA_CA_NICKNAME = 'caSigningCert cert-pki-ca'
-RENEWAL_CA_NAME = 'dogtag-ipa-ca-renew-agent'
+from ipalib.constants import IPA_CA_NICKNAME, RENEWAL_CA_NAME
 
 class CertUpdate(admintool.AdminTool):
     command_name = 'ipa-certupdate'
@@ -85,11 +82,8 @@ class CertUpdate(admintool.AdminTool):
             certs = certstore.get_ca_certs(ldap, api.env.basedn,
                                            api.env.realm, ca_enabled)
 
-            # find lightweight CAs (on renewal master only)
-            lwcas = []
-            for ca_obj in api.Command.ca_find()['result']:
-                if IPA_CA_CN not in ca_obj['cn']:
-                    lwcas.append(ca_obj)
+            # find lightweight CAs
+            lwcas = api.Command.ca_find()['result']
 
             api.Backend.rpcclient.disconnect()
         finally:
@@ -98,8 +92,12 @@ class CertUpdate(admintool.AdminTool):
         server_fstore = sysrestore.FileStore(paths.SYSRESTORE)
         if server_fstore.has_files():
             self.update_server(certs)
-            for entry in lwcas:
-                self.server_track_lightweight_ca(entry)
+            try:
+                from ipaserver.install import cainstance
+                cainstance.add_lightweight_ca_tracking_requests(self.log, lwcas)
+            except Exception as e:
+                self.log.exception(
+                    "Failed to add lightweight CA tracking requests")
 
         self.update_client(certs)
 
@@ -163,39 +161,6 @@ class CertUpdate(admintool.AdminTool):
 
         self.update_file(paths.CA_CRT, certs)
 
-    def server_track_lightweight_ca(self, entry):
-        nickname = "{} {}".format(IPA_CA_NICKNAME, entry['ipacaid'][0])
-        criteria = {
-            'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
-            'cert-nickname': nickname,
-            'ca-name': RENEWAL_CA_NAME,
-        }
-        request_id = certmonger.get_request_id(criteria)
-        if request_id is None:
-            try:
-                certmonger.dogtag_start_tracking(
-                    secdir=paths.PKI_TOMCAT_ALIAS_DIR,
-                    pin=certmonger.get_pin('internal'),
-                    pinfile=None,
-                    nickname=nickname,
-                    ca=RENEWAL_CA_NAME,
-                    pre_command='stop_pkicad',
-                    post_command='renew_ca_cert "%s"' % nickname,
-                )
-                request_id = certmonger.get_request_id(criteria)
-                certmonger.modify(request_id, profile='ipaCACertRenewal')
-                self.log.debug(
-                    'Lightweight CA renewal: '
-                    'added tracking request for "%s"', nickname)
-            except RuntimeError as e:
-                self.log.error(
-                    'Lightweight CA renewal: Certmonger failed to '
-                    'start tracking certificate: %s', e)
-        else:
-            self.log.debug(
-                'Lightweight CA renewal: '
-                'already tracking certificate "%s"', nickname)
-
     def update_file(self, filename, certs, mode=0o444):
         certs = (c[0] for c in certs if c[2] is not False)
         try:
diff --git a/ipalib/constants.py b/ipalib/constants.py
index 0574bb3aa457dd79a6d64f6b8a6b57161d32da92..d5b918c49d695c5a15bee576d88902700743e263 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -273,3 +273,5 @@ CA_SUFFIX_NAME = 'ca'
 PKI_GSSAPI_SERVICE_NAME = 'dogtag'
 IPA_CA_CN = u'ipa'
 IPA_CA_RECORD = "ipa-ca"
+IPA_CA_NICKNAME = 'caSigningCert cert-pki-ca'
+RENEWAL_CA_NAME = 'dogtag-ipa-ca-renew-agent'
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 2ec02d6628ebc9e3a9bad141ec636c84eab14cef..7c2f1e1a29a201ff53555e76a2d5aa8408037eee 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1379,6 +1379,9 @@ class CAInstance(DogtagInstance):
 
         self.step("enabling CA instance", self.__enable_instance)
 
+        self.step("configuring certmonger renewal for lightweight CAs",
+                  self.__add_lightweight_ca_tracking_requests)
+
         self.start_creation(runtime=210)
 
     def setup_lightweight_ca_key_retrieval(self):
@@ -1444,6 +1447,36 @@ class CAInstance(DogtagInstance):
         os.chmod(keyfile, 0o600)
         os.chown(keyfile, pent.pw_uid, pent.pw_gid)
 
+    def __add_lightweight_ca_tracking_requests(self):
+        server_id = installutils.realm_to_serverid(api.env.realm)
+        dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
+        conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
+        is_already_connected = conn.isconnected()
+
+        if not is_already_connected:
+            try:
+                conn.connect(autobind=True)
+            except errors.PublicError as e:
+                self.log.error(
+                    "Cannot connect to LDAP to add "
+                        "lightweight CA tracking requests: %s",
+                    e
+                )
+                return
+
+        try:
+            lwcas = conn.get_entries(
+                base_dn=ipautil.realm_to_suffix(api.env.realm),
+                filter='(objectclass=ipaca)',
+                attrs_list=['cn', 'ipacaid'],
+            )
+            add_lightweight_ca_tracking_requests(self.log, lwcas)
+        except errors.NotFound:
+            pass  # shouldn't happen, but don't fail if it does
+        finally:
+            if not is_already_connected:
+                conn.disconnect()
+
 
 def replica_ca_install_check(config):
     if not config.setup_ca:
@@ -2066,6 +2099,53 @@ def ensure_default_caacl():
         api.Backend.ldap2.disconnect()
 
 
+def add_lightweight_ca_tracking_requests(logger, lwcas):
+    """Add tracking requests for the given lightweight CAs.
+
+    The entries must have the 'cn' and 'ipacaid' attributes.
+
+    The IPA CA, if present, is skipped.
+
+    """
+    for entry in lwcas:
+        if ipalib.constants.IPA_CA_CN in entry['cn']:
+            continue
+
+        nickname = "{} {}".format(
+                ipalib.constants.IPA_CA_NICKNAME,
+                entry['ipacaid'][0])
+        criteria = {
+            'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
+            'cert-nickname': nickname,
+            'ca-name': ipalib.constants.RENEWAL_CA_NAME,
+        }
+        request_id = certmonger.get_request_id(criteria)
+        if request_id is None:
+            try:
+                certmonger.dogtag_start_tracking(
+                    secdir=paths.PKI_TOMCAT_ALIAS_DIR,
+                    pin=certmonger.get_pin('internal'),
+                    pinfile=None,
+                    nickname=nickname,
+                    ca=ipalib.constants.RENEWAL_CA_NAME,
+                    pre_command='stop_pkicad',
+                    post_command='renew_ca_cert "%s"' % nickname,
+                )
+                request_id = certmonger.get_request_id(criteria)
+                certmonger.modify(request_id, profile='ipaCACertRenewal')
+                logger.debug(
+                    'Lightweight CA renewal: '
+                    'added tracking request for "%s"', nickname)
+            except RuntimeError as e:
+                logger.error(
+                    'Lightweight CA renewal: Certmonger failed to '
+                    'start tracking certificate: %s', e)
+        else:
+            logger.debug(
+                'Lightweight CA renewal: '
+                'already tracking certificate "%s"', nickname)
+
+
 def update_ipa_conf():
     """
     Update IPA configuration file to ensure that RA plugins are enabled and
-- 
2.5.5



More information about the Freeipa-devel mailing list