diff --git a/SOURCES/0007-Catch-and-log-errors-when-adding-CA-profiles_rhbz#1999142.patch b/SOURCES/0007-Catch-and-log-errors-when-adding-CA-profiles_rhbz#1999142.patch new file mode 100644 index 0000000..34b33c7 --- /dev/null +++ b/SOURCES/0007-Catch-and-log-errors-when-adding-CA-profiles_rhbz#1999142.patch @@ -0,0 +1,53 @@ +From a6e708ab4006d6623c37de1692de5362fcdb5dd6 Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Mon, 30 Aug 2021 16:44:47 -0400 +Subject: [PATCH] Catch and log errors when adding CA profiles + +Rather than stopping the installer entirely, catch and report +errors adding new certificate profiles, and remove the +broken profile entry from LDAP so it may be re-added later. + +It was discovered that installing a newer IPA that has the +ACME profile which requires sanToCNDefault will fail when +installing a new server against a very old one that lacks +this class. + +Running ipa-server-upgrade post-install will add the profile +and generate the missing ipa-ca SAN record so that ACME +can work. + +https://pagure.io/freeipa/issue/8974 + +Signed-off-by: Rob Crittenden +Reviewed-By: Florence Blanc-Renaud +--- + ipaserver/install/cainstance.py | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py +index 9e842b33e..8c8bf1b3a 100644 +--- a/ipaserver/install/cainstance.py ++++ b/ipaserver/install/cainstance.py +@@ -1973,8 +1973,17 @@ def import_included_profiles(): + + # 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) +- logger.debug("Imported profile '%s'", profile_id) ++ try: ++ _create_dogtag_profile(profile_id, profile_data, ++ overwrite=True) ++ except errors.HTTPRequestError as e: ++ logger.warning("Failed to import profile '%s': %s. Running " ++ "ipa-server-upgrade when installation is " ++ "completed may resolve this issue.", ++ profile_id, e) ++ conn.delete_entry(entry) ++ else: ++ logger.debug("Imported profile '%s'", profile_id) + else: + logger.debug( + "Profile '%s' is already in LDAP; skipping", profile_id +-- +2.31.1 + diff --git a/SOURCES/0008-selinux-policy-allow-custodia-to-access-proc-cpuinfo_rhbz#1998129.patch b/SOURCES/0008-selinux-policy-allow-custodia-to-access-proc-cpuinfo_rhbz#1998129.patch new file mode 100644 index 0000000..14a8b03 --- /dev/null +++ b/SOURCES/0008-selinux-policy-allow-custodia-to-access-proc-cpuinfo_rhbz#1998129.patch @@ -0,0 +1,41 @@ +From 07e2bf732f54f936cccc4e0c7b468d77f97e911a Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Mon, 30 Aug 2021 18:40:24 +0200 +Subject: [PATCH] selinux policy: allow custodia to access /proc/cpuinfo + +On aarch64, custodia creates AVC when accessing /proc/cpuinfo. + +According to gcrypt manual +(https://gnupg.org/documentation/manuals/gcrypt/Configuration.html), +/proc/cpuinfo is used on ARM architecture to read the hardware +capabilities of the CPU. This explains why the issue happens only +on aarch64. + +audit2allow suggests to add the following: +allow ipa_custodia_t proc_t:file { getattr open read }; + +but this policy would be too broad. Instead, the patch is using +the interface kernel_read_system_state. + +Fixes: https://pagure.io/freeipa/issue/8972 +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: Christian Heimes +--- + selinux/ipa.te | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/selinux/ipa.te b/selinux/ipa.te +index 68e109419..7492fca04 100644 +--- a/selinux/ipa.te ++++ b/selinux/ipa.te +@@ -364,6 +364,7 @@ files_tmp_filetrans(ipa_custodia_t, ipa_custodia_tmp_t, { dir file }) + + kernel_dgram_send(ipa_custodia_t) + kernel_read_network_state(ipa_custodia_t) ++kernel_read_system_state(ipa_custodia_t) + + auth_read_passwd(ipa_custodia_t) + +-- +2.31.1 + diff --git a/SOURCES/0009-extdom-return-LDAP_NO_SUCH_OBJECT-if-domains-differ_rhbz#2000263.patch b/SOURCES/0009-extdom-return-LDAP_NO_SUCH_OBJECT-if-domains-differ_rhbz#2000263.patch new file mode 100644 index 0000000..e88902d --- /dev/null +++ b/SOURCES/0009-extdom-return-LDAP_NO_SUCH_OBJECT-if-domains-differ_rhbz#2000263.patch @@ -0,0 +1,46 @@ +From 4fca95751ca32a1ed16a6d8a4e557c5799ec5c78 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 25 Aug 2021 17:10:29 +0200 +Subject: [PATCH] extdom: return LDAP_NO_SUCH_OBJECT if domains differ + +If a client sends a request to lookup an object from a given trusted +domain by UID or GID and an object with matching ID is only found in a +different domain the extdom should return LDAP_NO_SUCH_OBJECT to +indicate to the client that the requested ID does not exists in the +given domain. + +Resolves: https://pagure.io/freeipa/issue/8965 +Reviewed-By: Rob Crittenden +--- + .../ipa-extdom-extop/ipa_extdom_common.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c +index 5d97ff613..6f646b9f4 100644 +--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c ++++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c +@@ -542,7 +542,9 @@ int pack_ber_user(struct ipa_extdom_ctx *ctx, + if (strcasecmp(locat+1, domain_name) == 0 ) { + locat[0] = '\0'; + } else { +- ret = LDAP_INVALID_SYNTAX; ++ /* The found object is from a different domain than requested, ++ * that means it does not exist in the requested domain */ ++ ret = LDAP_NO_SUCH_OBJECT; + goto done; + } + } +@@ -655,7 +657,9 @@ int pack_ber_group(enum response_types response_type, + if (strcasecmp(locat+1, domain_name) == 0 ) { + locat[0] = '\0'; + } else { +- ret = LDAP_INVALID_SYNTAX; ++ /* The found object is from a different domain than requested, ++ * that means it does not exist in the requested domain */ ++ ret = LDAP_NO_SUCH_OBJECT; + goto done; + } + } +-- +2.31.1 + diff --git a/SOURCES/0010-migrate-ds-workaround-to-detect-compat-tree_rhbz#1999992.patch b/SOURCES/0010-migrate-ds-workaround-to-detect-compat-tree_rhbz#1999992.patch new file mode 100644 index 0000000..8ea12a5 --- /dev/null +++ b/SOURCES/0010-migrate-ds-workaround-to-detect-compat-tree_rhbz#1999992.patch @@ -0,0 +1,37 @@ +From 3c4f9e7347965ff9a887147df34e720224ffa7cc Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Tue, 7 Sep 2021 17:06:53 +0200 +Subject: [PATCH] migrate-ds: workaround to detect compat tree + +Migrate-ds needs to check if compat tree is enabled before +migrating users and groups. The check is doing a base +search on cn=compat,$SUFFIX and considers the compat tree +enabled when the entry exists. + +Due to a bug in slapi-nis, the base search may return NotFound +even though the compat tree is enabled. The workaround is to +perform a base search on cn=users,cn=compat,$SUFFIX instead. + +Fixes: https://pagure.io/freeipa/issue/8984 +Reviewed-By: Alexander Bokovoy +--- + ipaserver/plugins/migration.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ipaserver/plugins/migration.py b/ipaserver/plugins/migration.py +index db5241915..6ee205fc8 100644 +--- a/ipaserver/plugins/migration.py ++++ b/ipaserver/plugins/migration.py +@@ -922,7 +922,8 @@ migration process might be incomplete\n''') + # check whether the compat plugin is enabled + if not options.get('compat'): + try: +- ldap.get_entry(DN(('cn', 'compat'), (api.env.basedn))) ++ ldap.get_entry(DN(('cn', 'users'), ('cn', 'compat'), ++ (api.env.basedn))) + return dict(result={}, failed={}, enabled=True, compat=False) + except errors.NotFound: + pass +-- +2.31.1 + diff --git a/SOURCES/0011-Test-ldapsearch-with-base-scope-works-with-_rhbz#2000553.patch b/SOURCES/0011-Test-ldapsearch-with-base-scope-works-with-_rhbz#2000553.patch new file mode 100644 index 0000000..450a75e --- /dev/null +++ b/SOURCES/0011-Test-ldapsearch-with-base-scope-works-with-_rhbz#2000553.patch @@ -0,0 +1,89 @@ +From a3d71eb72a6125a80a9d7b698f34dcb95dc25184 Mon Sep 17 00:00:00 2001 +From: Anuja More +Date: Thu, 5 Aug 2021 20:03:21 +0530 +Subject: [PATCH] ipatests: Test ldapsearch with base scope works with compat + tree. + +Added test to verify that ldapsearch for compat tree +with scope base and sub is not failing. + +Related: https://bugzilla.redhat.com/show_bug.cgi?id=1958909 + +Signed-off-by: Anuja More +Reviewed-By: Mohammad Rizwan +Reviewed-By: Florence Blanc-Renaud +--- + ipatests/test_integration/test_commands.py | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py +index 2035ced56..e3a0d867e 100644 +--- a/ipatests/test_integration/test_commands.py ++++ b/ipatests/test_integration/test_commands.py +@@ -1558,6 +1558,19 @@ class TestIPACommandWithoutReplica(IntegrationTest): + # Run the command again after cache is removed + self.master.run_command(['ipa', 'user-show', 'ipauser1']) + ++ def test_basesearch_compat_tree(self): ++ """Test ldapsearch against compat tree is working ++ ++ This to ensure that ldapsearch with base scope is not failing. ++ ++ related: https://bugzilla.redhat.com/show_bug.cgi?id=1958909 ++ """ ++ tasks.kinit_admin(self.master) ++ base_dn = str(self.master.domain.basedn) ++ base = "cn=admins,cn=groups,cn=compat,{basedn}".format(basedn=base_dn) ++ tasks.ldapsearch_dm(self.master, base, ldap_args=[], scope='sub') ++ tasks.ldapsearch_dm(self.master, base, ldap_args=[], scope='base') ++ + + class TestIPAautomount(IntegrationTest): + @classmethod +-- +2.31.1 + +From d4062e407d242a72b9d4e32f4fdd6aed086ce005 Mon Sep 17 00:00:00 2001 +From: Anuja More +Date: Thu, 5 Aug 2021 20:23:15 +0530 +Subject: [PATCH] ipatests: skip test_basesearch_compat_tree on fedora. + +slapi-nis with fix is not part of fedora yet. +test requires with fix: +https://pagure.io/slapi-nis/c/61ea8f6a104da25329e301a8f56944f860de8177? + +Signed-off-by: Anuja More +Reviewed-By: Mohammad Rizwan +Reviewed-By: Florence Blanc-Renaud +--- + ipatests/test_integration/test_commands.py | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py +index e3a0d867e..4d9a81652 100644 +--- a/ipatests/test_integration/test_commands.py ++++ b/ipatests/test_integration/test_commands.py +@@ -38,6 +38,7 @@ from ipatests.create_external_ca import ExternalCA + from ipatests.test_ipalib.test_x509 import good_pkcs7, badcert + from ipapython.ipautil import realm_to_suffix, ipa_generate_password + from ipaserver.install.installutils import realm_to_serverid ++from pkg_resources import parse_version + + logger = logging.getLogger(__name__) + +@@ -1565,6 +1566,12 @@ class TestIPACommandWithoutReplica(IntegrationTest): + + related: https://bugzilla.redhat.com/show_bug.cgi?id=1958909 + """ ++ version = self.master.run_command( ++ ["rpm", "-qa", "--qf", "%{VERSION}", "slapi-nis"] ++ ) ++ if tasks.get_platform(self.master) == "fedora" and parse_version( ++ version.stdout_text) <= parse_version("0.56.7"): ++ pytest.skip("Test requires slapi-nis with fix on fedora") + tasks.kinit_admin(self.master) + base_dn = str(self.master.domain.basedn) + base = "cn=admins,cn=groups,cn=compat,{basedn}".format(basedn=base_dn) +-- +2.31.1 + diff --git a/SOURCES/0012-ipatests-Test-unsecure-nsupdate_rhbz#2000553.patch b/SOURCES/0012-ipatests-Test-unsecure-nsupdate_rhbz#2000553.patch new file mode 100644 index 0000000..a223c94 --- /dev/null +++ b/SOURCES/0012-ipatests-Test-unsecure-nsupdate_rhbz#2000553.patch @@ -0,0 +1,162 @@ +From 4fdab0c94c4e17e42e5f38a0e671bea39bcc9b74 Mon Sep 17 00:00:00 2001 +From: Anuja More +Date: Mon, 9 Aug 2021 20:57:22 +0530 +Subject: [PATCH] ipatests: Test unsecure nsupdate. + +The test configures an external bind server on the ipa-server +(not the IPA-embedded DNS server) that allows unauthenticated nsupdates. + +When the IPA client is registered using ipa-client-install, +DNS records are added for the client in the bind server using nsupdate. +The first try is using GSS-TIG but fails as expected, and the client +installer then tries with unauthenticated nsupdate. + +Related : https://pagure.io/freeipa/issue/8402 + +Signed-off-by: Anuja More +Reviewed-By: Rob Crittenden +Reviewed-By: Florence Blanc-Renaud +--- + .../test_installation_client.py | 118 ++++++++++++++++++ + 1 file changed, 118 insertions(+) + +diff --git a/ipatests/test_integration/test_installation_client.py b/ipatests/test_integration/test_installation_client.py +index fa59a5255..014b0f6ab 100644 +--- a/ipatests/test_integration/test_installation_client.py ++++ b/ipatests/test_integration/test_installation_client.py +@@ -8,10 +8,15 @@ Module provides tests for various options of ipa-client-install. + + from __future__ import absolute_import + ++import pytest ++import re + import shlex ++import textwrap + ++from ipaplatform.paths import paths + from ipatests.test_integration.base import IntegrationTest + from ipatests.pytest_ipa.integration import tasks ++from ipatests.pytest_ipa.integration.firewall import Firewall + + + class TestInstallClient(IntegrationTest): +@@ -70,3 +75,116 @@ class TestInstallClient(IntegrationTest): + extra_args=['--ssh-trust-dns']) + result = self.clients[0].run_command(['cat', '/etc/ssh/ssh_config']) + assert 'HostKeyAlgorithms' not in result.stdout_text ++ ++ ++class TestClientInstallBind(IntegrationTest): ++ """ ++ The test configures an external bind server on the ipa-server ++ (not the IPA-embedded DNS server) that allows unauthenticated nsupdates. ++ When the IPA client is registered using ipa-client-install, ++ DNS records are added for the client in the bind server using nsupdate. ++ The first try is using GSS-TIG but fails as expected, and the client ++ installer then tries with unauthenticated nsupdate. ++ """ ++ ++ num_clients = 1 ++ ++ @classmethod ++ def install(cls, mh): ++ cls.client = cls.clients[0] ++ ++ @pytest.fixture ++ def setup_bindserver(self): ++ bindserver = self.master ++ named_conf_backup = tasks.FileBackup(self.master, paths.NAMED_CONF) ++ # create a zone in the BIND server that is identical to the IPA ++ add_zone = textwrap.dedent(""" ++ zone "{domain}" IN {{ type master; ++ file "{domain}.db"; allow-query {{ any; }}; ++ allow-update {{ any; }}; }}; ++ """).format(domain=bindserver.domain.name) ++ ++ namedcfg = bindserver.get_file_contents( ++ paths.NAMED_CONF, encoding='utf-8') ++ namedcfg += '\n' + add_zone ++ bindserver.put_file_contents(paths.NAMED_CONF, namedcfg) ++ ++ def update_contents(path, pattern, replace): ++ contents = bindserver.get_file_contents(path, encoding='utf-8') ++ namedcfg_query = re.sub(pattern, replace, contents) ++ bindserver.put_file_contents(path, namedcfg_query) ++ ++ update_contents(paths.NAMED_CONF, 'localhost;', 'any;') ++ update_contents(paths.NAMED_CONF, "listen-on port 53 { 127.0.0.1; };", ++ "#listen-on port 53 { 127.0.0.1; };") ++ update_contents(paths.NAMED_CONF, "listen-on-v6 port 53 { ::1; };", ++ "#listen-on-v6 port 53 { ::1; };") ++ ++ add_records = textwrap.dedent(""" ++ @ IN SOA {fqdn}. root.{domain}. ( ++ 1001 ;Serial ++ 3H ;Refresh ++ 15M ;Retry ++ 1W ;Expire ++ 1D ;Minimum 1D ++ ) ++ @ IN NS {fqdn}. ++ ns1 IN A {bindserverip} ++ _kerberos.{domain}. IN TXT {zoneupper} ++ {fqdn}. IN A {bindserverip} ++ ipa-ca.{domain}. IN A {bindserverip} ++ _kerberos-master._tcp.{domain}. IN SRV 0 100 88 {fqdn}. ++ _kerberos-master._udp.{domain}. IN SRV 0 100 88 {fqdn}. ++ _kerberos._tcp.{domain}. IN SRV 0 100 88 {fqdn}. ++ _kerberos._udp.{domain}. IN SRV 0 100 88 {fqdn}. ++ _kpasswd._tcp.{domain}. IN SRV 0 100 464 {fqdn}. ++ _kpasswd._udp.{domain}. IN SRV 0 100 464 {fqdn}. ++ _ldap._tcp.{domain}. IN SRV 0 100 389 {fqdn}. ++ """).format( ++ fqdn=bindserver.hostname, ++ domain=bindserver.domain.name, ++ bindserverip=bindserver.ip, ++ zoneupper=bindserver.domain.name.upper() ++ ) ++ bindserverdb = "/var/named/{0}.db".format(bindserver.domain.name) ++ bindserver.put_file_contents(bindserverdb, add_records) ++ bindserver.run_command(['systemctl', 'start', 'named']) ++ Firewall(bindserver).enable_services(["dns"]) ++ yield ++ named_conf_backup.restore() ++ bindserver.run_command(['rm', '-rf', bindserverdb]) ++ ++ def test_client_nsupdate(self, setup_bindserver): ++ """Test secure nsupdate failed, then try unsecure nsupdate.. ++ ++ Test to verify when bind is configured with dynamic update policy, ++ and during client-install 'nsupdate -g' fails then it should run with ++ second call using unauthenticated nsupdate. ++ ++ Related : https://pagure.io/freeipa/issue/8402 ++ """ ++ # with pre-configured bind server, install ipa-server without dns. ++ tasks.install_master(self.master, setup_dns=False) ++ self.client.resolver.backup() ++ self.client.resolver.setup_resolver( ++ self.master.ip, self.master.domain.name) ++ try: ++ self.client.run_command(['ipa-client-install', '-U', ++ '--domain', self.client.domain.name, ++ '--realm', self.client.domain.realm, ++ '-p', self.client.config.admin_name, ++ '-w', self.client.config.admin_password, ++ '--server', self.master.hostname]) ++ # call unauthenticated nsupdate if GSS-TSIG nsupdate failed. ++ str1 = "nsupdate (GSS-TSIG) failed" ++ str2 = "'/usr/bin/nsupdate', '/etc/ipa/.dns_update.txt'" ++ client_log = self.client.get_file_contents( ++ paths.IPACLIENT_INSTALL_LOG, encoding='utf-8' ++ ) ++ assert str1 in client_log and str2 in client_log ++ dig_after = self.client.run_command( ++ ['dig', '@{0}'.format(self.master.ip), self.client.hostname, ++ '-t', 'SSHFP']) ++ assert "ANSWER: 0" not in dig_after.stdout_text.strip() ++ finally: ++ self.client.resolver.restore() +-- +2.31.1 + diff --git a/SOURCES/0013-Don-t-store-entries-with-a-usercertificate-in-the-LD_rhbz#1999893.patch b/SOURCES/0013-Don-t-store-entries-with-a-usercertificate-in-the-LD_rhbz#1999893.patch new file mode 100644 index 0000000..739e7c3 --- /dev/null +++ b/SOURCES/0013-Don-t-store-entries-with-a-usercertificate-in-the-LD_rhbz#1999893.patch @@ -0,0 +1,128 @@ +From be1e3bbfc13aff9a583108376f245b81cc3666fb Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Thu, 9 Sep 2021 15:26:55 -0400 +Subject: [PATCH] Don't store entries with a usercertificate in the LDAP cache + +usercertificate often has a subclass and both the plain and +subclassed (binary) values are queried. I'm concerned that +they are used more or less interchangably in places so not +caching these entries is the safest path forward for now until +we can dedicate the time to find all usages, determine their +safety and/or perhaps handle this gracefully within the cache +now. + +What we see in this bug is that usercertificate;binary holds the +first certificate value but a user-mod is done with +setattr usercertificate=. Since there is no +usercertificate value (remember, it's usercertificate;binary) +a replace is done and 389-ds wipes the existing value as we've +asked it to. + +I'm not comfortable with simply treating them the same because +in LDAP they are not. + +https://pagure.io/freeipa/issue/8986 + +Signed-off-by: Rob Crittenden +Reviewed-By: Francois Cami +Reviewed-By: Fraser Tweedale +--- + ipapython/ipaldap.py | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py +index f94b784d6..ced8f1bd6 100644 +--- a/ipapython/ipaldap.py ++++ b/ipapython/ipaldap.py +@@ -1821,9 +1821,17 @@ class LDAPCache(LDAPClient): + entry=None, exception=None): + # idnsname - caching prevents delete when mod value to None + # cospriority - in a Class of Service object, uncacheable +- # TODO - usercertificate was banned at one point and I don't remember +- # why... +- BANNED_ATTRS = {'idnsname', 'cospriority'} ++ # usercertificate* - caching subtypes is tricky, trade less ++ # complexity for performance ++ # ++ # TODO: teach the cache about subtypes ++ ++ BANNED_ATTRS = { ++ 'idnsname', ++ 'cospriority', ++ 'usercertificate', ++ 'usercertificate;binary' ++ } + if not self._enable_cache: + return + +-- +2.31.1 + +From 86588640137562b2016fdb0f91142d00bc38e54a Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Fri, 10 Sep 2021 09:01:48 -0400 +Subject: [PATCH] ipatests: Test that a user can be issued multiple + certificates + +Prevent regressions in the LDAP cache layer that caused newly +issued certificates to overwrite existing ones. + +https://pagure.io/freeipa/issue/8986 + +Signed-off-by: Rob Crittenden +Reviewed-By: Francois Cami +Reviewed-By: Fraser Tweedale +--- + ipatests/test_integration/test_cert.py | 29 ++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/ipatests/test_integration/test_cert.py b/ipatests/test_integration/test_cert.py +index 7d51b76ee..b4e85eadc 100644 +--- a/ipatests/test_integration/test_cert.py ++++ b/ipatests/test_integration/test_cert.py +@@ -16,6 +16,7 @@ import string + import time + + from ipaplatform.paths import paths ++from ipapython.dn import DN + from cryptography import x509 + from cryptography.x509.oid import ExtensionOID + from cryptography.hazmat.backends import default_backend +@@ -183,6 +184,34 @@ class TestInstallMasterClient(IntegrationTest): + ) + assert "profile: caServerCert" in result.stdout_text + ++ def test_multiple_user_certificates(self): ++ """Test that a user may be issued multiple certificates""" ++ ldap = self.master.ldap_connect() ++ ++ user = 'user1' ++ ++ tasks.kinit_admin(self.master) ++ tasks.user_add(self.master, user) ++ ++ for id in (0,1): ++ csr_file = f'{id}.csr' ++ key_file = f'{id}.key' ++ cert_file = f'{id}.crt' ++ openssl_cmd = [ ++ 'openssl', 'req', '-newkey', 'rsa:2048', '-keyout', key_file, ++ '-nodes', '-out', csr_file, '-subj', '/CN=' + user] ++ self.master.run_command(openssl_cmd) ++ ++ cmd_args = ['ipa', 'cert-request', '--principal', user, ++ '--certificate-out', cert_file, csr_file] ++ self.master.run_command(cmd_args) ++ ++ # easier to count by pulling the LDAP entry ++ entry = ldap.get_entry(DN(('uid', user), ('cn', 'users'), ++ ('cn', 'accounts'), self.master.domain.basedn)) ++ ++ assert len(entry.get('usercertificate')) == 2 ++ + @pytest.fixture + def test_subca_certs(self): + """ +-- +2.31.1 + diff --git a/SPECS/ipa.spec b/SPECS/ipa.spec index 694581c..d45b5f0 100644 --- a/SPECS/ipa.spec +++ b/SPECS/ipa.spec @@ -191,7 +191,7 @@ Name: %{package_name} Version: %{IPA_VERSION} -Release: 4%{?rc_version:.%rc_version}%{?dist} +Release: 6%{?rc_version:.%rc_version}%{?dist} Summary: The Identity, Policy and Audit system License: GPLv3+ @@ -217,6 +217,13 @@ Patch0003: 0003-stageuser-add-ipauserauthtypeclass-when-required_rhbz#19796 Patch0004: 0004-man-page-update-ipa-server-upgrade.1_rhbz#1973273.patch Patch0005: 0005-Fall-back-to-krbprincipalname-when-validating-host-a_rhbz#1979625.patch Patch0006: 0006-rhel-platform-add-a-named-crypto-policy-support_rhbz#1982956.patch +Patch0007: 0007-Catch-and-log-errors-when-adding-CA-profiles_rhbz#1999142.patch +Patch0008: 0008-selinux-policy-allow-custodia-to-access-proc-cpuinfo_rhbz#1998129.patch +Patch0009: 0009-extdom-return-LDAP_NO_SUCH_OBJECT-if-domains-differ_rhbz#2000263.patch +Patch0010: 0010-migrate-ds-workaround-to-detect-compat-tree_rhbz#1999992.patch +Patch0011: 0011-Test-ldapsearch-with-base-scope-works-with-_rhbz#2000553.patch +Patch0012: 0012-ipatests-Test-unsecure-nsupdate_rhbz#2000553.patch +Patch0013: 0013-Don-t-store-entries-with-a-usercertificate-in-the-LD_rhbz#1999893.patch Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch %endif %endif @@ -1702,6 +1709,22 @@ fi %changelog +* Fri Sep 17 2021 Thomas Woerner - 4.9.6-6 +- Don't store entries with a usercertificate in the LDAP cache + Resolves: RHBZ#1999893 + +* Mon Sep 13 2021 Thomas Woerner - 4.9.6-5 +- Catch and log errors when adding CA profiles + Resolves: RHBZ#1999142 +- selinux policy: allow custodia to access /proc/cpuinfo + Resolves: RHBZ#1998129 +- extdom: LDAP_INVALID_SYNTAX returned instead of LDAP_NO_SUCH_OBJECT + Resolves: RHBZ#2000263 +- ipa migrate-ds command fails to warn when compat plugin is enabled + Resolves: RHBZ#1999992 +- Backport latest test fixes in python3-ipatests + Resolves: RHBZ#2000553 + * Thu Jul 22 2021 Thomas Woerner - 4.9.6-4 - ipatests: NAMED_CRYPTO_POLICY_FILE not defined for RHEL Resolves: RHBZ#1982956