[Freeipa-devel] [PATCH] 0057..0058 Fix caIPAserviceCert regression

Fraser Tweedale ftweedal at redhat.com
Wed May 18 06:09:20 UTC 2016


Rebased version of 0057 attached, along with new patch 0058 that
detects when the Dogtag version of caIPAserviceCert has been
erroneously imported and repairs the profile.

Thanks,
Fraser
-------------- next part --------------
From 9994a98a0cd3bcf6b4af72708c7ac1cfdfdd5440 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Wed, 11 May 2016 16:13:51 +1000
Subject: [PATCH] Prevent replica install from overwriting cert profiles

An earlier change that unconditionally triggers import of file-based
profiles to LDAP during server or replica install results in
replicas overwriting FreeIPA-managed profiles with profiles of the
same name shipped with Dogtag. ('caIPAserviceCert' is the affected
profile).

Avoid this situation by never overwriting existing profiles during
the LDAP import.

Fixes: https://fedorahosted.org/freeipa/ticket/5881
---
 ipaserver/install/cainstance.py | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 3ca4fa8d373ebc3375a9fc75b59969292f0198f0..7e68b832831c3487c7bda466ba04d1a3eb51e780 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1764,7 +1764,9 @@ def import_included_profiles():
             conn.add_entry(entry)
             profile_data = ipautil.template_file(
                 '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
-            _create_dogtag_profile(profile_id, profile_data)
+
+            # Create the profile, replacing any existing profile of same name
+            _create_dogtag_profile(profile_id, profile_data, overwrite=True)
             root_logger.info("Imported profile '%s'", profile_id)
 
     api.Backend.ra_certprofile.override_port = None
@@ -1816,12 +1818,17 @@ def migrate_profiles_to_ldap(dogtag_constants):
                 profile_data += '\n'
             profile_data += 'profileId={}\n'.format(profile_id)
             profile_data += 'classId={}\n'.format(class_id)
-            _create_dogtag_profile(profile_id, profile_data)
+
+            # Import the profile, but do not replace it if it already exists.
+            # This prevents replicas from replacing IPA-managed profiles with
+            # Dogtag default profiles of same name.
+            #
+            _create_dogtag_profile(profile_id, profile_data, overwrite=False)
 
     api.Backend.ra_certprofile.override_port = None
 
 
-def _create_dogtag_profile(profile_id, profile_data):
+def _create_dogtag_profile(profile_id, profile_data, overwrite):
     with api.Backend.ra_certprofile as profile_api:
         # import the profile
         try:
@@ -1832,9 +1839,8 @@ def _create_dogtag_profile(profile_id, profile_data):
             root_logger.debug("Error migrating '{}': {}".format(
                 profile_id, e))
 
-            # conflicting profile; replace it if we are
-            # installing IPA, but keep it for upgrades
-            if api.env.context == 'installer':
+            # profile already exists
+            if overwrite:
                 try:
                     profile_api.disable_profile(profile_id)
                 except errors.RemoteRetrieveError:
-- 
2.5.5

-------------- next part --------------
From 9524513a6e7c1e9da7d0a20dfec1d1566158cef0 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Wed, 11 May 2016 16:13:51 +1000
Subject: [PATCH] Prevent replica install from overwriting cert profiles

An earlier change that unconditionally triggers import of file-based
profiles to LDAP during server or replica install results in
replicas overwriting FreeIPA-managed profiles with profiles of the
same name shipped with Dogtag. ('caIPAserviceCert' is the affected
profile).

Avoid this situation by never overwriting existing profiles during
the LDAP import.

Fixes: https://fedorahosted.org/freeipa/ticket/5881
---
 ipaserver/install/cainstance.py | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 10bc2afc416737e89ffa7255e50bec96eb86fcce..274694012d5afc8690c4d69356d5ae56ae0a44e1 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1665,7 +1665,9 @@ def import_included_profiles():
             conn.add_entry(entry)
             profile_data = ipautil.template_file(
                 '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
-            _create_dogtag_profile(profile_id, profile_data)
+
+            # Create the profile, replacing any existing profile of same name
+            _create_dogtag_profile(profile_id, profile_data, overwrite=True)
             root_logger.info("Imported profile '%s'", profile_id)
 
     api.Backend.ra_certprofile.override_port = None
@@ -1717,12 +1719,17 @@ def migrate_profiles_to_ldap():
                 profile_data += '\n'
             profile_data += 'profileId={}\n'.format(profile_id)
             profile_data += 'classId={}\n'.format(class_id)
-            _create_dogtag_profile(profile_id, profile_data)
+
+            # Import the profile, but do not replace it if it already exists.
+            # This prevents replicas from replacing IPA-managed profiles with
+            # Dogtag default profiles of same name.
+            #
+            _create_dogtag_profile(profile_id, profile_data, overwrite=False)
 
     api.Backend.ra_certprofile.override_port = None
 
 
-def _create_dogtag_profile(profile_id, profile_data):
+def _create_dogtag_profile(profile_id, profile_data, overwrite):
     with api.Backend.ra_certprofile as profile_api:
         # import the profile
         try:
@@ -1733,9 +1740,8 @@ def _create_dogtag_profile(profile_id, profile_data):
             root_logger.debug("Error migrating '{}': {}".format(
                 profile_id, e))
 
-            # conflicting profile; replace it if we are
-            # installing IPA, but keep it for upgrades
-            if api.env.context == 'installer':
+            # profile already exists
+            if overwrite:
                 try:
                     profile_api.disable_profile(profile_id)
                 except errors.RemoteRetrieveError:
-- 
2.5.5

-------------- next part --------------
From 67080ad78af7f701d3be266eaf9c42ee30e12a21 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Wed, 11 May 2016 16:13:51 +1000
Subject: [PATCH] Prevent replica install from overwriting cert profiles

An earlier change that unconditionally triggers import of file-based
profiles to LDAP during server or replica install results in
replicas overwriting FreeIPA-managed profiles with profiles of the
same name shipped with Dogtag. ('caIPAserviceCert' is the affected
profile).

Avoid this situation by never overwriting existing profiles during
the LDAP import.

Fixes: https://fedorahosted.org/freeipa/ticket/5881
---
 ipaserver/install/cainstance.py | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index a21f7d2671461dfb99797d39fc7ee5706317241f..7ba5a5ae72bea656c5818a9fd5909926eb4886d1 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1664,7 +1664,9 @@ def import_included_profiles():
             conn.add_entry(entry)
             profile_data = ipautil.template_file(
                 '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
-            _create_dogtag_profile(profile_id, profile_data)
+
+            # Create the profile, replacing any existing profile of same name
+            _create_dogtag_profile(profile_id, profile_data, overwrite=True)
             root_logger.info("Imported profile '%s'", profile_id)
 
     api.Backend.ra_certprofile.override_port = None
@@ -1716,12 +1718,17 @@ def migrate_profiles_to_ldap():
                 profile_data += '\n'
             profile_data += 'profileId={}\n'.format(profile_id)
             profile_data += 'classId={}\n'.format(class_id)
-            _create_dogtag_profile(profile_id, profile_data)
+
+            # Import the profile, but do not replace it if it already exists.
+            # This prevents replicas from replacing IPA-managed profiles with
+            # Dogtag default profiles of same name.
+            #
+            _create_dogtag_profile(profile_id, profile_data, overwrite=False)
 
     api.Backend.ra_certprofile.override_port = None
 
 
-def _create_dogtag_profile(profile_id, profile_data):
+def _create_dogtag_profile(profile_id, profile_data, overwrite):
     with api.Backend.ra_certprofile as profile_api:
         # import the profile
         try:
@@ -1732,9 +1739,8 @@ def _create_dogtag_profile(profile_id, profile_data):
             root_logger.debug("Error migrating '{}': {}".format(
                 profile_id, e))
 
-            # conflicting profile; replace it if we are
-            # installing IPA, but keep it for upgrades
-            if api.env.context == 'installer':
+            # profile already exists
+            if overwrite:
                 try:
                     profile_api.disable_profile(profile_id)
                 except errors.RemoteRetrieveError:
-- 
2.5.5

-------------- next part --------------
From c990ff5f8b376503a93ac661ced76fdda815243d Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Wed, 18 May 2016 14:10:39 +1000
Subject: [PATCH] Detect and repair incorrect caIPAserviceCert config

A regression caused replica installation to replace the FreeIPA
version of caIPAserviceCert with the version shipped by Dogtag.

During upgrade, detect and repair occurrences of this problem.

Part of: https://fedorahosted.org/freeipa/ticket/5881
---
 ipaserver/install/cainstance.py     | 49 ++++++++++++++++++++++++++++++++++---
 ipaserver/install/server/upgrade.py |  3 +++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 274694012d5afc8690c4d69356d5ae56ae0a44e1..1413f4ddc56959db7c4ebc897fc0d191999e85e2 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1619,14 +1619,18 @@ def configure_profiles_acl():
     conn.disconnect()
     return updated
 
-def import_included_profiles():
+
+def __get_profile_config(profile_id):
     sub_dict = dict(
         DOMAIN=ipautil.format_netloc(api.env.domain),
         IPA_CA_RECORD=IPA_CA_RECORD,
         CRL_ISSUER='CN=Certificate Authority,o=ipaca',
         SUBJECT_DN_O=dsinstance.DsInstance().find_subject_base(),
     )
+    return ipautil.template_file(
+        '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
 
+def import_included_profiles():
     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)
@@ -1663,10 +1667,9 @@ def import_included_profiles():
                 ipacertprofilestoreissued=['TRUE' if store_issued else 'FALSE'],
             )
             conn.add_entry(entry)
-            profile_data = ipautil.template_file(
-                '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
 
             # Create the profile, replacing any existing profile of same name
+            profile_data = __get_profile_config(profile_id)
             _create_dogtag_profile(profile_id, profile_data, overwrite=True)
             root_logger.info("Imported profile '%s'", profile_id)
 
@@ -1674,6 +1677,46 @@ def import_included_profiles():
     conn.disconnect()
 
 
+def repair_profile_caIPAserviceCert():
+    """
+    A regression caused replica installation to replace the FreeIPA
+    version of caIPAserviceCert with the version shipped by Dogtag.
+
+    This function detects and repairs occurrences of this problem.
+
+    """
+    api.Backend.ra_certprofile._read_password()
+    api.Backend.ra_certprofile.override_port = 8443
+
+    profile_id = 'caIPAserviceCert'
+
+    with api.Backend.ra_certprofile as profile_api:
+        try:
+            cur_config = profile_api.read_profile(profile_id).splitlines()
+        except errors.RemoteRetrieveError as e:
+            # no profile there to check/repair
+            api.Backend.ra_certprofile.override_port = None
+            return
+
+    indicators = [
+        "policyset.serverCertSet.1.default.params.name="
+            "CN=$request.req_subject_name.cn$, OU=pki-ipa, O=IPA ",
+        "policyset.serverCertSet.9.default.params.crlDistPointsPointName_0="
+            "https://ipa.example.com/ipa/crl/MasterCRL.bin",
+        ]
+    need_repair = all(l in cur_config for l in indicators)
+
+    if need_repair:
+        root_logger.debug(
+            "Detected that profile '{}' has been replaced with "
+            "incorrect version; begin repair.".format(profile_id))
+        _create_dogtag_profile(
+            profile_id, __get_profile_config(profile_id), overwrite=True)
+        root_logger.debug("Repair of profile '{}' complete.".format(profile_id))
+
+    api.Backend.ra_certprofile.override_port = None
+
+
 def migrate_profiles_to_ldap():
     """Migrate profiles from filesystem to LDAP.
 
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index e6bce6694f2a4bed99a714c6907f040f73c19423..045a4f6dc10b49921b2a3f451083ea4aa133175c 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1658,6 +1658,9 @@ def upgrade_configuration():
     ca_import_included_profiles(ca)
     add_default_caacl(ca)
 
+    if ca.is_configured():
+        cainstance.repair_profile_caIPAserviceCert()
+
     set_sssd_domain_option('ipa_server_mode', 'True')
 
     if ds_running and not ds.is_running():
-- 
2.5.5

-------------- next part --------------
From 001151508bc8e3e40ec7cec077ec850fc3eccbf9 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Wed, 18 May 2016 14:10:39 +1000
Subject: [PATCH] Detect and repair incorrect caIPAserviceCert config

A regression caused replica installation to replace the FreeIPA
version of caIPAserviceCert with the version shipped by Dogtag.

During upgrade, detect and repair occurrences of this problem.

Part of: https://fedorahosted.org/freeipa/ticket/5881
---
 ipaserver/install/cainstance.py     | 49 ++++++++++++++++++++++++++++++++++---
 ipaserver/install/server/upgrade.py |  3 +++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 7e68b832831c3487c7bda466ba04d1a3eb51e780..adbe968a429a6de5ed5c7a147bb6fda76127f444 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1718,14 +1718,18 @@ def configure_profiles_acl():
     conn.disconnect()
     return updated
 
-def import_included_profiles():
+
+def __get_profile_config(profile_id):
     sub_dict = dict(
         DOMAIN=ipautil.format_netloc(api.env.domain),
         IPA_CA_RECORD=IPA_CA_RECORD,
         CRL_ISSUER='CN=Certificate Authority,o=ipaca',
         SUBJECT_DN_O=dsinstance.DsInstance().find_subject_base(),
     )
+    return ipautil.template_file(
+        '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
 
+def import_included_profiles():
     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)
@@ -1762,10 +1766,9 @@ def import_included_profiles():
                 ipacertprofilestoreissued=['TRUE' if store_issued else 'FALSE'],
             )
             conn.add_entry(entry)
-            profile_data = ipautil.template_file(
-                '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
 
             # Create the profile, replacing any existing profile of same name
+            profile_data = __get_profile_config(profile_id)
             _create_dogtag_profile(profile_id, profile_data, overwrite=True)
             root_logger.info("Imported profile '%s'", profile_id)
 
@@ -1773,6 +1776,46 @@ def import_included_profiles():
     conn.disconnect()
 
 
+def repair_profile_caIPAserviceCert():
+    """
+    A regression caused replica installation to replace the FreeIPA
+    version of caIPAserviceCert with the version shipped by Dogtag.
+
+    This function detects and repairs occurrences of this problem.
+
+    """
+    api.Backend.ra_certprofile._read_password()
+    api.Backend.ra_certprofile.override_port = 8443
+
+    profile_id = 'caIPAserviceCert'
+
+    with api.Backend.ra_certprofile as profile_api:
+        try:
+            cur_config = profile_api.read_profile(profile_id).splitlines()
+        except errors.RemoteRetrieveError as e:
+            # no profile there to check/repair
+            api.Backend.ra_certprofile.override_port = None
+            return
+
+    indicators = [
+        "policyset.serverCertSet.1.default.params.name="
+            "CN=$request.req_subject_name.cn$, OU=pki-ipa, O=IPA ",
+        "policyset.serverCertSet.9.default.params.crlDistPointsPointName_0="
+            "https://ipa.example.com/ipa/crl/MasterCRL.bin",
+        ]
+    need_repair = all(l in cur_config for l in indicators)
+
+    if need_repair:
+        root_logger.debug(
+            "Detected that profile '{}' has been replaced with "
+            "incorrect version; begin repair.".format(profile_id))
+        _create_dogtag_profile(
+            profile_id, __get_profile_config(profile_id), overwrite=True)
+        root_logger.debug("Repair of profile '{}' complete.".format(profile_id))
+
+    api.Backend.ra_certprofile.override_port = None
+
+
 def migrate_profiles_to_ldap(dogtag_constants):
     """Migrate profiles from filesystem to LDAP.
 
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index c53b19a937d559b25da256670a5205ab40e0cadb..b0cd789d58408f720774adb276843a1b6ab6007d 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1554,6 +1554,9 @@ def upgrade_configuration():
     ca_import_included_profiles(ca)
     add_default_caacl(ca)
 
+    if ca.is_configured():
+        cainstance.repair_profile_caIPAserviceCert()
+
     set_sssd_domain_option('ipa_server_mode', 'True')
 
     if ds_running and not ds.is_running():
-- 
2.5.5

-------------- next part --------------
From cf49fc421a4aa163cd213a362093ad595049a781 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Wed, 18 May 2016 14:10:39 +1000
Subject: [PATCH] Detect and repair incorrect caIPAserviceCert config

A regression caused replica installation to replace the FreeIPA
version of caIPAserviceCert with the version shipped by Dogtag.

During upgrade, detect and repair occurrences of this problem.

Part of: https://fedorahosted.org/freeipa/ticket/5881
---
 ipaserver/install/cainstance.py     | 49 ++++++++++++++++++++++++++++++++++---
 ipaserver/install/server/upgrade.py |  3 +++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 7ba5a5ae72bea656c5818a9fd5909926eb4886d1..337a07797b26ff668f95d139ab35fbe491e6b470 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1618,14 +1618,18 @@ def configure_profiles_acl():
     conn.disconnect()
     return updated
 
-def import_included_profiles():
+
+def __get_profile_config(profile_id):
     sub_dict = dict(
         DOMAIN=ipautil.format_netloc(api.env.domain),
         IPA_CA_RECORD=IPA_CA_RECORD,
         CRL_ISSUER='CN=Certificate Authority,o=ipaca',
         SUBJECT_DN_O=dsinstance.DsInstance().find_subject_base(),
     )
+    return ipautil.template_file(
+        '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
 
+def import_included_profiles():
     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)
@@ -1662,10 +1666,9 @@ def import_included_profiles():
                 ipacertprofilestoreissued=['TRUE' if store_issued else 'FALSE'],
             )
             conn.add_entry(entry)
-            profile_data = ipautil.template_file(
-                '/usr/share/ipa/profiles/{}.cfg'.format(profile_id), sub_dict)
 
             # Create the profile, replacing any existing profile of same name
+            profile_data = __get_profile_config(profile_id)
             _create_dogtag_profile(profile_id, profile_data, overwrite=True)
             root_logger.info("Imported profile '%s'", profile_id)
 
@@ -1673,6 +1676,46 @@ def import_included_profiles():
     conn.disconnect()
 
 
+def repair_profile_caIPAserviceCert():
+    """
+    A regression caused replica installation to replace the FreeIPA
+    version of caIPAserviceCert with the version shipped by Dogtag.
+
+    This function detects and repairs occurrences of this problem.
+
+    """
+    api.Backend.ra_certprofile._read_password()
+    api.Backend.ra_certprofile.override_port = 8443
+
+    profile_id = 'caIPAserviceCert'
+
+    with api.Backend.ra_certprofile as profile_api:
+        try:
+            cur_config = profile_api.read_profile(profile_id).splitlines()
+        except errors.RemoteRetrieveError as e:
+            # no profile there to check/repair
+            api.Backend.ra_certprofile.override_port = None
+            return
+
+    indicators = [
+        "policyset.serverCertSet.1.default.params.name="
+            "CN=$request.req_subject_name.cn$, OU=pki-ipa, O=IPA ",
+        "policyset.serverCertSet.9.default.params.crlDistPointsPointName_0="
+            "https://ipa.example.com/ipa/crl/MasterCRL.bin",
+        ]
+    need_repair = all(l in cur_config for l in indicators)
+
+    if need_repair:
+        root_logger.debug(
+            "Detected that profile '{}' has been replaced with "
+            "incorrect version; begin repair.".format(profile_id))
+        _create_dogtag_profile(
+            profile_id, __get_profile_config(profile_id), overwrite=True)
+        root_logger.debug("Repair of profile '{}' complete.".format(profile_id))
+
+    api.Backend.ra_certprofile.override_port = None
+
+
 def migrate_profiles_to_ldap():
     """Migrate profiles from filesystem to LDAP.
 
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 38fe2c3e89da55faa30c624983cb8f9c630357b3..375d18522e9cfcf6d85c7a65b7be259bdd364134 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1643,6 +1643,9 @@ def upgrade_configuration():
     ca_import_included_profiles(ca)
     add_default_caacl(ca)
 
+    if ca.is_configured():
+        cainstance.repair_profile_caIPAserviceCert()
+
     set_sssd_domain_option('ipa_server_mode', 'True')
 
     if ds_running and not ds.is_running():
-- 
2.5.5



More information about the Freeipa-devel mailing list