From 669dd083711c28d7a5aaa28e145dde838c2f3118 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Mon, 23 Jun 2025 10:08:09 +0000 Subject: [PATCH] Import from CS git --- ...ng-with-null-LDAP-context_rhel#58435.patch | 84 ++++++++ ...n-REALM-on-the-admin-user_rhel#89895.patch | 189 ++++++++++++++++++ SPECS/ipa.spec | 12 +- 3 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0039-kdb-keeep-ipadb_get_connection-from-succeding-with-null-LDAP-context_rhel#58435.patch create mode 100644 SOURCES/0040-Set-krbCanonicalName-admin-REALM-on-the-admin-user_rhel#89895.patch diff --git a/SOURCES/0039-kdb-keeep-ipadb_get_connection-from-succeding-with-null-LDAP-context_rhel#58435.patch b/SOURCES/0039-kdb-keeep-ipadb_get_connection-from-succeding-with-null-LDAP-context_rhel#58435.patch new file mode 100644 index 0000000..f27247b --- /dev/null +++ b/SOURCES/0039-kdb-keeep-ipadb_get_connection-from-succeding-with-null-LDAP-context_rhel#58435.patch @@ -0,0 +1,84 @@ +From ae37b3e6ed12bddb650bdce8e9729e81fef40840 Mon Sep 17 00:00:00 2001 +From: Julien Rische +Date: May 08 2025 06:21:00 +0000 +Subject: kdb: keep ipadb_get_connection() from succeeding with null LDAP context + + +The final call to ipadb_reinit_mspac() in ipadb_get_connection() is not +considered essential for the function to succeed, as there might be +cases where the required pieces of information to generate PACs are not +yet configured in the database. However, in environments where 389ds is +overwhelmed, the LDAP connection established at the beginning of +ipadb_get_connection() might already be lost while executing +ipadb_reinit_mspac(). + +Connection errors were not distinguished from configuration errors, +which could result in ipadb_get_connection() succeeding while the LDAP +context is set to null, leading to a KDC crash on the next LDAP request. + +ipadb_get_connection() now explicitly checks the value of the LDAP +context before returning. + +Fixes: https://pagure.io/freeipa/issue/9777 +Reviewed-By: Rob Crittenden +Reviewed-By: Rob Crittenden +Reviewed-By: Rafael Guterres Jeffman + +--- + +diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c +index fcadb8e..98315a0 100644 +--- a/daemons/ipa-kdb/ipa_kdb.c ++++ b/daemons/ipa-kdb/ipa_kdb.c +@@ -524,26 +524,43 @@ int ipadb_get_connection(struct ipadb_context *ipactx) + + /* get adtrust options using default refresh interval */ + ret = ipadb_reinit_mspac(ipactx, false, &stmsg); +- if (ret && stmsg) +- krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg); ++ if (ret) { ++ if (stmsg) { ++ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg); ++ } ++ /* Initialization of the MS-PAC generator is an optional dependency. ++ * Fail only if the connection was lost. */ ++ if (!ipactx->lcontext) { ++ goto done; ++ } ++ } + + ret = 0; + + done: + ldap_msgfree(res); + ++ /* LDAP context should never be null on success, but keep this test out of ++ * security to make sure we do not return an invalid context. */ ++ if (ret == 0 && !ipactx->lcontext) { ++ krb5_klog_syslog(LOG_WARNING, "Internal malfunction: LDAP connection " ++ "process resulted in an invalid context " ++ "(please report this incident)"); ++ ret = LDAP_SERVER_DOWN; ++ } ++ + if (ret) { ++ /* Cleanup LDAP context if connection failed. */ + if (ipactx->lcontext) { + ldap_unbind_ext_s(ipactx->lcontext, NULL, NULL); + ipactx->lcontext = NULL; + } +- if (ret == LDAP_SERVER_DOWN) { +- return ETIMEDOUT; +- } +- return EIO; ++ ++ /* Replace LDAP error code by POSIX error code. */ ++ ret = ret == LDAP_SERVER_DOWN ? ETIMEDOUT : EIO; + } + +- return 0; ++ return ret; + } + + static krb5_principal ipadb_create_local_tgs(krb5_context kcontext, + diff --git a/SOURCES/0040-Set-krbCanonicalName-admin-REALM-on-the-admin-user_rhel#89895.patch b/SOURCES/0040-Set-krbCanonicalName-admin-REALM-on-the-admin-user_rhel#89895.patch new file mode 100644 index 0000000..12f8ef5 --- /dev/null +++ b/SOURCES/0040-Set-krbCanonicalName-admin-REALM-on-the-admin-user_rhel#89895.patch @@ -0,0 +1,189 @@ +From d6d2282f9f1b93ae7fb6e074920e41e64f35ab12 Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Mon, 28 Apr 2025 13:43:40 -0400 +Subject: [PATCH] Set krbCanonicalName=admin@REALM on the admin user + +The admin must always own this name. If another entry has this +value set then remove it. + +There is a uniqueness plugin for this attribute so the only two +possibilities are: + +- no entry has this value set +- the admin user has this value set +- a different entry has the value set + +Still, for robustness purposes, the upgrade plugin will handle +more entries. + +Signed-off-by: Rob Crittenden +--- + install/share/bootstrap-template.ldif | 1 + + .../updates/90-post_upgrade_plugins.update | 1 + + .../plugins/add_admin_krbcanonicalname.py | 79 +++++++++++++++++++ + ipatests/test_integration/test_commands.py | 38 +++++++++ + 4 files changed, 119 insertions(+) + create mode 100644 ipaserver/install/plugins/add_admin_krbcanonicalname.py + +diff --git a/install/share/bootstrap-template.ldif b/install/share/bootstrap-template.ldif +index 325eb8450..94972eb72 100644 +--- a/install/share/bootstrap-template.ldif ++++ b/install/share/bootstrap-template.ldif +@@ -239,6 +239,7 @@ objectClass: ipasshuser + uid: admin + krbPrincipalName: admin@$REALM + krbPrincipalName: root@$REALM ++krbCanonicalName: admin@$REALM + cn: Administrator + sn: Administrator + uidNumber: $IDSTART +diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update +index 7c3bba3e0..3d78c7b5a 100644 +--- a/install/updates/90-post_upgrade_plugins.update ++++ b/install/updates/90-post_upgrade_plugins.update +@@ -25,6 +25,7 @@ plugin: update_mapping_Guests_to_nobody + plugin: fix_kra_people_entry + plugin: update_pwpolicy + plugin: update_pwpolicy_grace ++plugin: add_admin_krbcanonicalname + + # last + # DNS version 1 +diff --git a/ipaserver/install/plugins/add_admin_krbcanonicalname.py b/ipaserver/install/plugins/add_admin_krbcanonicalname.py +new file mode 100644 +index 000000000..e9ffdf55a +--- /dev/null ++++ b/ipaserver/install/plugins/add_admin_krbcanonicalname.py +@@ -0,0 +1,79 @@ ++# ++# Copyright (C) 2025 FreeIPA Contributors see COPYING for license ++# ++ ++from __future__ import absolute_import ++ ++import logging ++ ++from ipalib import errors ++from ipalib import Registry ++from ipalib import Updater ++from ipapython.dn import DN ++ ++logger = logging.getLogger(__name__) ++ ++register = Registry() ++ ++ ++@register() ++class add_admin_krbcanonicalname(Updater): ++ """ ++ Ensures that only the admin user has the krbCanonicalName of ++ admin@$REALM. ++ """ ++ ++ def execute(self, **options): ++ ldap = self.api.Backend.ldap2 ++ ++ search_filter = ( ++ "(krbcanonicalname=admin@{})".format(self.api.env.realm)) ++ try: ++ (entries, _truncated) = ldap.find_entries( ++ filter=search_filter, base_dn=self.api.env.basedn, ++ time_limit=0, size_limit=0) ++ except errors.EmptyResult: ++ logger.debug("add_admin_krbcanonicalname: No user set with " ++ "admin krbcanonicalname") ++ entries = [] ++ # fall through ++ except errors.ExecutionError as e: ++ logger.error("add_admin_krbcanonicalname: Can not get list " ++ "of krbcanonicalname: %s", e) ++ return False, [] ++ ++ admin_set = False ++ # admin should be only user with admin@ as krbcanonicalname ++ # It has a uniquness setting so there can be only one, we ++ # just didn't automatically set it for admin. ++ for entry in entries: ++ if entry.single_value.get('uid') != 'admin': ++ logger.critical( ++ "add_admin_krbcanonicalname: " ++ "entry %s has a krbcanonicalname of admin. Removing.", ++ entry.dn) ++ del entry['krbcanonicalname'] ++ ldap.update_entry(entry) ++ else: ++ admin_set = True ++ ++ if not admin_set: ++ dn = DN( ++ ('uid', 'admin'), ++ self.api.env.container_user, ++ self.api.env.basedn) ++ entry = ldap.get_entry(dn) ++ entry['krbcanonicalname'] = 'admin@%s' % self.api.env.realm ++ try: ++ ldap.update_entry(entry) ++ except errors.DuplicateEntry: ++ logger.critical( ++ "add_admin_krbcanonicalname: " ++ "Failed to set krbcanonicalname on admin. It is set " ++ "on another entry.") ++ except errors.ExecutionError as e: ++ logger.critical( ++ "add_admin_krbcanonicalname: " ++ "Failed to set krbcanonicalname on admin: %s", e) ++ ++ return False, [] +diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py +index 621982c4f..1526a6e0d 100644 +--- a/ipatests/test_integration/test_commands.py ++++ b/ipatests/test_integration/test_commands.py +@@ -1796,6 +1796,44 @@ class TestIPACommandWithoutReplica(IntegrationTest): + assert result.returncode == 1 + assert 'cannot be deleted or disabled' in result.stderr_text + ++ def test_unique_krbcanonicalname(self): ++ """Verify that the uniqueness for krbcanonicalname is working""" ++ master = self.master ++ ++ base_dn = str(master.domain.basedn) ++ hostname = master.hostname ++ realm = master.domain.realm ++ principal = f'test/{hostname}@{realm}' ++ entry_ldif = textwrap.dedent(""" ++ dn: krbprincipalname={principal},cn=services,cn=accounts,{base_dn} ++ changetype: add ++ ipakrbprincipalalias: test/{hostname}@{realm} ++ krbprincipalname: {principal} ++ objectclass: ipakrbprincipal ++ objectclass: ipaobject ++ objectclass: ipaservice ++ objectclass: krbprincipal ++ objectclass: krbprincipalaux ++ objectclass: top ++ krbcanonicalname: admin@{realm} ++ managedby: fqdn={hostname},cn=computers,cn=accounts,{base_dn} ++ """).format( ++ base_dn=base_dn, ++ hostname=hostname, ++ principal=principal, ++ realm=realm) ++ tasks.kdestroy_all(master) ++ master.run_command( ++ ['kinit', '-kt', '/etc/krb5.keytab', f'host/{hostname}@{realm}']) ++ args = [ ++ 'ldapmodify', ++ '-Y', ++ 'GSSAPI' ++ ] ++ result = master.run_command(args, stdin_text=entry_ldif, ++ raiseonerr=False) ++ assert "entry with the same attribute value" in result.stderr_text ++ + + class TestIPACommandWithoutReplica(IntegrationTest): + """ +-- +2.48.1 + + diff --git a/SPECS/ipa.spec b/SPECS/ipa.spec index f1620e7..1cb969d 100644 --- a/SPECS/ipa.spec +++ b/SPECS/ipa.spec @@ -190,7 +190,7 @@ Name: %{package_name} Version: %{IPA_VERSION} -Release: 16%{?rc_version:.%rc_version}%{?dist} +Release: 18%{?rc_version:.%rc_version}%{?dist} Summary: The Identity, Policy and Audit system License: GPLv3+ @@ -247,6 +247,8 @@ Patch0035: 0035-Unconditionally-add-MS-PAC-to-global-config-on-update_rhel# Patch0036: 0036-ipatests-Update-ipa-adtrust-install-test_rhel#40894.patch Patch0037: 0037-Replica-CA-installation-ignore-skew-during-initial-replication_rhel#80995.patch Patch0038: 0038-Add-a-check-into-ipa-cert-fix-tool-to-avoid-updating-certs-if-CA-is-close-to-being-expired_rhel#4941.patch +Patch0039: 0039-kdb-keeep-ipadb_get_connection-from-succeding-with-null-LDAP-context_rhel#58435.patch +Patch0040: 0040-Set-krbCanonicalName-admin-REALM-on-the-admin-user_rhel#89895.patch %if 0%{?rhel} >= 8 Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch @@ -1761,6 +1763,14 @@ fi %endif %changelog +* Tue Jun 03 2025 Rafael Jeffman - 4.9.13-18 +- Set krbCanonicalName admin@REALM on the admin user + Resolves: RHEL-89895 + +* Mon May 19 2025 Rafael Jeffman - 4.9.13-17 +- kdb: keeep ipadb_get_connection() from succeding with null LDAP context + Resolves: RHEL-58453 + * Mon Mar 31 2025 Rafael Jeffman - 4.9.13-16 - Add a- heck into ipa-cert-fix tool to avoid updating certs if CA is close to expire Resolves: RHEL-4941