From 7cca66eef575158676df73c63aad4f8ab44ca84b Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud Date: Fri, 6 Oct 2023 10:59:48 +0200 Subject: [PATCH] ipa-4.11.0-1 - Resolves: RHEL-11652 Rebase ipa to latest 4.11.x version for RHEL 9.4 --- .gitignore | 2 + ...-notification-which-hides-Add-button.patch | 35 -- ...hat-SSSD_PUBCONF_KRB5_INCLUDE_D_DIR-.patch | 48 -- ...penSSL-certificate-parser-in-cert-fi.patch | 103 ---- 0004-Revert-cert_find-fix-call-with-all.patch | 32 - ...ryptography-parser-directly-in-cert-.patch | 115 ---- ...rade-add-PKI-drop-in-file-if-missing.patch | 38 -- ...-add-a-test-for-upgrade-and-PKI-drop.patch | 53 -- ...stall-PKI-before-shutting-down-servi.patch | 129 ---- 0009-Detection-of-PKI-subsystem.patch | 44 -- 0010-Upgrade-fix-replica-agreement.patch | 164 ----- ...sts-add-a-test-to-ipa-server-upgrade.patch | 69 --- ...backup-restore-scenario-with-replica.patch | 55 -- ...-data-type-to-avoid-endianness-issue.patch | 54 -- ...firewall-rule-for-http-service-on-ac.patch | 42 -- ...ove-error-related-to-non-existing-id.patch | 79 --- ...-a-test-for-user-plugin-with-non-exi.patch | 122 ---- ...ry-leak-in-the-OTP-last-token-plugin.patch | 117 ---- ...nt-the-admin-user-from-being-deleted.patch | 136 ----- ...fix-error-handling-of-is_master_host.patch | 87 --- ...expected-webui-msg-for-admin-deletio.patch | 38 -- ...fixture-call-and-wait-to-get-things-.patch | 70 --- 0022-ipatests-fix-test_topology.patch | 60 -- 0023-ipatests-idm-api-related-tests.patch | 560 ------------------ ...tests-fixture-can-produce-IndexError.patch | 45 -- ...te-nss-and-pam-services-in-sssd.conf.patch | 42 -- freeipa.spec | 53 +- sources | 4 +- 28 files changed, 20 insertions(+), 2376 deletions(-) delete mode 100644 0001-webuitests-close-notification-which-hides-Add-button.patch delete mode 100644 0002-ipatests-Check-that-SSSD_PUBCONF_KRB5_INCLUDE_D_DIR-.patch delete mode 100644 0003-Revert-Use-the-OpenSSL-certificate-parser-in-cert-fi.patch delete mode 100644 0004-Revert-cert_find-fix-call-with-all.patch delete mode 100644 0005-Use-the-python-cryptography-parser-directly-in-cert-.patch delete mode 100644 0006-Upgrade-add-PKI-drop-in-file-if-missing.patch delete mode 100644 0007-Integration-test-add-a-test-for-upgrade-and-PKI-drop.patch delete mode 100644 0008-Uninstaller-uninstall-PKI-before-shutting-down-servi.patch delete mode 100644 0009-Detection-of-PKI-subsystem.patch delete mode 100644 0010-Upgrade-fix-replica-agreement.patch delete mode 100644 0011-Integration-tests-add-a-test-to-ipa-server-upgrade.patch delete mode 100644 0012-tests-fix-backup-restore-scenario-with-replica.patch delete mode 100644 0013-OTP-fix-data-type-to-avoid-endianness-issue.patch delete mode 100644 0014-ipatests-enable-firewall-rule-for-http-service-on-ac.patch delete mode 100644 0015-User-plugin-improve-error-related-to-non-existing-id.patch delete mode 100644 0016-xmlrpc-tests-add-a-test-for-user-plugin-with-non-exi.patch delete mode 100644 0017-Fix-memory-leak-in-the-OTP-last-token-plugin.patch delete mode 100644 0018-Prevent-the-admin-user-from-being-deleted.patch delete mode 100644 0019-ipa-kdb-fix-error-handling-of-is_master_host.patch delete mode 100644 0020-ipatests-update-expected-webui-msg-for-admin-deletio.patch delete mode 100644 0021-ipatests-remove-fixture-call-and-wait-to-get-things-.patch delete mode 100644 0022-ipatests-fix-test_topology.patch delete mode 100644 0023-ipatests-idm-api-related-tests.patch delete mode 100644 0024-ipatests-fixture-can-produce-IndexError.patch delete mode 100644 0025-Installer-activate-nss-and-pam-services-in-sssd.conf.patch diff --git a/.gitignore b/.gitignore index 85d0247..3b3628b 100644 --- a/.gitignore +++ b/.gitignore @@ -120,3 +120,5 @@ /freeipa-4.10.1.tar.gz.asc /freeipa-4.10.2.tar.gz /freeipa-4.10.2.tar.gz.asc +/freeipa-4.11.0.tar.gz +/freeipa-4.11.0.tar.gz.asc diff --git a/0001-webuitests-close-notification-which-hides-Add-button.patch b/0001-webuitests-close-notification-which-hides-Add-button.patch deleted file mode 100644 index f554010..0000000 --- a/0001-webuitests-close-notification-which-hides-Add-button.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 4f6ebb5fdf6d2514d4683247e5d1bfc6022a500e Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Tue, 6 Jun 2023 09:04:48 +0200 -Subject: [PATCH] webuitests: close notification which hides Add button - -The webui test test_service.py::test_service::test_arbitrary_certificates -randomly fails. -The test is creating a new service then navigates to the Service page -and clicks on the Add Certificate button. -The notification area may still be present and hide the button, with -the message "Service successfully added". -Close all notifications before navigating to the Service page. - -Fixes: https://pagure.io/freeipa/issue/9389 -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Michal Polovka ---- - ipatests/test_webui/test_service.py | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py -index f1d9a9d624bc587634e03a86050627a648feb26d..e2976d73acd1f574f1164828be9d8e871b737d7f 100644 ---- a/ipatests/test_webui/test_service.py -+++ b/ipatests/test_webui/test_service.py -@@ -296,6 +296,7 @@ class test_service(sevice_tasks): - cert_widget_sel = "div.certificate-widget" - - self.add_record(ENTITY, data) -+ self.close_notifications() - self.navigate_to_record(pkey) - - # check whether certificate section is present --- -2.41.0 - diff --git a/0002-ipatests-Check-that-SSSD_PUBCONF_KRB5_INCLUDE_D_DIR-.patch b/0002-ipatests-Check-that-SSSD_PUBCONF_KRB5_INCLUDE_D_DIR-.patch deleted file mode 100644 index 34d91f6..0000000 --- a/0002-ipatests-Check-that-SSSD_PUBCONF_KRB5_INCLUDE_D_DIR-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 8d34f453fb139c4cef055a4963f307a760316a73 Mon Sep 17 00:00:00 2001 -From: Anuja More -Date: Thu, 11 May 2023 12:50:10 +0530 -Subject: [PATCH] ipatests: Check that SSSD_PUBCONF_KRB5_INCLUDE_D_DIR is not - included in krb5.conf - -SSSD already provides a config snippet which includes -SSSD_PUBCONF_KRB5_INCLUDE_D_DIR, and having both breaks Java. -Test checks that krb5.conf does not include -SSSD_PUBCONF_KRB5_INCLUDE_D_DIR. - -Related: https://pagure.io/freeipa/issue/9267 - -Signed-off-by: Anuja More -Reviewed-By: Florence Blanc-Renaud ---- - .../test_integration/test_installation_client.py | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/ipatests/test_integration/test_installation_client.py b/ipatests/test_integration/test_installation_client.py -index 014b0f6ab34dd92c00c0187c2c86b8bfbaa70e81..56e1593bfcfa3eb7f9918fc6f2993d836884ea38 100644 ---- a/ipatests/test_integration/test_installation_client.py -+++ b/ipatests/test_integration/test_installation_client.py -@@ -76,6 +76,21 @@ class TestInstallClient(IntegrationTest): - result = self.clients[0].run_command(['cat', '/etc/ssh/ssh_config']) - assert 'HostKeyAlgorithms' not in result.stdout_text - -+ def test_client_install_with_krb5(self): -+ """Test that SSSD_PUBCONF_KRB5_INCLUDE_D_DIR is not added in krb5.conf -+ -+ SSSD already provides a config snippet which includes -+ SSSD_PUBCONF_KRB5_INCLUDE_D_DIR, and having both breaks Java. -+ Test checks that krb5.conf does not include -+ SSSD_PUBCONF_KRB5_INCLUDE_D_DIR. -+ -+ related: https://pagure.io/freeipa/issue/9267 -+ """ -+ krb5_cfg = self.master.get_file_contents(paths.KRB5_CONF) -+ assert 'includedir {dir}'.format( -+ dir=paths.SSSD_PUBCONF_KRB5_INCLUDE_D_DIR -+ ).encode() not in krb5_cfg -+ - - class TestClientInstallBind(IntegrationTest): - """ --- -2.41.0 - diff --git a/0003-Revert-Use-the-OpenSSL-certificate-parser-in-cert-fi.patch b/0003-Revert-Use-the-OpenSSL-certificate-parser-in-cert-fi.patch deleted file mode 100644 index 9f55246..0000000 --- a/0003-Revert-Use-the-OpenSSL-certificate-parser-in-cert-fi.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 276138087158c6b2ea76b43c754084144e543c0b Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Wed, 7 Jun 2023 11:32:21 -0400 -Subject: [PATCH] Revert "Use the OpenSSL certificate parser in cert-find" - -This reverts commit 191880bc9f77c3e8a3cecc82e6eea33ab5ad03e4. - -The problem isn't with python-cryptography, it is with the -IPACertificate class which does way more work on a certificate -than is necessary in cert-find. - -Related: https://pagure.io/freeipa/issue/9331 -Reviewed-By: Florence Blanc-Renaud ---- - freeipa.spec.in | 2 -- - ipaserver/plugins/cert.py | 26 +++----------------------- - 2 files changed, 3 insertions(+), 25 deletions(-) - -diff --git a/freeipa.spec.in b/freeipa.spec.in -index 3e23bbfe9d054a3a9febf468de0bcb4a6e81bb32..bec9780a82fe0d9bc5a50a93bdce8aa7e27a9f30 100755 ---- a/freeipa.spec.in -+++ b/freeipa.spec.in -@@ -412,7 +412,6 @@ BuildRequires: python3-pylint - BuildRequires: python3-pytest-multihost - BuildRequires: python3-pytest-sourceorder - BuildRequires: python3-qrcode-core >= 5.0.0 --BuildRequires: python3-pyOpenSSL - BuildRequires: python3-samba - BuildRequires: python3-six - BuildRequires: python3-sss -@@ -884,7 +883,6 @@ Requires: python3-netifaces >= 0.10.4 - Requires: python3-pyasn1 >= 0.3.2-2 - Requires: python3-pyasn1-modules >= 0.3.2-2 - Requires: python3-pyusb --Requires: python3-pyOpenSSL - Requires: python3-qrcode-core >= 5.0.0 - Requires: python3-requests - Requires: python3-six -diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py -index 400b1b3cec0aba82e699a4a981516e121f3e0c77..2e32f4ecd50ac92c28bcaffcebe9c2c87557858a 100644 ---- a/ipaserver/plugins/cert.py -+++ b/ipaserver/plugins/cert.py -@@ -30,7 +30,6 @@ import cryptography.x509 - from cryptography.hazmat.primitives import hashes, serialization - from dns import resolver, reversename - import six --import sys - - from ipalib import Command, Str, Int, Flag, StrEnum, SerialNumber - from ipalib import api -@@ -1618,19 +1617,7 @@ class cert_find(Search, CertMethod): - ) - - def _get_cert_key(self, cert): -- # for cert-find with a certificate value -- if isinstance(cert, x509.IPACertificate): -- return (DN(cert.issuer), cert.serial_number) -- -- issuer = [] -- for oid, value in cert.get_issuer().get_components(): -- issuer.append( -- '{}={}'.format(oid.decode('utf-8'), value.decode('utf-8')) -- ) -- issuer = ','.join(issuer) -- # Use this to flip from OpenSSL reverse to X500 ordering -- issuer = DN(issuer).x500_text() -- return (DN(issuer), cert.get_serial_number()) -+ return (DN(cert.issuer), cert.serial_number) - - def _cert_search(self, pkey_only, **options): - result = collections.OrderedDict() -@@ -1750,11 +1737,6 @@ class cert_find(Search, CertMethod): - return result, False, complete - - def _ldap_search(self, all, pkey_only, no_members, **options): -- # defer import of the OpenSSL module to not affect the requests -- # module which will use pyopenssl if this is available. -- if sys.modules.get('OpenSSL.SSL', False) is None: -- del sys.modules["OpenSSL.SSL"] -- import OpenSSL.crypto - ldap = self.api.Backend.ldap2 - - filters = [] -@@ -1813,14 +1795,12 @@ class cert_find(Search, CertMethod): - ca_enabled = getattr(context, 'ca_enabled') - for entry in entries: - for attr in ('usercertificate', 'usercertificate;binary'): -- for der in entry.raw.get(attr, []): -- cert = OpenSSL.crypto.load_certificate( -- OpenSSL.crypto.FILETYPE_ASN1, der) -+ for cert in entry.get(attr, []): - cert_key = self._get_cert_key(cert) - try: - obj = result[cert_key] - except KeyError: -- obj = {'serial_number': cert.get_serial_number()} -+ obj = {'serial_number': cert.serial_number} - if not pkey_only and (all or not ca_enabled): - # Retrieving certificate details is now deferred - # until after all certificates are collected. --- -2.41.0 - diff --git a/0004-Revert-cert_find-fix-call-with-all.patch b/0004-Revert-cert_find-fix-call-with-all.patch deleted file mode 100644 index baaa558..0000000 --- a/0004-Revert-cert_find-fix-call-with-all.patch +++ /dev/null @@ -1,32 +0,0 @@ -From d83a4b0babdc7beb124d3748b5815ce309739eb7 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Tue, 13 Jun 2023 17:01:49 -0400 -Subject: [PATCH] Revert "cert_find: fix call with --all" - -This reverts commit 1f30cc65276a532e7288217f216b72a2b0628c8f. - -The problem isn't with python-cryptography, it is with the -IPACertificate class which does way more work on a certificate -than is necessary in cert-find. - -Related: https://pagure.io/freeipa/issue/9331 -Reviewed-By: Florence Blanc-Renaud ---- - ipaserver/plugins/cert.py | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py -index 2e32f4ecd50ac92c28bcaffcebe9c2c87557858a..36a0e8cb31b4dbdd9bff09165d1d8aa203936d37 100644 ---- a/ipaserver/plugins/cert.py -+++ b/ipaserver/plugins/cert.py -@@ -1807,7 +1807,6 @@ class cert_find(Search, CertMethod): - # For the case of CA-less we need to keep - # the certificate because getting it again later - # would require unnecessary LDAP searches. -- cert = cert.to_cryptography() - obj['certificate'] = ( - base64.b64encode( - cert.public_bytes(x509.Encoding.DER)) --- -2.41.0 - diff --git a/0005-Use-the-python-cryptography-parser-directly-in-cert-.patch b/0005-Use-the-python-cryptography-parser-directly-in-cert-.patch deleted file mode 100644 index 1293cd0..0000000 --- a/0005-Use-the-python-cryptography-parser-directly-in-cert-.patch +++ /dev/null @@ -1,115 +0,0 @@ -From d9aa75459d650e5282a160a3eef09ed175dc5b51 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Wed, 7 Jun 2023 11:44:05 -0400 -Subject: [PATCH] Use the python-cryptography parser directly in cert-find - -cert-find is a rather complex beast because it not only -looks for certificates in the optional CA but within the -IPA LDAP database as well. It has a process to deduplicate -the certificates since any PKI issued certificates will -also be associated with an IPA record. - -In order to obtain the data to deduplicate the certificates -the cert from LDAP must be parser for issuer and serial number. -ipaldap has automation to determine the datatype of an -attribute and will use the ipalib.x509 IPACertificate class to -decode a certificate automatically if you access -entry['usercertificate']. - -The downside is that this is comparatively slow. Here is the -parse time in microseconds: - -cryptography 0.0081 -OpenSSL.crypto 0.2271 -ipalib.x509 2.6814 - -Since only issuer and subject are required there is no need to -make the expensive IPACertificate call. - -The IPACertificate parsing time is fine if you're parsing one -certificate but if the LDAP search returns a lot of certificates, -say in the thousands, then those microseconds add up quickly. -In testing it took ~17 seconds to parse 5k certificates (excluding -transmission overhead, etc). - -cert-find when there are a lot of certificates has been -historically slow. It isn't related to the CA which returns -large sets (well, 5k anyway) in a second or two. It was the -LDAP comparision adding tens of seconds to the runtime. - -When searching with the default sizelimit of 100 the time is -~10s without this patch. With it the time is 1.5s. - -CLI times from before and after searching for all certs: - -original: - -------------------------------- -Number of entries returned 5038 -------------------------------- -real 0m15.507s -user 0m0.828s -sys 0m0.241s - -using cryptography: - -real 0m4.037s -user 0m0.816s -sys 0m0.193s - -Fixes: https://pagure.io/freeipa/issue/9331 - -Signed-off-by: Rob Crittenden -Reviewed-By: Florence Blanc-Renaud ---- - ipaserver/plugins/cert.py | 3 ++- - ipatests/test_xmlrpc/test_cert_plugin.py | 12 +++++++++++- - 2 files changed, 13 insertions(+), 2 deletions(-) - -diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py -index 36a0e8cb31b4dbdd9bff09165d1d8aa203936d37..4fb85069a835d94969c9d05789714345ecc60e2e 100644 ---- a/ipaserver/plugins/cert.py -+++ b/ipaserver/plugins/cert.py -@@ -1795,7 +1795,8 @@ class cert_find(Search, CertMethod): - ca_enabled = getattr(context, 'ca_enabled') - for entry in entries: - for attr in ('usercertificate', 'usercertificate;binary'): -- for cert in entry.get(attr, []): -+ for der in entry.raw.get(attr, []): -+ cert = cryptography.x509.load_der_x509_certificate(der) - cert_key = self._get_cert_key(cert) - try: - obj = result[cert_key] -diff --git a/ipatests/test_xmlrpc/test_cert_plugin.py b/ipatests/test_xmlrpc/test_cert_plugin.py -index 433cebcd79f792e5c97307c6d599e50855ff4151..583c67fd942a61f42e578cc51a0e456cacf9a5e5 100644 ---- a/ipatests/test_xmlrpc/test_cert_plugin.py -+++ b/ipatests/test_xmlrpc/test_cert_plugin.py -@@ -254,6 +254,16 @@ class test_cert(BaseCert): - result = _emails_are_valid(email_addrs, []) - assert not result - -+ def test_00012_cert_find_all(self): -+ """ -+ Test that cert-find --all returns successfully. -+ -+ We don't know how many we'll get but there should be at least 10 -+ by default. -+ """ -+ res = api.Command['cert_find'](all=True) -+ assert 'count' in res and res['count'] >= 10 -+ - def test_99999_cleanup(self): - """ - Clean up cert test data -@@ -283,7 +293,7 @@ class test_cert_find(XMLRPC_test): - - short = api.env.host.split('.', maxsplit=1)[0] - -- def test_0001_find_all(self): -+ def test_0001_find_all_certs(self): - """ - Search for all certificates. - --- -2.41.0 - diff --git a/0006-Upgrade-add-PKI-drop-in-file-if-missing.patch b/0006-Upgrade-add-PKI-drop-in-file-if-missing.patch deleted file mode 100644 index 407363f..0000000 --- a/0006-Upgrade-add-PKI-drop-in-file-if-missing.patch +++ /dev/null @@ -1,38 +0,0 @@ -From f25003a730c0e28c22fae5fce607df734b55525c Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Mon, 19 Jun 2023 19:01:25 +0200 -Subject: [PATCH] Upgrade: add PKI drop-in file if missing - -During the installation of IPA server, the installer adds a drop-in -file in /etc/systemd/system/pki-tomcatd@pki-tomcat.service.d/ipa.conf -that ensures the CA is reachable before the start command returns. -If the file is missing (for instance because the server was installed -with an old version before this drop-in was created), the upgrade -should add the file. - -Fixes: https://pagure.io/freeipa/issue/9381 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipaserver/install/server/upgrade.py | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py -index f8701c8a0d43c7c1c1090e8576976b1c370b0104..8f3d57353605f28103c69cb0a34bf1c16fc4ae19 100644 ---- a/ipaserver/install/server/upgrade.py -+++ b/ipaserver/install/server/upgrade.py -@@ -1742,6 +1742,10 @@ def upgrade_configuration(): - os.path.join(paths.USR_SHARE_IPA_DIR, - "ipa-kdc-proxy.conf.template")) - if ca.is_configured(): -+ # Ensure that the drop-in file is present -+ if not os.path.isfile(paths.SYSTEMD_PKI_TOMCAT_IPA_CONF): -+ ca.add_ipa_wait() -+ - # Handle upgrade of AJP connector configuration - rewrite = ca.secure_ajp_connector() - if ca.ajp_secret: --- -2.41.0 - diff --git a/0007-Integration-test-add-a-test-for-upgrade-and-PKI-drop.patch b/0007-Integration-test-add-a-test-for-upgrade-and-PKI-drop.patch deleted file mode 100644 index 1e2912d..0000000 --- a/0007-Integration-test-add-a-test-for-upgrade-and-PKI-drop.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 392e60e3fa0e39a2e364268a21d869a2f3a85905 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Mon, 19 Jun 2023 19:04:32 +0200 -Subject: [PATCH] Integration test: add a test for upgrade and PKI drop-in file - -Add an upgrade test with the following scenario: -- remove PKI drop-in file (to simulate an upgrade from an old -version) -- remove caECServerCertWithSCT profile from LDAP -- launch the ipa-server-upgrade command -- check that the upgrade added the file - -Related: https://pagure.io/freeipa/issue/9381 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipatests/test_integration/test_upgrade.py | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/ipatests/test_integration/test_upgrade.py b/ipatests/test_integration/test_upgrade.py -index 9203503cdccf4478f9864bd487e458761e9a2a2f..182e3b5da3c758cc10913ad4eed119b0983fcc23 100644 ---- a/ipatests/test_integration/test_upgrade.py -+++ b/ipatests/test_integration/test_upgrade.py -@@ -455,3 +455,25 @@ class TestUpgrade(IntegrationTest): - assert 'tXTRecord' in location_krb_rec - assert len(location_krb_rec['tXTRecord']) == 1 - assert location_krb_rec['tXTRecord'][0] == f'"{realm}"' -+ -+ def test_pki_dropin_file(self): -+ """Test that upgrade adds the drop-in file if missing -+ -+ Test for ticket 9381 -+ Simulate an update from a version that didn't provide -+ /etc/systemd/system/pki-tomcatd@pki-tomcat.service.d/ipa.conf, -+ remove one of the certificate profiles from LDAP and check that upgrade -+ completes successfully and adds the missing file. -+ When the drop-in file is missing, the upgrade tries to login to -+ PKI in order to migrate the profile and fails because PKI failed to -+ start. -+ """ -+ self.master.run_command(["rm", "-f", paths.SYSTEMD_PKI_TOMCAT_IPA_CONF]) -+ ldif = textwrap.dedent(""" -+ dn: cn=caECServerCertWithSCT,ou=certificateProfiles,ou=ca,o=ipaca -+ changetype: delete -+ """) -+ tasks.ldapmodify_dm(self.master, ldif) -+ self.master.run_command(['ipa-server-upgrade']) -+ assert self.master.transport.file_exists( -+ paths.SYSTEMD_PKI_TOMCAT_IPA_CONF) --- -2.41.0 - diff --git a/0008-Uninstaller-uninstall-PKI-before-shutting-down-servi.patch b/0008-Uninstaller-uninstall-PKI-before-shutting-down-servi.patch deleted file mode 100644 index 2877404..0000000 --- a/0008-Uninstaller-uninstall-PKI-before-shutting-down-servi.patch +++ /dev/null @@ -1,129 +0,0 @@ -From f93a6d3ff52247ce5e582816fec689b8901fc984 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Wed, 14 Jun 2023 15:12:39 +0200 -Subject: [PATCH] Uninstaller: uninstall PKI before shutting down services - -The uninstaller is stopping all the services before -calling pkidestroy to uninstall the CA. -With PKI 11.4+ this sequence fails as pkidestroy tries -to connect to PKI server in order to unregister from the -security domain. The error interrupts the full completion -of pkidestroy, is logged but doesn't make ipa uninstallation -fail. -The issue is that trying to re-install later on would fail because -pkidestroy did not completely uninstall the CA. - -To avoid this, call pkidestroy before shutting down the services. -Also add an uninstall_check method that restarts IPA if it is -not running, and use pkidestroy --force to make sure that PKI -is uninstalled even if restart failed. - -Fixes: https://pagure.io/freeipa/issue/9330 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipaserver/install/ca.py | 18 ++++++++++++++++++ - ipaserver/install/dogtaginstance.py | 2 +- - ipaserver/install/kra.py | 2 ++ - ipaserver/install/server/install.py | 8 +++++--- - 4 files changed, 26 insertions(+), 4 deletions(-) - -diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py -index be0e732e8ff6966ccc0077d9339f9f0bc66ae6ec..c93ae1fce4c8848d493677eafee7952740e51631 100644 ---- a/ipaserver/install/ca.py -+++ b/ipaserver/install/ca.py -@@ -169,6 +169,24 @@ def print_ca_configuration(options): - - - def uninstall_check(options): -+ """IPA needs to be running so pkidestroy can unregister CA""" -+ ca = cainstance.CAInstance(api.env.realm) -+ if not ca.is_installed(): -+ return -+ -+ result = ipautil.run([paths.IPACTL, 'status'], -+ raiseonerr=False) -+ -+ if result.returncode not in [0, 4]: -+ try: -+ logger.info( -+ "Starting services to unregister CA from security domain") -+ ipautil.run([paths.IPACTL, 'start']) -+ except Exception: -+ logger.info("Re-starting IPA failed, continuing uninstall") -+ -+ -+def uninstall_crl_check(options): - """Check if the host is CRL generation master""" - # Skip the checks if the host is not a CA instance - ca = cainstance.CAInstance(api.env.realm) -diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py -index c2c6b3f49243f096448c178fafd09f429f0f46c8..4967aca01807e58dfcc3157af10b92eff5dba206 100644 ---- a/ipaserver/install/dogtaginstance.py -+++ b/ipaserver/install/dogtaginstance.py -@@ -305,7 +305,7 @@ class DogtagInstance(service.Service): - self.print_msg("Unconfiguring %s" % self.subsystem) - - args = [paths.PKIDESTROY, -- "-i", "pki-tomcat", -+ "-i", "pki-tomcat", "--force", - "-s", self.subsystem] - - # specify --log-file on PKI 11.0.0 or later -diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py -index 857c5165b808baee3f0815e78828fb899eb78a2d..59cbda812a853997752f7d932e0690e3a950aa1f 100644 ---- a/ipaserver/install/kra.py -+++ b/ipaserver/install/kra.py -@@ -132,6 +132,8 @@ def uninstall_check(options): - - if result.returncode not in [0, 4]: - try: -+ logger.info( -+ "Starting services to unregister KRA from security domain") - ipautil.run([paths.IPACTL, 'start']) - except Exception: - logger.info("Re-starting IPA failed, continuing uninstall") -diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py -index 4e4076410f1c1af188a0ab3606ef13be39702b7d..ccb958232935de2166f2d4867b626f59d7ba5333 100644 ---- a/ipaserver/install/server/install.py -+++ b/ipaserver/install/server/install.py -@@ -1110,6 +1110,7 @@ def uninstall_check(installer): - raise ScriptError("Aborting uninstall operation.") - - kra.uninstall_check(options) -+ ca.uninstall_check(options) - - try: - api.Backend.ldap2.connect(autobind=True) -@@ -1132,7 +1133,7 @@ def uninstall_check(installer): - else: - dns.uninstall_check(options) - -- ca.uninstall_check(options) -+ ca.uninstall_crl_check(options) - - cleanup_dogtag_server_specific_data() - -@@ -1181,6 +1182,9 @@ def uninstall(installer): - # Uninstall the KRA prior to shutting the services down so it - # can un-register with the CA. - kra.uninstall() -+ # Uninstall the CA priori to shutting the services down so it -+ # can unregister from the security domain -+ ca.uninstall() - - print("Shutting down all IPA services") - try: -@@ -1194,8 +1198,6 @@ def uninstall(installer): - - restore_time_sync(sstore, fstore) - -- ca.uninstall() -- - dns.uninstall() - - httpinstance.HTTPInstance(fstore).uninstall() --- -2.41.0 - diff --git a/0009-Detection-of-PKI-subsystem.patch b/0009-Detection-of-PKI-subsystem.patch deleted file mode 100644 index c85677a..0000000 --- a/0009-Detection-of-PKI-subsystem.patch +++ /dev/null @@ -1,44 +0,0 @@ -From b9a07b1e97ee4e310b50860103872685da540da4 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Mon, 19 Jun 2023 15:40:39 +0200 -Subject: [PATCH] Detection of PKI subsystem - -In order to know if ca/kra is installed locally, the code -is calling pki-server subsystem-show _subsystem_ -and ensures that "Enabled: True" is in the output. - -If a subsystem fails to start, the command returns -"Enabled: False" but it doesn't mean that the subsystem -is not installed, it just means that it is not active -right now. -Same output if the subsystem has been disabled with -pki-server subsystem-disable _subsystem_. - -The correct way to check if a subsystem is installed is to -ensure that subsystem-show does not exit on error and -contains "Enabled: ", whatever the value. - -Related: https://pagure.io/freeipa/issue/9330 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipaserver/install/dogtaginstance.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py -index 4967aca01807e58dfcc3157af10b92eff5dba206..7fdf2e0ed0f3ed99a6672f527d38dda0ce5ef8bb 100644 ---- a/ipaserver/install/dogtaginstance.py -+++ b/ipaserver/install/dogtaginstance.py -@@ -184,7 +184,7 @@ class DogtagInstance(service.Service): - ['pki-server', 'subsystem-show', self.subsystem.lower()], - capture_output=True) - # parse the command output -- return 'Enabled: True' in result.output -+ return 'Enabled: ' in result.output - except ipautil.CalledProcessError: - return False - --- -2.41.0 - diff --git a/0010-Upgrade-fix-replica-agreement.patch b/0010-Upgrade-fix-replica-agreement.patch deleted file mode 100644 index 46dc830..0000000 --- a/0010-Upgrade-fix-replica-agreement.patch +++ /dev/null @@ -1,164 +0,0 @@ -From ad77c4c6512f82019d1970d910647761b60aaedb Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Mon, 19 Jun 2023 10:36:29 +0200 -Subject: [PATCH] Upgrade: fix replica agreement - -The upgrade checks the replication agreements to ensure that -some attributes are excluded from replication. The agreements -are stored in entries like -cn=serverToreplica,cn=replica,cn=_suffix_,cn=mapping tree,cn=config -but those entries are managed by the replication topology plugin -and should not be updated directly. The consequence is that the update -of the attributes fails and ipa-server-update prints an error message: - -Error caught updating nsDS5ReplicatedAttributeList: Server is unwilling -to perform: Entry and attributes are managed by topology plugin.No direct -modifications allowed. -Error caught updating nsDS5ReplicatedAttributeListTotal: Server is -unwilling to perform: Entry and attributes are managed by topology -plugin.No direct modifications allowed. - -The upgrade continues but the replication is not excluding -passwordgraceusertime. - -Instead of editing the agreements, perform the modifications on -the topology segments. - -Fixes: https://pagure.io/freeipa/issue/9385 -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - .../install/plugins/fix_replica_agreements.py | 80 +++++++++---------- - 1 file changed, 38 insertions(+), 42 deletions(-) - -diff --git a/ipaserver/install/plugins/fix_replica_agreements.py b/ipaserver/install/plugins/fix_replica_agreements.py -index c0cdd3eb19c486121f727476360ce421b1d82728..d963753d0bf9ee65285a86fa9a249198c28a66e2 100644 ---- a/ipaserver/install/plugins/fix_replica_agreements.py -+++ b/ipaserver/install/plugins/fix_replica_agreements.py -@@ -22,6 +22,7 @@ import logging - from ipaserver.install import replication - from ipalib import Registry - from ipalib import Updater -+from ipalib import errors - - logger = logging.getLogger(__name__) - -@@ -41,35 +42,42 @@ class update_replica_attribute_lists(Updater): - def execute(self, **options): - # We need an LDAPClient connection to the backend - logger.debug("Start replication agreement exclude list update task") -- conn = self.api.Backend.ldap2 - -- repl = replication.ReplicationManager(self.api.env.realm, -- self.api.env.host, -- None, conn=conn) -- -- # We need to update only IPA replica agreements, not winsync -- ipa_replicas = repl.find_ipa_replication_agreements() -- -- logger.debug("Found %d agreement(s)", len(ipa_replicas)) -- -- for replica in ipa_replicas: -- for desc in replica.get('description', []): -- logger.debug('%s', desc) -- -- self._update_attr(repl, replica, -- 'nsDS5ReplicatedAttributeList', -- replication.EXCLUDES, template=EXCLUDE_TEMPLATE) -- self._update_attr(repl, replica, -- 'nsDS5ReplicatedAttributeListTotal', -- replication.TOTAL_EXCLUDES, template=EXCLUDE_TEMPLATE) -- self._update_attr(repl, replica, -- 'nsds5ReplicaStripAttrs', replication.STRIP_ATTRS) -+ # Find suffixes -+ suffixes = self.api.Command.topologysuffix_find()['result'] -+ for suffix in suffixes: -+ suffix_name = suffix['cn'][0] -+ # Find segments -+ sgmts = self.api.Command.topologysegment_find( -+ suffix_name, all=True)['result'] -+ for segment in sgmts: -+ updates = {} -+ updates = self._update_attr( -+ segment, updates, -+ 'nsds5replicatedattributelist', -+ replication.EXCLUDES, template=EXCLUDE_TEMPLATE) -+ updates = self._update_attr( -+ segment, updates, -+ 'nsds5replicatedattributelisttotal', -+ replication.TOTAL_EXCLUDES, template=EXCLUDE_TEMPLATE) -+ updates = self._update_attr( -+ segment, updates, -+ 'nsds5replicastripattrs', replication.STRIP_ATTRS) -+ if updates: -+ try: -+ self.api.Command.topologysegment_mod( -+ suffix_name, segment['cn'][0], -+ **updates) -+ except errors.EmptyModlist: -+ # No update done -+ logger.debug("No update required for the segment %s", -+ segment['cn'][0]) - - logger.debug("Done updating agreements") - - return False, [] # No restart, no updates - -- def _update_attr(self, repl, replica, attribute, values, template='%s'): -+ def _update_attr(self, segment, updates, attribute, values, template='%s'): - """Add or update an attribute of a replication agreement - - If the attribute doesn't already exist, it is added and set to -@@ -77,27 +85,21 @@ class update_replica_attribute_lists(Updater): - If the attribute does exist, `values` missing from it are just - appended to the end, also space-separated. - -- :param repl: Replication manager -- :param replica: Replica agreement -+ :param: updates: dict containing the updates -+ :param segment: dict containing segment information - :param attribute: Attribute to add or update - :param values: List of values the attribute should hold - :param template: Template to use when adding attribute - """ -- attrlist = replica.single_value.get(attribute) -+ attrlist = segment.get(attribute) - if attrlist is None: - logger.debug("Adding %s", attribute) - - # Need to add it altogether -- replica[attribute] = [template % " ".join(values)] -- -- try: -- repl.conn.update_entry(replica) -- logger.debug("Updated") -- except Exception as e: -- logger.error("Error caught updating replica: %s", str(e)) -+ updates[attribute] = template % " ".join(values) - - else: -- attrlist_normalized = attrlist.lower().split() -+ attrlist_normalized = attrlist[0].lower().split() - missing = [a for a in values - if a.lower() not in attrlist_normalized] - -@@ -105,14 +107,8 @@ class update_replica_attribute_lists(Updater): - logger.debug("%s needs updating (missing: %s)", attribute, - ', '.join(missing)) - -- replica[attribute] = [ -- '%s %s' % (attrlist, ' '.join(missing))] -+ updates[attribute] = '%s %s' % (attrlist[0], ' '.join(missing)) - -- try: -- repl.conn.update_entry(replica) -- logger.debug("Updated %s", attribute) -- except Exception as e: -- logger.error("Error caught updating %s: %s", -- attribute, str(e)) - else: - logger.debug("%s: No update necessary", attribute) -+ return updates --- -2.41.0 - diff --git a/0011-Integration-tests-add-a-test-to-ipa-server-upgrade.patch b/0011-Integration-tests-add-a-test-to-ipa-server-upgrade.patch deleted file mode 100644 index 27161d9..0000000 --- a/0011-Integration-tests-add-a-test-to-ipa-server-upgrade.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 3b58487c7b2f8ac133e37e8f90f85ff2fb05bf34 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Mon, 19 Jun 2023 10:36:59 +0200 -Subject: [PATCH] Integration tests: add a test to ipa-server-upgrade - -Add an integration test ensuring that the upgrade -properly updates the attributes to be excluded from -replication. - -Related: https://pagure.io/freeipa/issue/9385 -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - .../test_simple_replication.py | 30 +++++++++++++++++++ - 1 file changed, 30 insertions(+) - -diff --git a/ipatests/test_integration/test_simple_replication.py b/ipatests/test_integration/test_simple_replication.py -index 17092a49966e61d5a4a9b04c15abcb1de8be9683..d1e65ef7cc3e748670f2cdebe2a5cb7172af27f0 100644 ---- a/ipatests/test_integration/test_simple_replication.py -+++ b/ipatests/test_integration/test_simple_replication.py -@@ -23,8 +23,10 @@ import pytest - - from ipaplatform.paths import paths - from ipapython.dn import DN -+from ipaserver.install.replication import EXCLUDES - from ipatests.pytest_ipa.integration import tasks - from ipatests.test_integration.base import IntegrationTest -+from ipatests.test_integration.test_topology import find_segment - - - def check_replication(source_host, dest_host, login): -@@ -104,6 +106,34 @@ class TestSimpleReplication(IntegrationTest): - [paths.IPA_CUSTODIA_CHECK, self.master.hostname] - ) - -+ def test_fix_agreements(self): -+ """Test that upgrade fixes the list of attributes excluded from repl -+ -+ Test for ticket 9385 -+ """ -+ # Prepare the server by removing some values from -+ # from the nsDS5ReplicatedAttributeList -+ segment = find_segment(self.master, self.replicas[0], "domain") -+ self.master.run_command([ -+ "ipa", "topologysegment-mod", "domain", segment, -+ "--replattrs", -+ "(objectclass=*) $ EXCLUDE memberof idnssoaserial entryusn"]) -+ # Run the upgrade -+ result = self.master.run_command(["ipa-server-upgrade"]) -+ # Ensure that the upgrade updated the attribute without error -+ errmsg = "Error caught updating nsDS5ReplicatedAttributeList" -+ assert errmsg not in result.stdout_text -+ # Check the updated value -+ suffix = DN(self.master.domain.basedn) -+ dn = DN(('cn', str(suffix)), ('cn', 'mapping tree'), ('cn', 'config')) -+ result = tasks.ldapsearch_dm(self.master, str(dn), -+ ["nsDS5ReplicatedAttributeList"]) -+ output = result.stdout_text.lower() -+ -+ template = 'nsDS5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE %s' -+ expected_value = template % " ".join(EXCLUDES) -+ assert expected_value.lower() in output -+ - def test_replica_removal(self): - """Test replica removal""" - result = self.master.run_command(['ipa-replica-manage', 'list']) --- -2.41.0 - diff --git a/0012-tests-fix-backup-restore-scenario-with-replica.patch b/0012-tests-fix-backup-restore-scenario-with-replica.patch deleted file mode 100644 index 3c188e3..0000000 --- a/0012-tests-fix-backup-restore-scenario-with-replica.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5e291da42898cc646f699c21a44b03b833d346e8 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Tue, 27 Jun 2023 15:30:08 +0200 -Subject: [PATCH] tests: fix backup-restore scenario with replica - -The test TestBackupAndRestoreWithReplica is simulating a -master crash in order to check the behavior after ipa-restore. - -Since commit 67a33e5, the uninstaller restarts the services in -order to unregister the server from PKI security domain. An -indirect consequence is that master/replica communication is re- -established and operations removing entries (done by the uninstaller) -are replicated to the replica. -This means that the scenario does not really simulate a server crash. - -To make sure that no replication happens during this "crash", stop -the replica first, then uninstall the master, and finally restart -the replica before calling the ipa-restore command on the master. - -Fixes: https://pagure.io/freeipa/issue/9404 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipatests/test_integration/test_backup_and_restore.py | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/ipatests/test_integration/test_backup_and_restore.py b/ipatests/test_integration/test_backup_and_restore.py -index 390c065f373e9a8a667f228a09eebd9ac033a19f..83b6a6b44d805fb0615e2128d4be984c6f858bf9 100644 ---- a/ipatests/test_integration/test_backup_and_restore.py -+++ b/ipatests/test_integration/test_backup_and_restore.py -@@ -602,6 +602,12 @@ class TestBackupAndRestoreWithReplica(IntegrationTest): - tasks.user_add(self.replica1, 'test2_replica') - - # simulate master crash -+ # the replica is stopped to make sure master uninstallation -+ # does not delete any entry on the replica. In case of a -+ # real master crash there would not be any communication between -+ # master and replica -+ self.replica1.run_command(['ipactl', 'stop']) -+ - self.master.run_command(['ipactl', 'stop']) - tasks.uninstall_master(self.master, clean=False) - -@@ -612,6 +618,7 @@ class TestBackupAndRestoreWithReplica(IntegrationTest): - self.master.run_command([ - "systemctl", "disable", "oddjobd" - ]) -+ self.replica1.run_command(['ipactl', 'start']) - - self.master.run_command(['ipa-restore', '-U', backup_path]) - --- -2.41.0 - diff --git a/0013-OTP-fix-data-type-to-avoid-endianness-issue.patch b/0013-OTP-fix-data-type-to-avoid-endianness-issue.patch deleted file mode 100644 index e3dd65d..0000000 --- a/0013-OTP-fix-data-type-to-avoid-endianness-issue.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 631dd72369385b0793e5bc0e019c088b4f1e2bb3 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Mon, 26 Jun 2023 18:24:46 +0200 -Subject: [PATCH] OTP: fix data type to avoid endianness issue - -When 389-ds process an OTP authentication, the ipa-pwd-extop -plugin reads a buffer to extract the authentication type. -The type is stored in an int but the data is a ber_tag_t. - -On big endian machines the type cast does not cause any issue -but on s390x the buffer that should return 128 is seen as 0. - -As a consequence, the plugin considers that the method is not -LDAP_AUTH_SIMPLE and exits early, without processing the OTP. - -The fix is simple and consists in using the right type -(ber_tag_t is an unsigned long). - -Fixes: https://pagure.io/freeipa/issue/9402 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c -index 937594117956d57540d4cf4eabeef6d22860aec8..45626523ffa1030cdff4f3e0ccdfa1618a51ccaf 100644 ---- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c -+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c -@@ -1433,7 +1433,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb) - Slapi_DN *target_sdn = NULL; - Slapi_DN *sdn = NULL; - const char *dn = NULL; -- int method = 0; -+ ber_tag_t method = 0; - bool syncreq; - bool otpreq; - int ret = 0; -@@ -1454,8 +1454,10 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb) - } - - /* We're only interested in simple authentication. */ -- if (method != LDAP_AUTH_SIMPLE || credentials->bv_len == 0) -+ if (method != LDAP_AUTH_SIMPLE || credentials->bv_len == 0) { -+ LOG("Not handled (not simple bind or NULL dn/credentials)\n"); - return 0; -+ } - - /* Retrieve the user's entry. */ - sdn = slapi_sdn_dup(target_sdn); --- -2.41.0 - diff --git a/0014-ipatests-enable-firewall-rule-for-http-service-on-ac.patch b/0014-ipatests-enable-firewall-rule-for-http-service-on-ac.patch deleted file mode 100644 index 693cfad..0000000 --- a/0014-ipatests-enable-firewall-rule-for-http-service-on-ac.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1e8352486cd5f77ff79e18798f04f406baf0a9a1 Mon Sep 17 00:00:00 2001 -From: Mohammad Rizwan -Date: Wed, 14 Jun 2023 17:32:02 +0530 -Subject: [PATCH] ipatests: enable firewall rule for http service on acme - client - -when system hardning done i.e in case of STIG, sometimes http challanges -can't be validated by CA if port 80 is not open. This fix enable it to facilitate -the communication. - -Signed-off-by: Mohammad Rizwan -Reviewed-By: Rob Crittenden -Reviewed-By: Florence Blanc-Renaud ---- - ipatests/test_integration/test_acme.py | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py -index 9718c408b7f48dd78dc2abae32fb9ecb85445dfb..cca20983e65f99d5ba0bb7bc6dc2b5684a6f37d9 100644 ---- a/ipatests/test_integration/test_acme.py -+++ b/ipatests/test_integration/test_acme.py -@@ -10,6 +10,7 @@ import pytest - - from ipalib.constants import IPA_CA_RECORD - from ipatests.test_integration.base import IntegrationTest -+from ipatests.pytest_ipa.integration.firewall import Firewall - from ipatests.pytest_ipa.integration import tasks - from ipatests.test_integration.test_caless import CALessBase, ipa_certs_cleanup - from ipatests.test_integration.test_random_serial_numbers import ( -@@ -85,6 +86,9 @@ def prepare_acme_client(master, client): - acme_host = f'{IPA_CA_RECORD}.{master.domain.name}' - acme_server = f'https://{acme_host}/acme/directory' - -+ # enable firewall rule on client -+ Firewall(client).enable_services(["http", "https"]) -+ - # install acme client packages - if not skip_certbot_tests: - tasks.install_packages(client, ['certbot']) --- -2.41.0 - diff --git a/0015-User-plugin-improve-error-related-to-non-existing-id.patch b/0015-User-plugin-improve-error-related-to-non-existing-id.patch deleted file mode 100644 index c92a18c..0000000 --- a/0015-User-plugin-improve-error-related-to-non-existing-id.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 387873080f1bc14aeaad89311b06dc46934be1ab Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Wed, 19 Jul 2023 13:24:55 +0200 -Subject: [PATCH] User plugin: improve error related to non existing idp - -The user and stageuser commands return the following error -when the user is created/updated with a non existing idp: -$ ipa user-add testuser --first test --last user --idp dummy -ipa: ERROR: no such entry - -The error is not descriptive enough and has been modified to -display instead: -$ ipa user-add testuser --first test --last user --idp dummy -ipa: ERROR: External IdP configuration dummy not found - -Fixes: https://pagure.io/freeipa/issue/9416 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipaserver/plugins/baseuser.py | 6 +++++- - ipaserver/plugins/stageuser.py | 6 +++++- - ipaserver/plugins/user.py | 6 +++++- - 3 files changed, 15 insertions(+), 3 deletions(-) - -diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py -index 73b76d328a88639afd40bd261c8a35f324ec865b..ba5f9b7763662b32f238c0fb0ca548ff2f07db0d 100644 ---- a/ipaserver/plugins/baseuser.py -+++ b/ipaserver/plugins/baseuser.py -@@ -708,7 +708,11 @@ class baseuser_mod(LDAPUpdate): - if 'ipaidpuser' not in obj_classes: - entry_attrs['objectclass'].append('ipaidpuser') - -- answer = self.api.Object['idp'].get_dn_if_exists(cl) -+ try: -+ answer = self.api.Object['idp'].get_dn_if_exists(cl) -+ except errors.NotFound: -+ reason = "External IdP configuration {} not found" -+ raise errors.NotFound(reason=_(reason).format(cl)) - entry_attrs['ipaidpconfiglink'] = answer - - # Note: we could have used the method add_missing_object_class -diff --git a/ipaserver/plugins/stageuser.py b/ipaserver/plugins/stageuser.py -index 51438a83a95d15fb320148d2934a52f13a38f390..852e51b0eb0d757940b84721a6f01e43c5f36dd2 100644 ---- a/ipaserver/plugins/stageuser.py -+++ b/ipaserver/plugins/stageuser.py -@@ -404,7 +404,11 @@ class stageuser_add(baseuser_add): - if 'ipaidpuser' not in entry_attrs['objectclass']: - entry_attrs['objectclass'].append('ipaidpuser') - -- answer = self.api.Object['idp'].get_dn_if_exists(cl) -+ try: -+ answer = self.api.Object['idp'].get_dn_if_exists(cl) -+ except errors.NotFound: -+ reason = "External IdP configuration {} not found" -+ raise errors.NotFound(reason=_(reason).format(cl)) - entry_attrs['ipaidpconfiglink'] = answer - - self.pre_common_callback(ldap, dn, entry_attrs, attrs_list, *keys, -diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py -index 643b44f141e3add76f95cbeec6e90fec0ad4c9ad..a337e1fc7b44ef41ad16e18bd965b7af0a767d05 100644 ---- a/ipaserver/plugins/user.py -+++ b/ipaserver/plugins/user.py -@@ -638,7 +638,11 @@ class user_add(baseuser_add): - if 'ipaidpuser' not in entry_attrs['objectclass']: - entry_attrs['objectclass'].append('ipaidpuser') - -- answer = self.api.Object['idp'].get_dn_if_exists(rcl) -+ try: -+ answer = self.api.Object['idp'].get_dn_if_exists(rcl) -+ except errors.NotFound: -+ reason = "External IdP configuration {} not found" -+ raise errors.NotFound(reason=_(reason).format(rcl)) - entry_attrs['ipaidpconfiglink'] = answer - - self.pre_common_callback(ldap, dn, entry_attrs, attrs_list, *keys, --- -2.41.0 - diff --git a/0016-xmlrpc-tests-add-a-test-for-user-plugin-with-non-exi.patch b/0016-xmlrpc-tests-add-a-test-for-user-plugin-with-non-exi.patch deleted file mode 100644 index e5bae94..0000000 --- a/0016-xmlrpc-tests-add-a-test-for-user-plugin-with-non-exi.patch +++ /dev/null @@ -1,122 +0,0 @@ -From caacccc6b92c08f510fba2e31d9c56eb372abddc Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Wed, 19 Jul 2023 13:28:43 +0200 -Subject: [PATCH] xmlrpc tests: add a test for user plugin with non-existing - idp - -Add new tests checking the error returned for -ipa user-add ... --idp nonexistingidp -ipa user-mod ... --idp nonexistingidp -ipa stageuser-add ... --idp nonexistingidp -ipa stageuser-mod ... --idp nonexistingidp - -The expected error message is: -ipa: ERROR: External IdP configuration nonexistingidp not found - -Related: https://pagure.io/freeipa/issue/9416 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipatests/test_xmlrpc/test_stageuser_plugin.py | 20 +++++++++++++++ - ipatests/test_xmlrpc/test_user_plugin.py | 25 +++++++++++++++++++ - 2 files changed, 45 insertions(+) - -diff --git a/ipatests/test_xmlrpc/test_stageuser_plugin.py b/ipatests/test_xmlrpc/test_stageuser_plugin.py -index 394015f87f9f4bd275a15bab930e28f16b299274..9ae5561dfa4e0d54fe1231501bfea3c0ba261849 100644 ---- a/ipatests/test_xmlrpc/test_stageuser_plugin.py -+++ b/ipatests/test_xmlrpc/test_stageuser_plugin.py -@@ -39,6 +39,8 @@ gid = u'456' - invalidrealm1 = u'suser1@NOTFOUND.ORG' - invalidrealm2 = u'suser1@BAD@NOTFOUND.ORG' - -+nonexistentidp = 'IdPDoesNotExist' -+ - invaliduser1 = u'+tuser1' - invaliduser2 = u'tuser1234567890123456789012345678901234567890' - -@@ -431,6 +433,15 @@ class TestCreateInvalidAttributes(XMLRPC_test): - invalidrealm2))): - command() - -+ def test_create_invalid_idp(self, stageduser): -+ stageduser.ensure_missing() -+ command = stageduser.make_create_command( -+ options={u'ipaidpconfiglink': nonexistentidp}) -+ with raises_exact(errors.NotFound( -+ reason="External IdP configuration {} not found".format( -+ nonexistentidp))): -+ command() -+ - - @pytest.mark.tier1 - class TestUpdateInvalidAttributes(XMLRPC_test): -@@ -466,6 +477,15 @@ class TestUpdateInvalidAttributes(XMLRPC_test): - message=u'invalid \'gidnumber\': must be at least 1')): - command() - -+ def test_update_invalididp(self, stageduser): -+ stageduser.ensure_exists() -+ command = stageduser.make_update_command( -+ updates={u'ipaidpconfiglink': nonexistentidp}) -+ with raises_exact(errors.NotFound( -+ reason="External IdP configuration {} not found".format( -+ nonexistentidp))): -+ command() -+ - - @pytest.mark.tier1 - class TestActive(XMLRPC_test): -diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py -index 8ac19a4f9ce4f341838282ecd3ed1bb491ac7004..baa28672e7552140a703ecdfa5772b445298cb37 100644 ---- a/ipatests/test_xmlrpc/test_user_plugin.py -+++ b/ipatests/test_xmlrpc/test_user_plugin.py -@@ -86,6 +86,8 @@ expired_expiration_string = "1991-12-07T19:54:13Z" - # Date in ISO format (2013-12-10T12:00:00) - isodate_re = re.compile(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$') - -+nonexistentidp = 'IdPDoesNotExist' -+ - - @pytest.fixture(scope='class') - def user_min(request, xmlrpc_setup): -@@ -542,6 +544,18 @@ class TestUpdate(XMLRPC_test): - command() - user.delete() - -+ def test_update_invalid_idp(self, user): -+ """ Test user-mod --idp with a non-existent idp """ -+ user.ensure_exists() -+ command = user.make_update_command( -+ updates=dict(ipaidpconfiglink=nonexistentidp) -+ ) -+ with raises_exact(errors.NotFound( -+ reason="External IdP configuration {} not found".format( -+ nonexistentidp) -+ )): -+ command() -+ - - @pytest.mark.tier1 - class TestCreate(XMLRPC_test): -@@ -770,6 +784,17 @@ class TestCreate(XMLRPC_test): - user_radius.check_create(result) - user_radius.delete() - -+ def test_create_with_invalididp(self): -+ testuser = UserTracker( -+ name='idpuser', givenname='idp', sn='user', -+ ipaidpconfiglink=nonexistentidp -+ ) -+ with raises_exact(errors.NotFound( -+ reason="External IdP configuration {} not found".format( -+ nonexistentidp) -+ )): -+ testuser.create() -+ - - @pytest.mark.tier1 - class TestUserWithGroup(XMLRPC_test): --- -2.41.0 - diff --git a/0017-Fix-memory-leak-in-the-OTP-last-token-plugin.patch b/0017-Fix-memory-leak-in-the-OTP-last-token-plugin.patch deleted file mode 100644 index 08b2092..0000000 --- a/0017-Fix-memory-leak-in-the-OTP-last-token-plugin.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 421e8e9ac886c50b4bb463a62b8ad5de8da94f31 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Mon, 26 Jun 2023 13:06:51 -0400 -Subject: [PATCH] Fix memory leak in the OTP last token plugin - -Three memory leaks are addressed: - -1. String values retrieved from the pblock need to be manually -freed. - -2. The list of objectclasses retreived from the pblock need to be -freed. - -3. Internal search results need to be freed. - -Fixes: https://pagure.io/freeipa/issue/9403 - -Signed-off-by: Rob Crittenden -Reviewed-By: Rafael Guterres Jeffman -Reviewed-By: Alexander Bokovoy ---- - .../ipa-otp-lasttoken/ipa_otp_lasttoken.c | 38 +++++++++++++------ - daemons/ipa-slapi-plugins/libotp/otp_token.c | 1 + - 2 files changed, 27 insertions(+), 12 deletions(-) - -diff --git a/daemons/ipa-slapi-plugins/ipa-otp-lasttoken/ipa_otp_lasttoken.c b/daemons/ipa-slapi-plugins/ipa-otp-lasttoken/ipa_otp_lasttoken.c -index b7a2ba7f012fdbf90284ee6605788e196aa4793b..11106b239f9de9074125979cfae7c02e434936e1 100644 ---- a/daemons/ipa-slapi-plugins/ipa-otp-lasttoken/ipa_otp_lasttoken.c -+++ b/daemons/ipa-slapi-plugins/ipa-otp-lasttoken/ipa_otp_lasttoken.c -@@ -54,7 +54,7 @@ void *ipa_otp_lasttoken_plugin_id; - - static bool entry_is_token(Slapi_Entry *entry) - { -- char **ocls; -+ char **ocls = NULL; - - ocls = slapi_entry_attr_get_charray(entry, SLAPI_ATTR_OBJECTCLASS); - for (size_t i = 0; ocls != NULL && ocls[i] != NULL; i++) { -@@ -64,6 +64,7 @@ static bool entry_is_token(Slapi_Entry *entry) - } - } - -+ slapi_ch_array_free(ocls); - return false; - } - -@@ -138,7 +139,8 @@ static bool is_pwd_enabled(const char *user_dn) - static bool is_allowed(Slapi_PBlock *pb, Slapi_Entry *entry) - { - Slapi_DN *target_sdn = NULL; -- const char *bind_dn; -+ char *bind_dn; -+ bool rv = false; - - /* Ignore internal operations. */ - if (slapi_op_internal(pb)) -@@ -147,23 +149,35 @@ static bool is_allowed(Slapi_PBlock *pb, Slapi_Entry *entry) - /* Load parameters. */ - (void) slapi_pblock_get(pb, SLAPI_TARGET_SDN, &target_sdn); - (void) slapi_pblock_get(pb, SLAPI_CONN_DN, &bind_dn); -- if (target_sdn == NULL || bind_dn == NULL) { -- LOG_FATAL("Missing parameters!\n"); -- return false; -+ if (bind_dn == NULL) { -+ LOG_FATAL("bind_dn parameter missing!\n"); -+ goto done; -+ } -+ if (target_sdn == NULL) { -+ LOG_FATAL("target_sdn parameter missing!\n"); -+ goto done; - } - - if (entry != NULL - ? !entry_is_token(entry) -- : !sdn_in_otp_container(target_sdn)) -- return true; -+ : !sdn_in_otp_container(target_sdn)) { -+ rv = true; -+ goto done; -+ } - -- if (!sdn_is_only_enabled_token(target_sdn, bind_dn)) -- return true; -+ if (!sdn_is_only_enabled_token(target_sdn, bind_dn)) { -+ rv = true; -+ goto done; -+ } - -- if (is_pwd_enabled(bind_dn)) -- return true; -+ if (is_pwd_enabled(bind_dn)) { -+ rv = true; -+ goto done; -+ } - -- return false; -+done: -+ slapi_ch_free_string(&bind_dn); -+ return rv; - } - - static inline int send_error(Slapi_PBlock *pb, int rc, const char *errstr) -diff --git a/daemons/ipa-slapi-plugins/libotp/otp_token.c b/daemons/ipa-slapi-plugins/libotp/otp_token.c -index a3cbfb0621c071f8addb29f7ce02f870a807c61d..4be4ede07cbbd0d26bcc9952ef4d84d777076ae7 100644 ---- a/daemons/ipa-slapi-plugins/libotp/otp_token.c -+++ b/daemons/ipa-slapi-plugins/libotp/otp_token.c -@@ -398,6 +398,7 @@ static struct otp_token **find(const struct otp_config *cfg, const char *user_dn - } - - error: -+ slapi_free_search_results_internal(pb); - slapi_pblock_destroy(pb); - return tokens; - } --- -2.41.0 - diff --git a/0018-Prevent-the-admin-user-from-being-deleted.patch b/0018-Prevent-the-admin-user-from-being-deleted.patch deleted file mode 100644 index ee01e45..0000000 --- a/0018-Prevent-the-admin-user-from-being-deleted.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 4b02322fc786ee9caaa0380659507a2cec0d4101 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Thu, 25 May 2023 18:24:29 -0400 -Subject: [PATCH] Prevent the admin user from being deleted - -admin is required for trust operations - -Note that testing for removing the last member is now -irrelevant because admin must always exist so the test -for it was removed, but the code check remains. It is done -after the protected member check. - -Fixes: https://pagure.io/freeipa/issue/8878 - -Signed-off-by: Rob Crittenden -Reviewed-By: Alexander Bokovoy ---- - ipaserver/plugins/user.py | 19 +++++++++-- - ipatests/test_xmlrpc/test_user_plugin.py | 40 ++++++++++++------------ - 2 files changed, 37 insertions(+), 22 deletions(-) - -diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py -index a337e1fc7b44ef41ad16e18bd965b7af0a767d05..6f5e34917e1b838a463dee146a4e9390f20c130a 100644 ---- a/ipaserver/plugins/user.py -+++ b/ipaserver/plugins/user.py -@@ -138,14 +138,23 @@ MEMBEROF_ADMINS = "(memberOf={})".format( - ) - - NOT_MEMBEROF_ADMINS = '(!{})'.format(MEMBEROF_ADMINS) -+PROTECTED_USERS = ('admin',) - - - def check_protected_member(user, protected_group_name=u'admins'): - ''' -- Ensure the last enabled member of a protected group cannot be deleted or -- disabled by raising LastMemberError. -+ Ensure admin and the last enabled member of a protected group cannot -+ be deleted or disabled by raising ProtectedEntryError or -+ LastMemberError as appropriate. - ''' - -+ if user in PROTECTED_USERS: -+ raise errors.ProtectedEntryError( -+ label=_("user"), -+ key=user, -+ reason=_("privileged user"), -+ ) -+ - # Get all users in the protected group - result = api.Command.user_find(in_group=protected_group_name) - -@@ -868,6 +877,12 @@ class user_mod(baseuser_mod): - - def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): - dn, oc = self.obj.get_either_dn(*keys, **options) -+ if options.get('rename') and keys[-1] in PROTECTED_USERS: -+ raise errors.ProtectedEntryError( -+ label=_("user"), -+ key=keys[-1], -+ reason=_("privileged user"), -+ ) - if 'objectclass' not in entry_attrs and 'rename' not in options: - entry_attrs.update({'objectclass': oc}) - self.pre_common_callback(ldap, dn, entry_attrs, attrs_list, *keys, -diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py -index baa28672e7552140a703ecdfa5772b445298cb37..df105a23529b29944411a6418e5db55d56e2c72a 100644 ---- a/ipatests/test_xmlrpc/test_user_plugin.py -+++ b/ipatests/test_xmlrpc/test_user_plugin.py -@@ -978,22 +978,32 @@ class TestManagers(XMLRPC_test): - - @pytest.mark.tier1 - class TestAdmins(XMLRPC_test): -- def test_remove_original_admin(self): -- """ Try to remove the only admin """ -+ def test_delete_admin(self): -+ """ Try to delete the protected admin user """ - tracker = Tracker() -- command = tracker.make_command('user_del', [admin1]) -+ command = tracker.make_command('user_del', admin1) - -- with raises_exact(errors.LastMemberError( -- key=admin1, label=u'group', container=admin_group)): -+ with raises_exact(errors.ProtectedEntryError(label=u'user', -+ key=admin1, reason='privileged user')): -+ command() -+ -+ def test_rename_admin(self): -+ """ Try to rename the admin user """ -+ tracker = Tracker() -+ command = tracker.make_command('user_mod', admin1, -+ **dict(rename=u'newadmin')) -+ -+ with raises_exact(errors.ProtectedEntryError(label=u'user', -+ key=admin1, reason='privileged user')): - command() - - def test_disable_original_admin(self): -- """ Try to disable the only admin """ -+ """ Try to disable the original admin """ - tracker = Tracker() - command = tracker.make_command('user_disable', admin1) - -- with raises_exact(errors.LastMemberError( -- key=admin1, label=u'group', container=admin_group)): -+ with raises_exact(errors.ProtectedEntryError(label=u'user', -+ key=admin1, reason='privileged user')): - command() - - def test_create_admin2(self, admin2): -@@ -1011,21 +1021,11 @@ class TestAdmins(XMLRPC_test): - admin2.disable() - tracker = Tracker() - -- with raises_exact(errors.LastMemberError( -- key=admin1, label=u'group', container=admin_group)): -+ with raises_exact(errors.ProtectedEntryError(label=u'user', -+ key=admin1, reason='privileged user')): - tracker.run_command('user_disable', admin1) -- with raises_exact(errors.LastMemberError( -- key=admin1, label=u'group', container=admin_group)): -- tracker.run_command('user_del', admin1) - admin2.delete() - -- with raises_exact(errors.LastMemberError( -- key=admin1, label=u'group', container=admin_group)): -- tracker.run_command('user_disable', admin1) -- with raises_exact(errors.LastMemberError( -- key=admin1, label=u'group', container=admin_group)): -- tracker.run_command('user_del', admin1) -- - - @pytest.mark.tier1 - class TestPreferredLanguages(XMLRPC_test): --- -2.41.0 - diff --git a/0019-ipa-kdb-fix-error-handling-of-is_master_host.patch b/0019-ipa-kdb-fix-error-handling-of-is_master_host.patch deleted file mode 100644 index 957d97f..0000000 --- a/0019-ipa-kdb-fix-error-handling-of-is_master_host.patch +++ /dev/null @@ -1,87 +0,0 @@ -From fd32e6a3d95f28d2d11d41ee5dabb0d563cb5d51 Mon Sep 17 00:00:00 2001 -From: Julien Rische -Date: Mon, 31 Jul 2023 11:26:43 +0200 -Subject: [PATCH] ipa-kdb: fix error handling of is_master_host() - -Adding proper error handling to the is_master_host() function to allow -it to make the difference between the absence of a master host object -and a connection failure. This will keep the krb5kdc daemon from -continuing to run with a NULL LDAP context. - -Fixes: https://pagure.io/freeipa/issue/9422 - -Signed-off-by: Julien Rische -Reviewed-By: Alexander Bokovoy ---- - daemons/ipa-kdb/ipa_kdb_mspac.c | 41 +++++++++++++++++++-------------- - 1 file changed, 24 insertions(+), 17 deletions(-) - -diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c -index 83b507cb422c735f933edaebfc7b903b8fa908e4..1558e2bead288d9d00014e9b3b059934e80b54e4 100644 ---- a/daemons/ipa-kdb/ipa_kdb_mspac.c -+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c -@@ -401,27 +401,29 @@ static krb5_error_code ipadb_add_asserted_identity(struct ipadb_context *ipactx, - return 0; - } - --static bool is_master_host(struct ipadb_context *ipactx, const char *fqdn) -+static krb5_error_code -+is_master_host(struct ipadb_context *ipactx, const char *fqdn, bool *result) - { -- int ret; -+ int err; - char *master_host_base = NULL; -- LDAPMessage *result = NULL; -- krb5_error_code err; -+ LDAPMessage *ldap_res = NULL; - -- ret = asprintf(&master_host_base, "cn=%s,cn=masters,cn=ipa,cn=etc,%s", -+ err = asprintf(&master_host_base, "cn=%s,cn=masters,cn=ipa,cn=etc,%s", - fqdn, ipactx->base); -- if (ret == -1) { -- return false; -- } -+ if (err == -1) -+ return ENOMEM; -+ - err = ipadb_simple_search(ipactx, master_host_base, LDAP_SCOPE_BASE, -- NULL, NULL, &result); -+ NULL, NULL, &ldap_res); - free(master_host_base); -- ldap_msgfree(result); -- if (err == 0) { -- return true; -- } -+ ldap_msgfree(ldap_res); -+ if (err != KRB5_KDB_NOENTRY && err != 0) -+ return err; -+ -+ if (result) -+ *result = err != KRB5_KDB_NOENTRY; - -- return false; -+ return 0; - } - - static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, -@@ -692,9 +694,14 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, - if ((is_host || is_service)) { - /* it is either host or service, so get the hostname first */ - char *sep = strchr(info3->base.account_name.string, '/'); -- bool is_master = is_master_host( -- ipactx, -- sep ? sep + 1 : info3->base.account_name.string); -+ bool is_master; -+ -+ ret = is_master_host(ipactx, -+ sep ? sep + 1 : info3->base.account_name.string, -+ &is_master); -+ if (ret) -+ return ret; -+ - if (is_master) { - /* Well known RID of domain controllers group */ - if (info3->base.rid == 0) { --- -2.41.0 - diff --git a/0020-ipatests-update-expected-webui-msg-for-admin-deletio.patch b/0020-ipatests-update-expected-webui-msg-for-admin-deletio.patch deleted file mode 100644 index 17ad7c5..0000000 --- a/0020-ipatests-update-expected-webui-msg-for-admin-deletio.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 13d5e88eb4ebb7a0132cbb050a9d230304ecbcff Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Wed, 2 Aug 2023 15:41:57 +0200 -Subject: [PATCH] ipatests: update expected webui msg for admin deletion - -The deletion of the admin is now forbidden (even if it is -not the last member of the admins group) and the error -message has changed from "admin cannot be deleted or -disabled because it is the last member of group admins" -to " user admin cannot be deleted/modified: privileged user". - -Update the expected message in the webui test. - -Related: https://pagure.io/freeipa/issue/8878 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Alexander Bokovoy ---- - ipatests/test_webui/test_user.py | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/ipatests/test_webui/test_user.py b/ipatests/test_webui/test_user.py -index 8d44fbdb9380c94058307b02a96299d0e178cdc7..a8a92d00c7e1f40ef10eb9133cea8752daafe730 100644 ---- a/ipatests/test_webui/test_user.py -+++ b/ipatests/test_webui/test_user.py -@@ -50,8 +50,7 @@ INV_FIRSTNAME = ("invalid 'first': Leading and trailing spaces are " - FIELD_REQ = 'Required field' - ERR_INCLUDE = 'may only include letters, numbers, _, -, . and $' - ERR_MISMATCH = 'Passwords must match' --ERR_ADMIN_DEL = ('admin cannot be deleted or disabled because it is the last ' -- 'member of group admins') -+ERR_ADMIN_DEL = ('user admin cannot be deleted/modified: privileged user') - USR_EXIST = 'user with name "{}" already exists' - ENTRY_EXIST = 'This entry already exists' - ACTIVE_ERR = 'active user with name "{}" already exists' --- -2.41.0 - diff --git a/0021-ipatests-remove-fixture-call-and-wait-to-get-things-.patch b/0021-ipatests-remove-fixture-call-and-wait-to-get-things-.patch deleted file mode 100644 index 1a01ef2..0000000 --- a/0021-ipatests-remove-fixture-call-and-wait-to-get-things-.patch +++ /dev/null @@ -1,70 +0,0 @@ -From ff6cfcacd67a0461a0341e17854732cbe301f1d6 Mon Sep 17 00:00:00 2001 -From: Mohammad Rizwan -Date: Wed, 2 Aug 2023 12:48:40 +0530 -Subject: [PATCH] ipatests: remove fixture call and wait to get things settle - -system date moved in order to expire the certs. Sometime it -is observed that subsequent operation fails with 500 error for CA, -hence restart the services after moving date and wait for sometime -to get things settle. - -Also the tests was calling fixture which is not required for it, hence -removed it as well. - -Fixes: https://pagure.io/freeipa/issue/9348 - -Signed-off-by: Mohammad Rizwan -Reviewed-By: Florence Blanc-Renaud ---- - ipatests/test_integration/test_acme.py | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py -index cca20983e65f99d5ba0bb7bc6dc2b5684a6f37d9..c7389732cd067d49541cd04ea6687a6b95b4669f 100644 ---- a/ipatests/test_integration/test_acme.py -+++ b/ipatests/test_integration/test_acme.py -@@ -606,6 +606,11 @@ def issue_and_expire_acme_cert(): - tasks.kdestroy_all(host) - tasks.move_date(host, 'stop', '+90days+60minutes') - -+ # restart ipa services as date moved and wait to get things settle -+ time.sleep(10) -+ master.run_command(['ipactl', 'restart']) -+ time.sleep(10) -+ - tasks.get_kdcinfo(master) - # Note raiseonerr=False: - # the assert is located after kdcinfo retrieval. -@@ -627,6 +632,11 @@ def issue_and_expire_acme_cert(): - for host in hosts: - tasks.move_date(host, 'start', '-90days-60minutes') - -+ # restart ipa services as date moved and wait to get things settle -+ time.sleep(10) -+ hosts[0].run_command(['ipactl', 'restart']) -+ time.sleep(10) -+ - - class TestACMERenew(IntegrationTest): - -@@ -960,7 +970,7 @@ class TestACMEPrune(IntegrationTest): - ) - assert f'Number of entries returned {no_of_cert - search_size_limit}' - -- def test_prune_config_show(self, issue_and_expire_acme_cert): -+ def test_prune_config_show(self): - """Test to check config-show command shows set param""" - if (tasks.get_pki_version(self.master) - < tasks.parse_version('11.3.0')): -@@ -1001,7 +1011,7 @@ class TestACMEPrune(IntegrationTest): - assert 'Request Search Time Limit: 0' in result.stdout_text - assert 'cron Schedule: 0 0 1 * *' in result.stdout_text - -- def test_prune_disable(self, issue_and_expire_acme_cert): -+ def test_prune_disable(self): - """Test prune command throw error after disabling the pruning""" - if (tasks.get_pki_version(self.master) - < tasks.parse_version('11.3.0')): --- -2.41.0 - diff --git a/0022-ipatests-fix-test_topology.patch b/0022-ipatests-fix-test_topology.patch deleted file mode 100644 index 92729ef..0000000 --- a/0022-ipatests-fix-test_topology.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 1278e614dd93bf0ac3d6e0c36cb9c277808afb2c Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Fri, 11 Aug 2023 08:01:18 +0200 -Subject: [PATCH] ipatests: fix test_topology - -The test TestTopologyOptions::test_add_remove_segment is -randomly failing downstream. Test scenario: -- create a line topology master <-> repl1 <-> repl2 -- create user on master -- wait for repl success on master -- check that the user is seen on repl2 - -The test waits for replication to complete on the master but -it should also wait for the replication to complete on repl1 -before checking the user presence on repl2. - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Anuja More ---- - ipatests/test_integration/test_topology.py | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/ipatests/test_integration/test_topology.py b/ipatests/test_integration/test_topology.py -index 8a240fa3c081a05b8f4501fe48694e01086003a1..618c9d5dcce994cd0359a291b044eb2cf0bddc74 100644 ---- a/ipatests/test_integration/test_topology.py -+++ b/ipatests/test_integration/test_topology.py -@@ -124,6 +124,9 @@ class TestTopologyOptions(IntegrationTest): - self.replicas[0], - self.replicas[1]) - assert err == "", err -+ # At this point we have replicas[1] <-> master <-> replicas[0] -+ # ^--------------------------^ -+ - # Make sure the new segment is shown by `ipa topologysegment-find` - result1 = self.master.run_command(['ipa', 'topologysegment-find', - DOMAIN_SUFFIX_NAME]).stdout_text -@@ -137,9 +140,12 @@ class TestTopologyOptions(IntegrationTest): - deleteme = find_segment(self.master, self.replicas[1]) - returncode, error = tasks.destroy_segment(self.master, deleteme) - assert returncode == 0, error -+ # At this point we have master <-> replicas[0] <-> replicas[1] -+ - # Wait till replication ends and make sure replica1 does not have - # segment that was deleted on master - master_ldap = self.master.ldap_connect() -+ repl_ldap = self.replicas[0].ldap_connect() - tasks.wait_for_replication(master_ldap) - result3 = self.replicas[0].run_command(['ipa', 'topologysegment-find', - DOMAIN_SUFFIX_NAME]).stdout_text -@@ -150,6 +156,7 @@ class TestTopologyOptions(IntegrationTest): - '--first', 'test', - '--last', 'user']) - tasks.wait_for_replication(master_ldap) -+ tasks.wait_for_replication(repl_ldap) - result4 = self.replicas[1].run_command(['ipa', 'user-find']) - assert('someuser' in result4.stdout_text), 'User not found: someuser' - # We end up having a line topology: master <-> replica1 <-> replica2 --- -2.41.0 - diff --git a/0023-ipatests-idm-api-related-tests.patch b/0023-ipatests-idm-api-related-tests.patch deleted file mode 100644 index 34c072a..0000000 --- a/0023-ipatests-idm-api-related-tests.patch +++ /dev/null @@ -1,560 +0,0 @@ -From ac6a2172f5dcb46701148c7b096ffa1b44076816 Mon Sep 17 00:00:00 2001 -From: Sudhir Menon -Date: Thu, 27 Jul 2023 14:33:08 +0530 -Subject: [PATCH] ipatests: idm api related tests. - -IDM API related tests are automated in the -above PR -Ref: https://freeipa.readthedocs.io/en/latest/api/basic_usage.html - -Signed-off-by: Sudhir Menon -Reviewed-By: Alexander Bokovoy -Reviewed-By: Florence Blanc-Renaud ---- - ipatests/test_integration/test_idm_api.py | 534 ++++++++++++++++++++++ - 1 file changed, 534 insertions(+) - create mode 100644 ipatests/test_integration/test_idm_api.py - -diff --git a/ipatests/test_integration/test_idm_api.py b/ipatests/test_integration/test_idm_api.py -new file mode 100644 -index 0000000000000000000000000000000000000000..eafef5dd8526bc14725d6bc32819cb5c7387f868 ---- /dev/null -+++ b/ipatests/test_integration/test_idm_api.py -@@ -0,0 +1,534 @@ -+# -+# Copyright (C) 2018 FreeIPA Contributors see COPYING for license -+# -+from __future__ import absolute_import -+ -+from ipatests.test_integration.base import IntegrationTest -+import textwrap -+ -+API_INIT = """ -+ from ipalib import api, errors -+ api.bootstrap_with_global_options(context="server") -+ api.finalize() -+ api.Backend.ldap2.connect() -+ """ -+ -+CERT = ( -+ b"MIIEkDCCAvigAwIBAgIBCzANBgkqhkiG9w0BAQsFADA5MRcwFQYDVQQKD\n" -+ b"A5URVNUUkVBTE0uVEVTVDEeMBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG\n" -+ b"9yaXR5MB4XDTIzMDcyODE3MTIxOVoXDTI1MDcyODE3MTIxOVowKjEXMBU\n" -+ b"GA1UECgwOVEVTVFJFQUxNLlRFU1QxDzANBgNVBAMMBmpzbWl0aDCCASIw\n" -+ b"DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOF0XFrdVXmKp95AVZW5o\n" -+ b"BWcij6vJPqeU3UpzTLbM+fROhNaKMX9S+yXrJHifOmhCOuNA8TtptKVJx\n" -+ b"CIDZ1/5KwPBk4vrnwOBtVMCftHj87MabBqV/nmQQrCiKTcJu4aQEDI9Qh\n" -+ b"yza09EJKvG8KkpnyuShtkP2LgkUxIqkjBg4DLV7grO+I+aG17QTuQxUTy\n" -+ b"icfYDBnzD4hTKPLf7d9KNyG+sEeyN0gceLFMUYaQ4lyapcSzYJwOSAc2B\n" -+ b"EU73tLaJlQORHL7HmhxrjD1IgZyxFjp/ofLVZFFoJAqjz2FWzOxmQw+bc\n" -+ b"0WTzQjeSTGx+l3htj7MmhIRBMqr3Um6zXkLKMCAwEAAaOCATAwggEsMB8\n" -+ b"GA1UdIwQYMBaAFCIXu6QtsiBVo1yZQZ7MMHTl5Wj6MEAGCCsGAQUFBwEB\n" -+ b"BDQwMjAwBggrBgEFBQcwAYYkaHR0cDovL2lwYS1jYS50ZXN0cmVhbG0ud\n" -+ b"GVzdC9jYS9vY3NwMA4GA1UdDwEB/wQEAwIE8DAdBgNVHSUEFjAUBggrBg\n" -+ b"EFBQcDAQYIKwYBBQUHAwIweQYDVR0fBHIwcDBuoDagNIYyaHR0cDovL2l\n" -+ b"wYS1jYS50ZXN0cmVhbG0udGVzdC9pcGEvY3JsL01hc3RlckNSTC5iaW6i\n" -+ b"NKQyMDAxDjAMBgNVBAoMBWlwYWNhMR4wHAYDVQQDDBVDZXJ0aWZpY2F0Z\n" -+ b"SBBdXRob3JpdHkwHQYDVR0OBBYEFNwQNQAG8MsKQPwMFyGzRiMzRAa5MA\n" -+ b"0GCSqGSIb3DQEBCwUAA4IBgQB2g0mS8XAPI+aRBa5q7Vbp1245CvMP0Eq\n" -+ b"Cz6gvCNwtxW0UDKnB++d/YQ13ft+x9Xj3rB/M2YXxdxTpQnQQv34CUcyh\n" -+ b"PQKJthAsbKBpdusCGrbS54zKFR0MjxwOwIIDHuI6eu2AoSpsmYs5UGzQm\n" -+ b"oCfQhbImK7iGLy0rOHaON1cWAFmC6lzJ2TFELc4N3eLYGVZy2ZtyZTgA3\n" -+ b"l97rBCwbDDFF1JWoOByIq8Ij99ksyMXws++sNUpo/1l8Jt0Gn6RBiidZB\n" -+ b"ef4+kJN+t6RAAwRQ / 3cmEggXcFoV13KZ70PeMXeX6CKMwXIwt3q7A78\n" -+ b"Wc/0OIBREZLhXpkmogCzWCuatdzeBIhMhx0vDEzaxlhf32ZWfN5pFMpgq\n" -+ b"wLZsdwMf6J65kGbE5Pg3Yxk7OiByxZJnR8UlvbU3r6RhMWutD6C0aqqNt\n" -+ b"o3us5gTmfRc8Mf1l/BUgDqkBKOTU8FHREGemG1HoklBym/Pbua0VMUA+s\n" -+ b"0nECR4LLM/o9PCJ2Y3QPBZy8Hg=\n" -+) -+ -+ -+class TestAPIScenario(IntegrationTest): -+ """ -+ Tests for IDM API scenarios -+ """ -+ -+ topology = "line" -+ -+ def create_and_run_script(self, filename, user_code_script): -+ self.master.put_file_contents(filename, user_code_script) -+ self.master.run_command(["python3", filename]) -+ self.master.run_command(["rm", filename]) -+ -+ def test_idm_user_add(self): -+ """ -+ This test checks that ipa user using api.Command["user_add"] -+ and then checks that user is displayed using -+ api.Command["user_show"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ api.Command["user_add"]("jsmith", givenname="John", sn="Smith", -+ ipauserauthtype="otp") -+ cmd = api.Command["user_show"]("jsmith", all=True)["result"] -+ assert 'otp' in cmd['ipauserauthtype'] -+ assert 'John Smith' in cmd['cn'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/user_add.py", user_code_script -+ ) -+ -+ def test_idm_user_find(self): -+ """ -+ This test checks that user is displayed -+ using api.Command["user_find"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["user_find"]("jsmith") -+ assert '1 user matched' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/user_find.py", user_code_script -+ ) -+ -+ def test_idm_user_mod(self): -+ """ -+ This test checks that user attribute is modified -+ using api.Command["user_mod"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["user_mod"]("jsmith", -+ mail="jsmith@example.org")["result"] -+ assert 'jsmith@example.org' in cmd['mail'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/user_mod.py", user_code_script -+ ) -+ -+ def test_disable_user(self): -+ """ -+ This test checks that user is disabled -+ using api.Command["user_disable"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["user_disable"]("jsmith") -+ assert 'Disabled user account "jsmith"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/disable_user.py", user_code_script -+ ) -+ -+ def test_enable_user(self): -+ """ -+ This test checks that user is enabled -+ using api.Command["user_enable"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["user_enable"]("jsmith") -+ assert 'Enabled user account "jsmith"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/enable_user.py", user_code_script -+ ) -+ -+ def test_create_ipa_group(self): -+ """ -+ This test checks that group is created -+ using api.Command["group_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["group_add"]("developers", gidnumber=500, -+ description="Developers") -+ assert 'Added group "developers"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/create_group.py", user_code_script -+ ) -+ -+ def test_show_ipa_group(self): -+ """ -+ This test checks that group is displayed -+ using api.Command["group_show"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["group_show"]("developers") -+ assert 'developers' in cmd['result']['cn'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/group_show.py", user_code_script -+ ) -+ -+ def test_ipa_group_mod(self): -+ """ -+ This test checks that group description is modified -+ using api.Command["group_mod"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["group_mod"]("developers", description='developer') -+ ["result"] -+ assert 'Modified group "developers"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/group_mod.py", user_code_script -+ ) -+ -+ def test_add_members_to_ipa_group(self): -+ """ -+ This test checks that member is added to group -+ using api.Command["group_add_member"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["group_add_member"]("developers", -+ user='jsmith')["result"] -+ assert 'jsmith' in cmd['member_user'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/create_group_members.py", user_code_script -+ ) -+ -+ def test_ipa_group_find(self): -+ """ -+ This test checks that group is displayed -+ using api.Command["group_find"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["group_find"]("developers") -+ assert '1 group matched' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/group_find.py", user_code_script -+ ) -+ -+ def test_remove_member_group(self): -+ """ -+ This test checks that group member is removed -+ using api.Command["group_remove_member"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["group_remove_member"]("developers", -+ user="jsmith") -+ assert 'member_user' not in cmd -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/remove_member_group.py", user_code_script -+ ) -+ -+ def test_add_permission(self): -+ """ -+ This test checks that permission is added -+ using api.Command["permission_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["permission_add"]("Create users", -+ ipapermright='add', type='user') -+ assert 'Added permission "Create users"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/add_perm.py", user_code_script -+ ) -+ -+ def test_create_hbac_rule(self): -+ """ -+ This test checks that hbac rule is added -+ using api.Command["hbacrule_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["hbacrule_add"]("sshd_rule") -+ assert 'Added HBAC rule "sshd_rule"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/add_hbac_rule.py", user_code_script -+ ) -+ -+ def test_add_hbac_service(self): -+ """ -+ This test checks that hbac service is added using -+ api.Command["hbacsvc_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["hbacsvc_add"]("chronyd") -+ assert 'Added HBAC service "chronyd"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/add_hbac_svc.py", user_code_script -+ ) -+ -+ def test_enable_hbac_rule(self): -+ """ -+ This test checks that hbac rule is enabled using -+ api.Command["hbacrule_enable"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["hbacrule_enable"]("sshd_rule") -+ assert 'Enabled HBAC rule "sshd_rule"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/enable_hbacrule.py", user_code_script -+ ) -+ -+ def test_create_sudo_rule(self): -+ """ -+ This test checks that sudo rule is created using -+ api.Command["sudorule_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["sudorule_add"]("timechange") -+ assert 'Added Sudo Rule "timechange"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/create_sudos.py", user_code_script -+ ) -+ -+ def test_add_user_certificate(self): -+ """ -+ This test checks user certificate is added using -+ api.Command["user_add_cert"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ msg = 'Added certificates to user "jsmith"' -+ cmd = api.Command["user_add_cert"]("jsmith", usercertificate={CERT}) -+ assert msg in cmd["summary"] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/add_cert.py", user_code_script -+ ) -+ -+ def test_remove_user_certificate(self): -+ """ -+ This test checks that user certificate is removed -+ using api.Command["user_remove_cert"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ msg = 'Removed certificates from user "jsmith"' -+ cmd = api.Command["user_remove_cert"]("jsmith", usercertificate={CERT}) -+ assert msg in cmd["summary"] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/remove_cert.py", user_code_script -+ ) -+ -+ def test_certmaprule_add(self): -+ """ -+ This test checks that certmap rule is added using -+ api.Command["certmaprule_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ msg = ('Added Certificate Identity Mapping Rule "testrule"') -+ cmd = api.Command["certmaprule_add"]("testrule") -+ assert msg in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/certmap_rule_add.py", user_code_script -+ ) -+ -+ def test_certmaprule_enable(self): -+ """ -+ This test checks that certmap rule is enabled -+ using api.Command["certmaprule_enable"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ msg = ('Enabled Certificate Identity Mapping Rule "testrule"') -+ cmd = api.Command["certmaprule_enable"]("testrule") -+ assert msg in cmd["summary"] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/certmap_rule_enable.py", user_code_script -+ ) -+ -+ def test_certmaprule_disable(self): -+ """ -+ This test checks that certmap rule is disabled using -+ api.Command["certmaprule_disable"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ msg = ('Disabled Certificate Identity Mapping Rule "testrule"') -+ cmd = api.Command["certmaprule_disable"]("testrule") -+ assert msg in cmd["summary"] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/certmap_rule_disable.py", user_code_script -+ ) -+ -+ def test_certmaprule_del(self): -+ """ -+ This test checks that certmap rule is deleted using -+ api.Command["certmaprule_del"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ msg = ('Deleted Certificate Identity Mapping Rule "testrule"') -+ cmd = api.Command["certmaprule_del"]("testrule") -+ assert msg in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/certmap_rule_del.py", user_code_script -+ ) -+ -+ def test_add_role(self): -+ """ -+ This test checks that role and privilege is added using -+ api.Command["role_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd1 = api.Command["role_add"]("junioradmin", -+ description="Junior admin") -+ assert 'Added role "junioradmin"' in cmd1["summary"] -+ cmd2 = api.Command.role_add_privilege("junioradmin", -+ privilege="Vault Administrators")["result"] -+ assert 'Vault Administrators' in cmd2["memberof_privilege"] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/add_role.py", user_code_script -+ ) -+ -+ def test_add_subid(self): -+ """ -+ This test checks that subid is added for IPA user -+ using api.Command["subid_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["subid_add"](ipaowner="jsmith") -+ assert 'Added subordinate id ' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/add_subid.py", user_code_script -+ ) -+ -+ def test_add_otptoken(self): -+ """ -+ This test checks that otp token is added for IPA user -+ using api.Command["otptoken_add"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["otptoken_add"]( -+ type='HOTP', description='testotp', -+ ipatokenotpalgorithm='sha512', ipatokenowner='jsmith', -+ ipatokenotpdigits='6') -+ assert 'Added OTP token' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/add_otptoken.py", user_code_script -+ ) -+ -+ def test_user_del(self): -+ """ -+ This test checks that user is deleted -+ using api.Command["user_del"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["user_del"]("jsmith") -+ assert 'Deleted user "jsmith"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/user_del.py", user_code_script -+ ) -+ -+ def test_remove_ipa_group(self): -+ """ -+ This test checks that group is removed -+ using api.Command["group_del"] -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ cmd = api.Command["group_del"]("developers") -+ assert 'Deleted group "developers"' in cmd['summary'] -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/show_group.py", user_code_script -+ ) -+ -+ def test_batch_command(self): -+ """ -+ This test checks that batch commands -+ can be run using api. -+ """ -+ user_code_script = textwrap.dedent( -+ f""" -+ {API_INIT} -+ batch_args = [] -+ for i in range(5): -+ user_id = "user%i" % i -+ args = [user_id] -+ kw = {{'givenname' : user_id, 'sn' : user_id}} -+ batch_args.append({{'method' : 'user_add', 'params' : [args, kw]}}) -+ api.Command["batch"](*batch_args) -+ """ -+ ) -+ self.create_and_run_script( -+ "/tmp/batch.py", user_code_script -+ ) --- -2.41.0 - diff --git a/0024-ipatests-fixture-can-produce-IndexError.patch b/0024-ipatests-fixture-can-produce-IndexError.patch deleted file mode 100644 index 83ce90c..0000000 --- a/0024-ipatests-fixture-can-produce-IndexError.patch +++ /dev/null @@ -1,45 +0,0 @@ -From f816b4d9e6ff7a47b0da1a368d2454add78af07c Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Fri, 11 Aug 2023 09:10:30 +0200 -Subject: [PATCH] ipatests: fixture can produce IndexError - -The fixture issue_and_expire_acme_cert returns a function -that fills the hosts array. If the function is not called in -the test (for instance because a test is skipped, as in -TestACMEPrune::test_prune_cert_search_size_limit), hosts = [] -and hosts[0] raises an IndexError. - -Fix the fixture to check first that hosts is not empty. - -Related: https://pagure.io/freeipa/issue/9348 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Mohammad Rizwan Yusuf ---- - ipatests/test_integration/test_acme.py | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py -index c7389732cd067d49541cd04ea6687a6b95b4669f..bc989a9a2a00b0ac68b9dcffd4ccea269314961b 100644 ---- a/ipatests/test_integration/test_acme.py -+++ b/ipatests/test_integration/test_acme.py -@@ -633,9 +633,13 @@ def issue_and_expire_acme_cert(): - tasks.move_date(host, 'start', '-90days-60minutes') - - # restart ipa services as date moved and wait to get things settle -- time.sleep(10) -- hosts[0].run_command(['ipactl', 'restart']) -- time.sleep(10) -+ # if the internal fixture was not called (for instance because the test -+ # was skipped), hosts = [] and hosts[0] would produce an IndexError -+ # exception. -+ if hosts: -+ time.sleep(10) -+ hosts[0].run_command(['ipactl', 'restart']) -+ time.sleep(10) - - - class TestACMERenew(IntegrationTest): --- -2.41.0 - diff --git a/0025-Installer-activate-nss-and-pam-services-in-sssd.conf.patch b/0025-Installer-activate-nss-and-pam-services-in-sssd.conf.patch deleted file mode 100644 index a6a0eb3..0000000 --- a/0025-Installer-activate-nss-and-pam-services-in-sssd.conf.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 4a62a21499a4884f0db55d01966a6ff532a4ed1e Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Mon, 14 Aug 2023 10:53:05 +0200 -Subject: [PATCH] Installer: activate nss and pam services in sssd.conf - -If there is already a sssd.conf file before the installer is -executed, the nss and pam services may not be enabled by the -installer. This happens for instance if the machine is hardened -for STIG and sssd.conf does not define services=... in the -[sssd] section. - -The consequence is that trust cannot be established with an AD -domain. - -The installer must enable nss and pam services even if there is -a pre-existing sssd.conf file. - -Fixes: https://pagure.io/freeipa/issue/9427 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Alexander Bokovoy ---- - ipaclient/install/client.py | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py -index ef29a2c8a3f673860cb22e0e6953853fd96a8572..07d62a748f77e990a38e28e3675abb05eef0da8d 100644 ---- a/ipaclient/install/client.py -+++ b/ipaclient/install/client.py -@@ -969,6 +969,9 @@ def configure_sssd_conf( - nss_service.set_option('memcache_timeout', 600) - sssdconfig.save_service(nss_service) - -+ sssd_enable_service(sssdconfig, 'nss') -+ sssd_enable_service(sssdconfig, 'pam') -+ - domain.set_option('ipa_domain', cli_domain) - domain.set_option('ipa_hostname', client_hostname) - if cli_domain.lower() != cli_realm.lower(): --- -2.41.0 - diff --git a/freeipa.spec b/freeipa.spec index 1c0672b..bf420bb 100644 --- a/freeipa.spec +++ b/freeipa.spec @@ -87,8 +87,8 @@ %global httpd_version 2.4.37-21 %global bind_version 9.11.20-6 -# Fix for https://github.com/SSSD/sssd/issues/6331 -%global sssd_version 2.8.0 +# support for passkey +%global sssd_version 2.9.0 %else # Fedora @@ -148,8 +148,8 @@ # F35+, adds IdP integration %global sssd_version 2.7.0 %else -# Fix for https://github.com/SSSD/sssd/issues/6331 -%global sssd_version 2.8.0 +# Support for passkey +%global sssd_version 2.9.0 %endif # Fedora @@ -210,7 +210,7 @@ # Work-around fact that RPM SPEC parser does not accept # "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement -%define IPA_VERSION 4.10.2 +%define IPA_VERSION 4.11.0 # Release candidate version -- uncomment with one percent for RC versions #%%global rc_version %%nil %define AT_SIGN @ @@ -223,7 +223,7 @@ Name: %{package_name} Version: %{IPA_VERSION} -Release: 4%{?rc_version:.%rc_version}%{?dist} +Release: 1%{?rc_version:.%rc_version}%{?dist} Summary: The Identity, Policy and Audit system License: GPL-3.0-or-later @@ -247,31 +247,6 @@ Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch %endif %if 0%{?rhel} == 9 -Patch0001: 0001-webuitests-close-notification-which-hides-Add-button.patch -Patch0002: 0002-ipatests-Check-that-SSSD_PUBCONF_KRB5_INCLUDE_D_DIR-.patch -Patch0003: 0003-Revert-Use-the-OpenSSL-certificate-parser-in-cert-fi.patch -Patch0004: 0004-Revert-cert_find-fix-call-with-all.patch -Patch0005: 0005-Use-the-python-cryptography-parser-directly-in-cert-.patch -Patch0006: 0006-Upgrade-add-PKI-drop-in-file-if-missing.patch -Patch0007: 0007-Integration-test-add-a-test-for-upgrade-and-PKI-drop.patch -Patch0008: 0008-Uninstaller-uninstall-PKI-before-shutting-down-servi.patch -Patch0009: 0009-Detection-of-PKI-subsystem.patch -Patch0010: 0010-Upgrade-fix-replica-agreement.patch -Patch0011: 0011-Integration-tests-add-a-test-to-ipa-server-upgrade.patch -Patch0012: 0012-tests-fix-backup-restore-scenario-with-replica.patch -Patch0013: 0013-OTP-fix-data-type-to-avoid-endianness-issue.patch -Patch0014: 0014-ipatests-enable-firewall-rule-for-http-service-on-ac.patch -Patch0015: 0015-User-plugin-improve-error-related-to-non-existing-id.patch -Patch0016: 0016-xmlrpc-tests-add-a-test-for-user-plugin-with-non-exi.patch -Patch0017: 0017-Fix-memory-leak-in-the-OTP-last-token-plugin.patch -Patch0018: 0018-Prevent-the-admin-user-from-being-deleted.patch -Patch0019: 0019-ipa-kdb-fix-error-handling-of-is_master_host.patch -Patch0020: 0020-ipatests-update-expected-webui-msg-for-admin-deletio.patch -Patch0021: 0021-ipatests-remove-fixture-call-and-wait-to-get-things-.patch -Patch0022: 0022-ipatests-fix-test_topology.patch -Patch0023: 0023-ipatests-idm-api-related-tests.patch -Patch0024: 0024-ipatests-fixture-can-produce-IndexError.patch -Patch0025: 0025-Installer-activate-nss-and-pam-services-in-sssd.conf.patch Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch %endif %endif @@ -581,12 +556,8 @@ Requires: python3-pyasn1 >= 0.3.2-2 Requires: python3-sssdconfig >= %{sssd_version} Requires: python3-psutil Requires: rpm-libs -# Indirect dependency: use newer urllib3 with TLS 1.3 PHA support -%if 0%{?rhel} -Requires: python3-urllib3 >= 1.24.2-3 -%else -Requires: python3-urllib3 >= 1.25.7 -%endif +# For urllib3.util.ssl_match_hostname +Requires: python3-urllib3 >= 1.25.8 %description -n python3-ipaserver IPA is an integrated solution to provide centrally managed Identity (users, @@ -739,6 +710,9 @@ Recommends: libsss_sudo Recommends: sudo Requires: (libsss_sudo if sudo) +# Passkey support +Recommends: sssd-passkey + Provides: %{alt_name}-client = %{version} Conflicts: %{alt_name}-client Obsoletes: %{alt_name}-client < %{version} @@ -909,6 +883,8 @@ Requires: platform-python-setuptools %else Requires: python3-setuptools %endif +# For urllib3.util.ssl_match_hostname +Requires: python3-urllib3 >= 1.25.8 %description -n python3-ipalib IPA is an integrated solution to provide centrally managed Identity (users, @@ -1763,6 +1739,9 @@ fi %endif %changelog +* Fri Oct 06 2023 Florence Blanc-Renaud - 4.11.0-1 +- Resolves: RHEL-11652 Rebase ipa to latest 4.11.x version for RHEL 9.4 + * Thu Aug 17 2023 Florence Blanc-Renaud - 4.10.2-4 - Resolves: rhbz#2231847 RHEL 8.8 & 9.2 fails to create AD trust with STIG applied - Resolves: rhbz#2232056 Include latest test fixes in python3-ipatests diff --git a/sources b/sources index ec1fc5a..b86cbff 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (freeipa-4.10.2.tar.gz) = be5c1552ead25f9fd6f885687110e2017abdb16ca3047a4458129fe5f8437d3bbd97723b49650dafd770333b30a6cdbc7b0c26fdf0c522ec2b62d0df642ce768 -SHA512 (freeipa-4.10.2.tar.gz.asc) = 732a73326548103aa9133a8ca6c3e56101fb858a2746d4aa2799571bab20111b9be36f5991f1f433fed2e435698a583b9be3cfc14d0abb9808355c3c5ab19fc7 +SHA512 (freeipa-4.11.0.tar.gz) = 2af27248bfa1cb39f52eb38d0ffcf76d8eed5397aca89932f6a6cef622fb93875c1b17b79742c6b67a086a84b02dacbc8ea05b3bc481cd296fe983f4ae13a80f +SHA512 (freeipa-4.11.0.tar.gz.asc) = 6464605296e00281cf0e22ff7e479f4100762a2aa2e2ae78a1c9e8f83ff5a7cdf13da610f5a1da4711552aa3268de04cb442bde37ecb5f716937a5f902b66825