diff --git a/0047-ipatests-skip-test_ipahealthcheck_ds_configcheck-for.patch b/0047-ipatests-skip-test_ipahealthcheck_ds_configcheck-for.patch new file mode 100644 index 0000000..8a0c5aa --- /dev/null +++ b/0047-ipatests-skip-test_ipahealthcheck_ds_configcheck-for.patch @@ -0,0 +1,51 @@ +From 45f96a0f978dfda0e2faa8360182a1dfd3122b94 Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Fri, 10 Jan 2025 13:22:29 +0100 +Subject: [PATCH] ipatests: skip test_ipahealthcheck_ds_configcheck for recent + versions + +389-ds removed the parameter nsslapd-logging-hr-timestamps-enabled +in 2.5.3 and above. Skip the test that exercises the corresponding +healthcheck. + +Fixes: https://pagure.io/freeipa/issue/9730 +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: Rob Crittenden +Reviewed-By: Rob Crittenden +--- + ipatests/test_integration/test_ipahealthcheck.py | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py +index cc51a5a6a62fbc50927fc2fc51f129a069e70b69..6b6f15aa433a423fe599118d2226e4c4ec62b13b 100644 +--- a/ipatests/test_integration/test_ipahealthcheck.py ++++ b/ipatests/test_integration/test_ipahealthcheck.py +@@ -18,7 +18,7 @@ import uuid + + import pytest + +-from ipalib import x509 ++from ipalib import errors, x509 + from ipapython.dn import DN + from ipapython.ipaldap import realm_to_serverid + from ipapython.certdb import NSS_SQL_FILES +@@ -1146,8 +1146,14 @@ class TestIpaHealthCheck(IntegrationTest): + ) + entry = ldap.get_entry(dn) + entry.single_value["nsslapd-logging-hr-timestamps-enabled"] = 'off' +- ldap.update_entry(entry) +- ++ try: ++ ldap.update_entry(entry) ++ except errors.DatabaseError as e: ++ expected_msg = "Unknown attribute " \ ++ "nsslapd-logging-hr-timestamps-enabled" ++ if expected_msg in e.message: ++ pytest.skip( ++ "389-ds removed nsslapd-logging-hr-timestamps-enabled") + yield + + entry = ldap.get_entry(dn) +-- +2.47.1 + diff --git a/0048-ipatests-restart-dirsrv-after-time-jumps.patch b/0048-ipatests-restart-dirsrv-after-time-jumps.patch new file mode 100644 index 0000000..d5c410b --- /dev/null +++ b/0048-ipatests-restart-dirsrv-after-time-jumps.patch @@ -0,0 +1,35 @@ +From ec94ee72714296c86ba1227a5a945a7ed0bc7fac Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Thu, 16 Jan 2025 15:43:17 +0100 +Subject: [PATCH] ipatests: restart dirsrv after time jumps + +The test for ipa-healthcheck is moving the date in the future. +Restart the dirsrv instance because the LDAP server is +sensitive to large time jumps. + +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: Rob Crittenden +Reviewed-By: Rob Crittenden +--- + ipatests/test_integration/test_ipahealthcheck.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py +index 6b6f15aa433a423fe599118d2226e4c4ec62b13b..7c3f5857a477070d8a9b52c04d41f35ac580c97f 100644 +--- a/ipatests/test_integration/test_ipahealthcheck.py ++++ b/ipatests/test_integration/test_ipahealthcheck.py +@@ -1634,6 +1634,11 @@ class TestIpaHealthCheck(IntegrationTest): + grace_date = datetime.strftime(grace_date, "%Y-%m-%d 00:00:01 Z") + self.master.run_command(['date', '-s', grace_date]) + ++ # Restart dirsrv as it doesn't like time jumps ++ instance = realm_to_serverid(self.master.domain.realm) ++ cmd = ["systemctl", "restart", "dirsrv@{}".format(instance)] ++ self.master.run_command(cmd) ++ + for check in ("IPACertmongerExpirationCheck", + "IPACertfileExpirationCheck",): + execute_expiring_check(check) +-- +2.47.1 + diff --git a/0049-ipa-otpd-do-not-pass-OIDC-client-secret-if-there-is-.patch b/0049-ipa-otpd-do-not-pass-OIDC-client-secret-if-there-is-.patch new file mode 100644 index 0000000..5ebb167 --- /dev/null +++ b/0049-ipa-otpd-do-not-pass-OIDC-client-secret-if-there-is-.patch @@ -0,0 +1,67 @@ +From f12c4ed600e9b35c930d386b37e36064fbf83968 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Fri, 17 Jan 2025 09:44:22 +0200 +Subject: [PATCH] ipa-otpd: do not pass OIDC client secret if there is none to + pass + +If there is no client secret specified for the OIDC client, don't push +it to oidc_child via stdin. oidc_child does only expect client secret if +--client-secret-stdin option was specified and we already specify it +only if client secret is not empty. + +In addition, if client secret is empty (it is a public OIDC client), +then strlen(NULL) would crash in glibc internals. Avoid that! + +Fixes: https://pagure.io/freeipa/issue/9734 + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Rob Crittenden +--- + daemons/ipa-otpd/oauth2.c | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/daemons/ipa-otpd/oauth2.c b/daemons/ipa-otpd/oauth2.c +index 52d7d7c9cb6c410bdbaa2e5eddccfea2204d3e69..0eb43b2372701d47b9ef62cbbdb32b97a5f7a0ba 100644 +--- a/daemons/ipa-otpd/oauth2.c ++++ b/daemons/ipa-otpd/oauth2.c +@@ -104,17 +104,26 @@ static void oauth2_on_child_writable(verto_ctx *vctx, verto_ev *ev) + } + + if (child_ctx->oauth2_state == OAUTH2_GET_DEVICE_CODE) { +- io = write(verto_get_fd(ev), child_ctx->item->idp.ipaidpClientSecret, +- strlen(child_ctx->item->idp.ipaidpClientSecret)); ++ if (child_ctx->item->idp.ipaidpClientSecret != NULL) { ++ io = write(verto_get_fd(ev), child_ctx->item->idp.ipaidpClientSecret, ++ strlen(child_ctx->item->idp.ipaidpClientSecret)); ++ } else { ++ io = 0; ++ } + } else { +- iov[0].iov_base = child_ctx->item->idp.ipaidpClientSecret; +- iov[0].iov_len = strlen(child_ctx->item->idp.ipaidpClientSecret); +- iov[1].iov_base = "\n"; +- iov[1].iov_len = 1; +- iov[2].iov_base = child_ctx->saved_item->oauth2.device_code_reply; +- iov[2].iov_len = strlen(child_ctx->saved_item->oauth2.device_code_reply); +- +- io = writev(verto_get_fd(ev), iov, 3); ++ int idx = 0; ++ if (child_ctx->item->idp.ipaidpClientSecret != NULL) { ++ iov[idx].iov_base = child_ctx->item->idp.ipaidpClientSecret; ++ iov[idx].iov_len = strlen(child_ctx->item->idp.ipaidpClientSecret); ++ idx++; ++ iov[idx].iov_base = "\n"; ++ iov[idx].iov_len = 1; ++ idx++; ++ } ++ iov[idx].iov_base = child_ctx->saved_item->oauth2.device_code_reply; ++ iov[idx].iov_len = strlen(child_ctx->saved_item->oauth2.device_code_reply); ++ idx++; ++ io = writev(verto_get_fd(ev), iov, idx); + } + otpd_queue_item_free(child_ctx->saved_item); + +-- +2.47.1 + diff --git a/0050-Migrate-Keycloak-tests-to-JDK-21-and-Keycloak-26.patch b/0050-Migrate-Keycloak-tests-to-JDK-21-and-Keycloak-26.patch new file mode 100644 index 0000000..0dc4f20 --- /dev/null +++ b/0050-Migrate-Keycloak-tests-to-JDK-21-and-Keycloak-26.patch @@ -0,0 +1,165 @@ +From 4e43dd7cd30042588a2264fca98b6e6b9d4d25bb Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Fri, 17 Jan 2025 12:33:54 +0200 +Subject: [PATCH] Migrate Keycloak tests to JDK 21 and Keycloak 26 + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Rob Crittenden +--- + .../pytest_ipa/integration/create_bridge.py | 2 +- + .../pytest_ipa/integration/create_keycloak.py | 28 +++++++++---------- + ipatests/test_integration/test_idp.py | 4 +-- + ipatests/test_integration/test_sso.py | 4 +-- + 4 files changed, 18 insertions(+), 20 deletions(-) + +diff --git a/ipatests/pytest_ipa/integration/create_bridge.py b/ipatests/pytest_ipa/integration/create_bridge.py +index 618c645feef86f846a60e5727e7777defc67624c..5dd2f305c2ba6f707ee40be12581ff62c951805b 100644 +--- a/ipatests/pytest_ipa/integration/create_bridge.py ++++ b/ipatests/pytest_ipa/integration/create_bridge.py +@@ -147,7 +147,7 @@ def setup_keycloak_scim_plugin(host, bridge_server): + # Login to keycloak as admin + kcadmin_sh = "/opt/keycloak/bin/kcadm.sh" + kcadmin = [kcadmin_sh, "config", "credentials", "--server", +- f"https://{host.hostname}:8443/auth/", ++ f"https://{host.hostname}:8443", + "--realm", "master", "--user", "admin", + "--password", password] + tasks.run_repeatedly(host, kcadmin, timeout=60) +diff --git a/ipatests/pytest_ipa/integration/create_keycloak.py b/ipatests/pytest_ipa/integration/create_keycloak.py +index 1340b95715c25f1bf1cbbf2e3c6e60731f3af08e..addade7594d7a1b8edefdb8c67ec4bc7abe70ef4 100644 +--- a/ipatests/pytest_ipa/integration/create_keycloak.py ++++ b/ipatests/pytest_ipa/integration/create_keycloak.py +@@ -6,10 +6,10 @@ from ipaplatform.paths import paths + from ipatests.pytest_ipa.integration import tasks + + +-def setup_keycloakserver(host, version='17.0.0'): ++def setup_keycloakserver(host, version='26.1.0'): + dir = "/opt/keycloak" + password = host.config.admin_password +- tasks.install_packages(host, ["unzip", "java-11-openjdk-headless", ++ tasks.install_packages(host, ["unzip", "java-21-openjdk-headless", + "openssl", "maven", "wget", + "firefox", "xorg-x11-server-Xvfb"]) + # add keycloak system user/group and folder +@@ -33,7 +33,7 @@ def setup_keycloakserver(host, version='17.0.0'): + + key = os.path.join(paths.OPENSSL_PRIVATE_DIR, "keycloak.key") + crt = os.path.join(paths.OPENSSL_PRIVATE_DIR, "keycloak.crt") +- keystore = os.path.join(paths.OPENSSL_PRIVATE_DIR, "keycloak.store") ++ keystore = os.path.join(paths.OPENSSL_PRIVATE_DIR, "keycloak.jks") + + host.run_command(["ipa-getcert", "request", "-K", + "HTTP/{0}".format(host.hostname), +@@ -49,14 +49,13 @@ def setup_keycloakserver(host, version='17.0.0'): + + # Setup keycloak service and config files + contents = textwrap.dedent(""" +- KEYCLOAK_ADMIN=admin +- KEYCLOAK_ADMIN_PASSWORD={admin_pswd} +- KC_HOSTNAME={host}:8443 ++ KC_BOOTSTRAP_ADMIN_USERNAME=admin ++ KC_BOOTSTRAP_ADMIN_PASSWORD={admin_pswd} ++ KC_HOSTNAME=https://{host}:8443/ + KC_HTTPS_CERTIFICATE_FILE={crt} + KC_HTTPS_CERTIFICATE_KEY_FILE={key} + KC_HTTPS_TRUST_STORE_FILE={store} + KC_HTTPS_TRUST_STORE_PASSWORD={store_pswd} +- KC_HTTP_RELATIVE_PATH=/auth + """).format(admin_pswd=password, host=host.hostname, crt=crt, key=key, + store=keystore, store_pswd=password) + host.put_file_contents("/etc/sysconfig/keycloak", contents) +@@ -84,14 +83,13 @@ def setup_keycloakserver(host, version='17.0.0'): + + # Run build stage first + env_vars = textwrap.dedent(""" +- export KEYCLOAK_ADMIN=admin +- export KC_HOSTNAME={hostname}:8443 ++ export KC_BOOTSTRAP_ADMIN_USERNAME=admin ++ export KC_HOSTNAME=https://{hostname}:8443/ + export KC_HTTPS_CERTIFICATE_FILE=/etc/pki/tls/certs/keycloak.crt + export KC_HTTPS_CERTIFICATE_KEY_FILE=/etc/pki/tls/private/keycloak.key +- export KC_HTTPS_TRUST_STORE_FILE=/etc/pki/tls/private/keycloak.store ++ export KC_HTTPS_TRUST_STORE_FILE=/etc/pki/tls/private/keycloak.jks + export KC_HTTPS_TRUST_STORE_PASSWORD={STORE_PASS} +- export KEYCLOAK_ADMIN_PASSWORD={ADMIN_PASS} +- export KC_HTTP_RELATIVE_PATH=/auth ++ export KC_BOOTSTRAP_ADMIN_PASSWORD={ADMIN_PASS} + """).format(hostname=host.hostname, STORE_PASS=password, + ADMIN_PASS=password) + +@@ -112,7 +110,7 @@ def setup_keycloakserver(host, version='17.0.0'): + host.run_command([kcadmin_sh, "config", "truststore", + "--trustpass", password, keystore]) + kcadmin = [kcadmin_sh, "config", "credentials", "--server", +- "https://{0}:8443/auth/".format(host.hostname), ++ "https://{0}:8443/".format(host.hostname), + "--realm", "master", "--user", "admin", + "--password", password + ] +@@ -133,7 +131,7 @@ def setup_keycloak_client(host): + password = host.config.admin_password + host.run_command(["/opt/keycloak/bin/kcreg.sh", + "config", "credentials", "--server", +- "https://{0}:8443/auth/".format(host.hostname), ++ "https://{0}:8443/".format(host.hostname), + "--realm", "master", "--user", "admin", + "--password", password] + ) +@@ -163,7 +161,7 @@ def setup_keycloak_client(host): + def uninstall_keycloak(host): + key = os.path.join(paths.OPENSSL_PRIVATE_DIR, "keycloak.key") + crt = os.path.join(paths.OPENSSL_PRIVATE_DIR, "keycloak.crt") +- keystore = os.path.join(paths.OPENSSL_PRIVATE_DIR, "keycloak.store") ++ keystore = os.path.join(paths.OPENSSL_PRIVATE_DIR, "keycloak.jks") + + host.run_command(["systemctl", "stop", "keycloak"], raiseonerr=False) + host.run_command(["getcert", "stop-tracking", "-k", key, "-f", crt], +diff --git a/ipatests/test_integration/test_idp.py b/ipatests/test_integration/test_idp.py +index ca2fcecb22459685450f2ed6c3ac1b9b215170f6..76edc9458e4448e05362ff040b8dab7a53cd3054 100644 +--- a/ipatests/test_integration/test_idp.py ++++ b/ipatests/test_integration/test_idp.py +@@ -122,7 +122,7 @@ class TestIDPKeycloak(IntegrationTest): + tasks.kinit_admin(self.master) + cmd = ["ipa", "idp-add", "keycloakidp", "--provider=keycloak", + "--client-id=ipa_oidc_client", "--org=master", +- "--base-url={0}:8443/auth".format(self.client.hostname)] ++ "--base-url={0}:8443".format(self.client.hostname)] + self.master.run_command(cmd, stdin_text="{0}\n{0}".format( + self.client.config.admin_password)) + tasks.user_add(self.master, 'keycloakuser', +@@ -282,7 +282,7 @@ class TestIDPKeycloak(IntegrationTest): + user = "backupuser" + cmd = ["ipa", "idp-add", "testidp", "--provider=keycloak", + "--client-id=ipa_oidc_client", "--org=master", +- "--base-url={0}:8443/auth".format(self.client.hostname)] ++ "--base-url={0}:8443".format(self.client.hostname)] + self.master.run_command(cmd, stdin_text="{0}\n{0}".format( + self.client.config.admin_password)) + +diff --git a/ipatests/test_integration/test_sso.py b/ipatests/test_integration/test_sso.py +index 9708e9fa05a75cb2657c657b39b015249f3fd208..57c5a96bae986ee9721fc540d2be2cdc443e78fb 100644 +--- a/ipatests/test_integration/test_sso.py ++++ b/ipatests/test_integration/test_sso.py +@@ -18,7 +18,7 @@ from selenium.webdriver.support import expected_conditions as EC + options = Options() + options.headless = True + driver = webdriver.Firefox(executable_path="/opt/geckodriver", options=options) +-verification_uri = "https://{hostname}:8443/auth/realms/master/account/#/" ++verification_uri = "https://{hostname}:8443/realms/master/account/#/" + driver.get(verification_uri) + + try: +@@ -60,7 +60,7 @@ def keycloak_add_user(host, kcadm_pass, username, password=None): + domain = host.domain.name + kcadmin_sh = "/opt/keycloak/bin/kcadm.sh" + kcadmin = [kcadmin_sh, "config", "credentials", "--server", +- f"https://{host.hostname}:8443/auth/", ++ f"https://{host.hostname}:8443", + "--realm", "master", "--user", "admin", + "--password", kcadm_pass] + +-- +2.47.1 + diff --git a/freeipa.spec b/freeipa.spec index 579bf72..8e3e9ac 100644 --- a/freeipa.spec +++ b/freeipa.spec @@ -224,7 +224,7 @@ Name: %{package_name} Version: %{IPA_VERSION} -Release: 8%{?rc_version:.%rc_version}%{?dist} +Release: 9%{?rc_version:.%rc_version}%{?dist} Summary: The Identity, Policy and Audit system License: GPL-3.0-or-later @@ -294,6 +294,10 @@ Patch0043: 0043-Unify-use-of-option-parsers.patch Patch0044: 0044-ipa-tools-remove-sensitive-material-from-the-command.patch Patch0045: 0045-ipa-otpd-use-oidc_child-s-client-secret-stdin-option.patch Patch0046: 0046-Fix-pylint-issue-in-ipatests-i18n.py.patch +Patch0047: 0047-ipatests-skip-test_ipahealthcheck_ds_configcheck-for.patch +Patch0048: 0048-ipatests-restart-dirsrv-after-time-jumps.patch +Patch0049: 0049-ipa-otpd-do-not-pass-OIDC-client-secret-if-there-is-.patch +Patch0050: 0050-Migrate-Keycloak-tests-to-JDK-21-and-Keycloak-26.patch Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch %endif %endif @@ -1909,6 +1913,10 @@ fi %endif %changelog +* Tue Jan 21 2025 Florence Blanc-Renaud - 4.12.2-9 +- Resolves: RHEL-74465 kinit with external idp user is failing +- Resolves: RHEL-75656 Include latest fixes in python3-ipatests package + * Thu Jan 16 2025 Florence Blanc-Renaud - 4.12.2-8 - Resolves: RHEL-73022 A slow HSM can cause IPA server installation to fail setting up certificate tracking [rhel-9] - Resolves: RHEL-71261 [RHEL-9.6] Include latest fixes in python3-ipatests package