diff --git a/0090-ipa-migrate-remove-replication-state-information.patch b/0090-ipa-migrate-remove-replication-state-information.patch new file mode 100644 index 0000000..e30900c --- /dev/null +++ b/0090-ipa-migrate-remove-replication-state-information.patch @@ -0,0 +1,66 @@ +From 5f632d9d7813f89d498cfb21c8472ff3cac2538a Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 29 Apr 2025 13:55:23 -0400 +Subject: [PATCH] ipa-migrate - remove replication state information + +Remove replication state information (happens when LDIFs are used). +State information is written like: + + attribute;adcsn= + +But we also support ";binary" which should not be removed so special +handling is needed in that case. + +Signed-off-by: Mark Reynolds +Fixes: https://pagure.io/freeipa/issue/9776 +Reviewed-By: Rob Crittenden +--- + ipaserver/install/ipa_migrate.py | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py +index 95ef0ac5adc830d04a6bb3a899b20aae86a77072..8ef0071f5c2edc1ce6cba780ac9a7d74122ea79d 100644 +--- a/ipaserver/install/ipa_migrate.py ++++ b/ipaserver/install/ipa_migrate.py +@@ -202,6 +202,14 @@ def decode_attr_vals(entry_attrs): + decoded_attrs = {} + for attr in entry_attrs: + vals = ensure_list_str(entry_attrs[attr]) ++ # Remove replication state data, but don't remove ";binary" ++ # e.g. userCertififccate;binary;adcsn= ++ parts = attr.split(";") ++ if len(parts) > 1 and not attr.endswith(";binary"): ++ if parts[1] == "binary": ++ attr = parts[0] + ";binary" ++ else: ++ attr = parts[0] + decoded_attrs[attr] = vals + return decoded_attrs + +@@ -269,19 +277,19 @@ class LDIFParser(ldif.LDIFParser): + if self.mc is None: + return + ++ entry_attrs = decode_attr_vals(entry) + if self.get_realm: + # Get the realm from krb container + if DN(("cn", "kerberos"), self.mc.remote_suffix) in DN(dn): + # check objectclass krbrealmcontainer + oc_attr = 'objectClass' +- if 'objectclass' in entry: ++ if 'objectclass' in entry_attrs: + oc_attr = 'objectclass' +- if 'krbrealmcontainer' in ensure_list_str(entry[oc_attr]): +- self.mc.remote_realm = ensure_str(entry['cn'][0]) ++ if 'krbrealmcontainer' in entry_attrs[oc_attr]: ++ self.mc.remote_realm = ensure_str(entry_attrs['cn'][0]) + self.mc.log_debug("Found remote realm from ldif: " + f"{self.mc.remote_realm}") + else: +- entry_attrs = decode_attr_vals(entry) + self.mc.process_db_entry(entry_dn=dn, entry_attrs=entry_attrs) + + +-- +2.49.0 + diff --git a/0091-ipa-migrate-do-not-process-AD-entgries-in-staging-mo.patch b/0091-ipa-migrate-do-not-process-AD-entgries-in-staging-mo.patch new file mode 100644 index 0000000..2e478ba --- /dev/null +++ b/0091-ipa-migrate-do-not-process-AD-entgries-in-staging-mo.patch @@ -0,0 +1,32 @@ +From 4e23fa92f1a07565618d49ed27b54d33618bba73 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 29 Apr 2025 14:00:51 -0400 +Subject: [PATCH] ipa-migrate - do not process AD entgries in staging mode + +Only migrate AD entries in production mode due to schema conflicts +created when removing certain AD attributes (e.g. +ipantsecurityidentifier) + +SIgned-off-by: Mark Reynolds +relates: https://pagure.io/freeipa/issue/9776 +Reviewed-By: Rob Crittenden +--- + ipaserver/install/ipa_migrate_constants.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ipaserver/install/ipa_migrate_constants.py b/ipaserver/install/ipa_migrate_constants.py +index 09856f07cabd124a7899bc5f355a56eb23023cc0..4beaa4f42a667ba83008213075b3ded782a83260 100644 +--- a/ipaserver/install/ipa_migrate_constants.py ++++ b/ipaserver/install/ipa_migrate_constants.py +@@ -870,7 +870,7 @@ DB_OBJECTS = { + 'oc': ['ipantdomainattrs'], + 'subtree': ',cn=ad,cn=etc,$SUFFIX', + 'label': 'AD', +- 'mode': 'all', ++ 'mode': 'production', + 'count': 0, + }, + +-- +2.49.0 + diff --git a/0092-ipa-migrate-improve-suffix-replacement.patch b/0092-ipa-migrate-improve-suffix-replacement.patch new file mode 100644 index 0000000..36195ba --- /dev/null +++ b/0092-ipa-migrate-improve-suffix-replacement.patch @@ -0,0 +1,47 @@ +From c052bbbfd2737f88b6496be7d4849cf17d9a126f Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 29 Apr 2025 14:05:15 -0400 +Subject: [PATCH] ipa-migrate - improve suffix replacement + +When values are "normalized/converted" to a new domain the order in +which the host/release/suffix are converted matters. Replacing the +suffix first can lead to incorrect results, so convert the host/realm +before converting the suffix + +Signed-off-by: Mark Reynolds +relates: https://pagure.io/freeipa/issue/9776 +Reviewed-By: Rob Crittenden +--- + ipaserver/install/ipa_migrate.py | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py +index 8ef0071f5c2edc1ce6cba780ac9a7d74122ea79d..a24a2ab7a5ffd4cf1d59179f14e2f5d348fd57e2 100644 +--- a/ipaserver/install/ipa_migrate.py ++++ b/ipaserver/install/ipa_migrate.py +@@ -1084,11 +1084,9 @@ class IPAMigrate(): + if isinstance(val, bytes) or isinstance(val, DN): + return val + +- # Replace base DN +- val = self.replace_suffix_value(val) +- + # For DNS DN we only replace suffix + if dns: ++ val = self.replace_suffix_value(val) + return val + + # Replace host +@@ -1102,6 +1100,9 @@ class IPAMigrate(): + # Replace realm + val = val.replace(self.remote_realm, self.realm) + ++ # Lastly, replace base DN ++ val = self.replace_suffix_value(val) ++ + return val + + def convert_values(self, values, dns=False): +-- +2.49.0 + diff --git a/0093-kdb-keep-ipadb_get_connection-from-succeeding-with-n.patch b/0093-kdb-keep-ipadb_get_connection-from-succeeding-with-n.patch new file mode 100644 index 0000000..751c1d9 --- /dev/null +++ b/0093-kdb-keep-ipadb_get_connection-from-succeeding-with-n.patch @@ -0,0 +1,87 @@ +From 5d893c9c3b8d384873f40d2524b1ebf0f34fb452 Mon Sep 17 00:00:00 2001 +From: Julien Rische +Date: Mon, 28 Apr 2025 18:01:39 +0200 +Subject: [PATCH] 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 +--- + daemons/ipa-kdb/ipa_kdb.c | 31 ++++++++++++++++++++++++------- + 1 file changed, 24 insertions(+), 7 deletions(-) + +diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c +index 903e19e83bbe383b878a3b9261dd501f96058d51..531ee223e1d5157c87a5c31dfe44b9cfa8dcc554 100644 +--- a/daemons/ipa-kdb/ipa_kdb.c ++++ b/daemons/ipa-kdb/ipa_kdb.c +@@ -530,26 +530,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, +-- +2.49.0 + diff --git a/0032-Use-OpenSSL-provider-with-BIND-for-Fedora-41-and-RHE.patch b/0094-Use-OpenSSL-provider-with-BIND-for-Fedora-42-and-RHE.patch similarity index 83% rename from 0032-Use-OpenSSL-provider-with-BIND-for-Fedora-41-and-RHE.patch rename to 0094-Use-OpenSSL-provider-with-BIND-for-Fedora-42-and-RHE.patch index 9a4163e..35828e3 100644 --- a/0032-Use-OpenSSL-provider-with-BIND-for-Fedora-41-and-RHE.patch +++ b/0094-Use-OpenSSL-provider-with-BIND-for-Fedora-42-and-RHE.patch @@ -1,22 +1,25 @@ -From ace726cb83320d7fcb051751591817fd419a8f6b Mon Sep 17 00:00:00 2001 +From 3e3af2d153f3fe8e8bfc0805e92cba0f5f649d73 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 6 Nov 2024 09:59:23 +0200 -Subject: [PATCH] Use OpenSSL provider with BIND for Fedora 41+ and RHEL10+ +Subject: [PATCH] Use OpenSSL provider with BIND for Fedora 42+ and RHEL10+ OpenSSL Engine API is deprecated and ability to compile against it is removed in RHEL10. OpenSSL provider API is the future. -Fedora 41+ also defaults to OpenSSL provider. With pkcs11-provider, the +Fedora 42+ also defaults to OpenSSL provider. With pkcs11-provider, the same PKCS#11 modules can be loaded transparently like with OpenSSL engines. Thus, we can update configuration to use the provider API. -TODO: - - dnssec-keyfromlabel does not work without engine, needs backport from - bind 9.20 +While Fedora 41 also defaults to OpenSSL provider, we need BIND version +that supports using OpenSSL provider API. This backport was only done in +Fedora 42. Fixes: https://pagure.io/freeipa/issue/9696 Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Alexander Bokovoy +Reviewed-By: Rob Crittenden --- freeipa.spec.in | 12 +++- install/share/Makefile.am | 2 + @@ -25,18 +28,18 @@ Signed-off-by: Alexander Bokovoy ipaplatform/base/constants.py | 1 + ipaplatform/fedora/constants.py | 9 ++- ipaplatform/rhel/constants.py | 7 ++- - ipaserver/dnssec/bindmgr.py | 21 ++++--- + ipaserver/dnssec/bindmgr.py | 27 ++++++--- ipaserver/install/dnskeysyncinstance.py | 55 +++++++++++++++---- ipaserver/install/server/upgrade.py | 12 ++-- - 10 files changed, 136 insertions(+), 27 deletions(-) + 10 files changed, 140 insertions(+), 29 deletions(-) create mode 100644 install/share/bind.openssl.provider.cnf.template create mode 100644 install/share/bind.openssl.provider.crp.cnf.template diff --git a/freeipa.spec.in b/freeipa.spec.in -index 72d7013a6c49873f4a59734c684c6c5510e669d0..3f6b133eee4ec40193b618882ad0813971beb5ec 100755 +index 01193a39e439d07ae09b48242e514fe22f1536ca..558b3cfffa11a77c459ba80316a5e0413662575e 100755 --- a/freeipa.spec.in +++ b/freeipa.spec.in -@@ -158,12 +158,20 @@ +@@ -163,12 +163,20 @@ # BIND employs 'pkcs11' OpenSSL engine instead of native PKCS11 # Fedora 31+ uses OpenSSL engine, as well as Fedora ELN (RHEL9) @@ -58,7 +61,7 @@ index 72d7013a6c49873f4a59734c684c6c5510e669d0..3f6b133eee4ec40193b618882ad08139 %if 0%{?rhel} == 8 # Make sure to use PKI versions that work with 389-ds fix for https://github.com/389ds/389-ds-base/issues/4609 -@@ -623,7 +631,7 @@ Requires: bind-dnssec-utils >= %{bind_version} +@@ -628,7 +636,7 @@ Requires: bind-dnssec-utils >= %{bind_version} Requires: bind-pkcs11 >= %{bind_version} %else Requires: softhsm >= %{softhsm_version} @@ -68,7 +71,7 @@ index 72d7013a6c49873f4a59734c684c6c5510e669d0..3f6b133eee4ec40193b618882ad08139 # See https://bugzilla.redhat.com/show_bug.cgi?id=1825812 # RHEL 8.3+ and Fedora 32+ have 2.1 diff --git a/install/share/Makefile.am b/install/share/Makefile.am -index 24664ca3bacb01fa4c57e9d7a5ea4ab48cfbdd90..0adebf8a3b0e01dbf62fe4b86190e60a3fbfea3b 100644 +index d8d270ca9f4b13ed01e65c6460a3a6b0dbbc5ebe..ae69c7bb867b9da87dcc220a93d159cca03b504d 100644 --- a/install/share/Makefile.am +++ b/install/share/Makefile.am @@ -50,6 +50,8 @@ dist_app_DATA = \ @@ -82,7 +85,7 @@ index 24664ca3bacb01fa4c57e9d7a5ea4ab48cfbdd90..0adebf8a3b0e01dbf62fe4b86190e60a kdc_extensions.template \ diff --git a/install/share/bind.openssl.provider.cnf.template b/install/share/bind.openssl.provider.cnf.template new file mode 100644 -index 0000000000000000000000000000000000000000..1bd5599cd32f9601416cbaca815dc73fca22b560 +index 0000000000000000000000000000000000000000..699922d132ad6c3d7556ebfeff7b703cfdf6e1aa --- /dev/null +++ b/install/share/bind.openssl.provider.cnf.template @@ -0,0 +1,19 @@ @@ -91,7 +94,7 @@ index 0000000000000000000000000000000000000000..1bd5599cd32f9601416cbaca815dc73f +openssl_conf = openssl_init + +[openssl_init] -+providers = provider_section ++providers = provider_sect + +[provider_sect] +default = default_sect @@ -137,10 +140,10 @@ index 0000000000000000000000000000000000000000..b52175e8f9971fa1a25a6c1c7a7121b2 +pkcs11-module-token-pin = file:$SOFTHSM_PIN +activate = 1 diff --git a/ipaplatform/base/constants.py b/ipaplatform/base/constants.py -index 1689efe52466f00fd8b014f720e1d21ebdbf2504..3f607ecbf961fbd78d78e05bcc1af3cd15a549d5 100644 +index 4c8038a846f81dcaee7cdb6a2226f26b0b12674d..8caded5f902cf6902153d1af8d48c96fe0a49f6c 100644 --- a/ipaplatform/base/constants.py +++ b/ipaplatform/base/constants.py -@@ -120,6 +120,7 @@ class BaseConstantsNamespace: +@@ -123,6 +123,7 @@ class BaseConstantsNamespace: NAMED_DATA_DIR = "data/" NAMED_OPTIONS_VAR = "OPTIONS" NAMED_OPENSSL_ENGINE = None @@ -149,7 +152,7 @@ index 1689efe52466f00fd8b014f720e1d21ebdbf2504..3f607ecbf961fbd78d78e05bcc1af3cd PKI_USER = User("pkiuser") PKI_GROUP = Group("pkiuser") diff --git a/ipaplatform/fedora/constants.py b/ipaplatform/fedora/constants.py -index 896e6f60737a904b06ac5fba6c1d1711577c79ec..78a53db28755d5394441ed6d5350648c80de54df 100644 +index 896e6f60737a904b06ac5fba6c1d1711577c79ec..1360b03536923fbbf75da7abed4799e20a469322 100644 --- a/ipaplatform/fedora/constants.py +++ b/ipaplatform/fedora/constants.py @@ -19,6 +19,10 @@ from ipaplatform.osinfo import osinfo @@ -157,8 +160,8 @@ index 896e6f60737a904b06ac5fba6c1d1711577c79ec..78a53db28755d5394441ed6d5350648c HAS_NFS_CONF = osinfo.version_number >= (30,) +# Fedora 40 and later deprecated OpenSSL engine and recommend using OpenSSL -+# provider API. -+HAS_OPENSSL_PROVIDER = osinfo.version_number >= (40,) ++# provider API. However, only bind 9.18 in F42+ was built with OpenSSL provider. ++HAS_OPENSSL_PROVIDER = osinfo.version_number >= (42,) + __all__ = ("constants", "User", "Group") @@ -200,10 +203,23 @@ index bc8c65a5d35af9afd27bc728768e49cd937e79a5..f4b50352190811db9dc780e3cec9d02c constants = RHELConstantsNamespace() diff --git a/ipaserver/dnssec/bindmgr.py b/ipaserver/dnssec/bindmgr.py -index 0c79cc03d404f0fb54bc3c6ab591206127c5870c..aeb8b919c64361fd8175366827fecba9705af3c3 100644 +index 0c79cc03d404f0fb54bc3c6ab591206127c5870c..4b0eccefc8842efedd226d46213764c2d4003fce 100644 --- a/ipaserver/dnssec/bindmgr.py +++ b/ipaserver/dnssec/bindmgr.py -@@ -121,17 +121,24 @@ class BINDMgr: +@@ -68,7 +68,7 @@ class BINDMgr: + str_val, + ipalib.constants.LDAP_GENERALIZED_TIME_FORMAT + ) +- return dt.strftime(time_bindfmt).encode('utf-8') ++ return dt.strftime(time_bindfmt) + + def dates2params(self, ldap_attrs): + """Convert LDAP timestamps to list of parameters suitable +@@ -117,21 +117,30 @@ class BINDMgr: + """Run dnssec-keyfromlabel on given LDAP object. + :returns: base file name of output files, e.g. Kaaa.test.+008+19719 + """ +- logger.info('attrs: %s', attrs) assert attrs.get('idnsseckeyzone', [b'FALSE'])[0] == b'TRUE', \ b'object %s is not a DNS zone key' % attrs['dn'] @@ -212,26 +228,29 @@ index 0c79cc03d404f0fb54bc3c6ab591206127c5870c..aeb8b919c64361fd8175366827fecba9 - paths.DNSSEC_SOFTHSM_PIN.encode('utf-8') - ) + uri = None ++ # LDAP object entries are all in binary encoding ++ keyref = attrs['idnsSecKeyRef'][0].decode('utf-8') + if platformconstants.NAMED_OPENSSL_ENGINE is not None: + uri = "%s;pin-source=%s" % ( -+ attrs['idnsSecKeyRef'][0], -+ paths.DNSSEC_SOFTHSM_PIN.encode('utf-8') ++ keyref, ++ paths.DNSSEC_SOFTHSM_PIN + ) + elif platformconstants.NAMED_OPENSSL_PROVIDER is not None: + uri = "%s;token=%s" % ( -+ attrs['idnsSecKeyRef'][0], -+ ipalib.constants.SOFTHSM_DNSSEC_TOKEN_LABEL.encode('utf-8') ++ keyref, ++ ipalib.constants.SOFTHSM_DNSSEC_TOKEN_LABEL + ) ++ ++ assert uri is not None cmd = [ paths.DNSSEC_KEYFROMLABEL, - '-E', 'pkcs11', '-K', workdir, - '-a', attrs['idnsSecAlgorithm'][0], - '-l', uri -+ '-a', attrs['idnsSecAlgorithm'][0].encode('utf-8'), ++ '-a', attrs['idnsSecAlgorithm'][0].decode('utf-8'), ] -+ if uri is not None: -+ cmd.extend(['-l', uri]) ++ cmd.extend(['-l', uri]) cmd.extend(self.dates2params(attrs)) if attrs.get('idnsSecKeySep', [b'FALSE'])[0].upper() == b'TRUE': cmd.extend(['-f', 'KSK']) @@ -331,7 +350,7 @@ index 36524655265130fca910eceb63fd4793ccc60d48..1979a472dd882a70cb0a41d782689deb sysconfig, 'OPENSSL_CONF', paths.DNSSEC_OPENSSL_CONF, diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py -index fb71df81a6bf8ecbb1631ca8f0a5fe55cc222782..e2aabb2845602aacda1ca3289b7d7e338bd2dba3 100644 +index f26a08aefcabda0c518cd026ea9273d6bf7d5b66..fb716d4c2921b2658a6fc4c984600a4feb52afce 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -549,15 +549,19 @@ def ca_initialize_hsm_state(ca): @@ -359,5 +378,5 @@ index fb71df81a6bf8ecbb1631ca8f0a5fe55cc222782..e2aabb2845602aacda1ca3289b7d7e33 dnskeysyncd.setup_named_sysconfig() dnskeysyncd.setup_ipa_dnskeysyncd_sysconfig() -- -2.47.0 +2.49.0 diff --git a/0095-DNS-detect-when-OpenSSL-engine-should-be-removed-on-.patch b/0095-DNS-detect-when-OpenSSL-engine-should-be-removed-on-.patch new file mode 100644 index 0000000..6818bb4 --- /dev/null +++ b/0095-DNS-detect-when-OpenSSL-engine-should-be-removed-on-.patch @@ -0,0 +1,50 @@ +From 3094ef83b898bb7b7a3e835084e444fd403c6ee8 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Tue, 1 Apr 2025 14:53:24 +0300 +Subject: [PATCH] DNS: detect when OpenSSL engine should be removed on upgrade + +For OpenSSL Provider API use we don't need 'named -E engine-name' +anymore, it has to be removed. The removal process is slightly +complicated because we need to detect '-E engine-name' and compare it +with the engine we know about (pkcs11) but if we are upgrading to the +build that supports OpenSSL Provider API, we don't know the engine name +anymore. + +Fixes: https://pagure.io/freeipa/issue/9696 + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Alexander Bokovoy +Reviewed-By: Rob Crittenden +--- + ipaserver/install/dnskeysyncinstance.py | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py +index 1979a472dd882a70cb0a41d782689debc66017a9..ae8a67a007cab36f81bf931e24755d3744265b8c 100644 +--- a/ipaserver/install/dnskeysyncinstance.py ++++ b/ipaserver/install/dnskeysyncinstance.py +@@ -149,7 +149,19 @@ class DNSKeySyncInstance(service.Service): + if options: + pattern = r"[ ]*-[a-zA-Z46]*E[ ]*(.*?)(?: |$)" + engines = re.findall(pattern, options) +- if engines and engines[-1] == constants.NAMED_OPENSSL_ENGINE: ++ ++ # if no '-E ' and we switched to the provider API, ++ # just exist, no named configuration to adjust ++ if len(engines) == 0 and constants.NAMED_OPENSSL_ENGINE is None: ++ return False ++ ++ # Something is configured in '-E ' but we don't have ++ # an engine name to compare because we already switched to the ++ # provider API, we only need to ensure old engine ref is removed. ++ if constants.NAMED_OPENSSL_ENGINE is None: ++ return True ++ ++ if engines[-1] == constants.NAMED_OPENSSL_ENGINE: + return True + + return False +-- +2.49.0 + diff --git a/0096-ipa-dnskeysyncd-use-systemd-tmpfiles-to-handle-token.patch b/0096-ipa-dnskeysyncd-use-systemd-tmpfiles-to-handle-token.patch new file mode 100644 index 0000000..45fa9bf --- /dev/null +++ b/0096-ipa-dnskeysyncd-use-systemd-tmpfiles-to-handle-token.patch @@ -0,0 +1,205 @@ +From efbe63a6ff2cbdab128c6d3c879862dba22ac1cb Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Fri, 25 Apr 2025 14:47:02 +0300 +Subject: [PATCH] ipa-dnskeysyncd: use systemd-tmpfiles to handle tokens + +ipa-dnskeysyncd daemon relies on both OpenDNSSEC and BIND accessing the +same cryptographic token. We use SoftHSMv2 here and store token in +DNSSEC_TOKENS_DIR, defined by the IPA platform. + +Configure ipa-dnskeysyncd service to update permissions of the token +files using custom systemd-tmpfiles configuration. + +Extend SELinux policy to handle access to the token under a separate +file context. Both token and its pin file need to be accessed by the BIND +rndc tool. + +Fixes: https://pagure.io/freeipa/issue/9696 + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Alexander Bokovoy +Reviewed-By: Rob Crittenden +--- + daemons/dnssec/Makefile.am | 1 + + daemons/dnssec/ipa-dnskeysyncd.service.in | 1 + + freeipa.spec.in | 1 + + init/tmpfilesd/Makefile.am | 11 ++++++++--- + init/tmpfilesd/ipa-dnssec.conf.in | 4 ++++ + ipaserver/install/dnskeysyncinstance.py | 10 ++++++++++ + ipaserver/install/server/upgrade.py | 10 +++++----- + selinux/ipa.fc | 3 +++ + selinux/ipa.te | 7 +++++++ + 9 files changed, 40 insertions(+), 8 deletions(-) + create mode 100644 init/tmpfilesd/ipa-dnssec.conf.in + +diff --git a/daemons/dnssec/Makefile.am b/daemons/dnssec/Makefile.am +index 0edab98be9d4dfd2221bcc3220785622a6545761..d270f0f9a5c06e9d9d455671157c3d1f32973419 100644 +--- a/daemons/dnssec/Makefile.am ++++ b/daemons/dnssec/Makefile.am +@@ -33,6 +33,7 @@ CLEANFILES = $(systemdsystemunit_DATA) $(nodist_app_SCRIPTS) + -e 's|@ODS_USER[@]|$(ODS_USER)|g' \ + -e 's|@ODS_GROUP[@]|$(ODS_GROUP)|g' \ + -e 's|@NAMED_GROUP[@]|$(NAMED_GROUP)|g' \ ++ -e 's|@IPA_DATA_DIR[@]|$(IPA_DATA_DIR)|g' \ + '$(srcdir)/$@.in' >$@ + + dnssecconfdir = $(IPA_SYSCONF_DIR)/dnssec +diff --git a/daemons/dnssec/ipa-dnskeysyncd.service.in b/daemons/dnssec/ipa-dnskeysyncd.service.in +index cd07275ad323649e305a96ad36488e93bd248d7b..6730c9676d272e38a8f69d2d23f5d29b86ff7d83 100644 +--- a/daemons/dnssec/ipa-dnskeysyncd.service.in ++++ b/daemons/dnssec/ipa-dnskeysyncd.service.in +@@ -4,6 +4,7 @@ Description=IPA key daemon + [Service] + Environment=LC_ALL=C.UTF-8 + EnvironmentFile=@sysconfenvdir@/ipa-dnskeysyncd ++ExecStartPre=/bin/sh -c '/bin/sed -e "s,@DNSSEC_TOKENS_DIR@,${DNSSEC_TOKENS_DIR},g;s,@DNSSEC_SOFTHSM_PIN@,${DNSSEC_SOFTHSM_PIN},g" @IPA_DATA_DIR@/ipa-dnssec.conf | /usr/bin/systemd-tmpfiles --create -' + ExecStart=@libexecdir@/ipa/ipa-dnskeysyncd + User=@ODS_USER@ + Group=@NAMED_GROUP@ +diff --git a/freeipa.spec.in b/freeipa.spec.in +index 558b3cfffa11a77c459ba80316a5e0413662575e..78004dc4fcec87079efcd235dcbf61ae2c20c669 100755 +--- a/freeipa.spec.in ++++ b/freeipa.spec.in +@@ -1771,6 +1771,7 @@ fi + %{_libexecdir}/ipa/ipa-ods-exporter + %{_sbindir}/ipa-dns-install + %{_mandir}/man1/ipa-dns-install.1* ++%{_usr}/share/ipa/ipa-dnssec.conf + %attr(644,root,root) %{_unitdir}/ipa-dnskeysyncd.service + %attr(644,root,root) %{_unitdir}/ipa-ods-exporter.socket + %attr(644,root,root) %{_unitdir}/ipa-ods-exporter.service +diff --git a/init/tmpfilesd/Makefile.am b/init/tmpfilesd/Makefile.am +index 5d6e96f2c07ff2b73752e46d6dbfe363a2a18821..8d264aaab06bff4c3be622d779c7fc3f4930b64d 100644 +--- a/init/tmpfilesd/Makefile.am ++++ b/init/tmpfilesd/Makefile.am +@@ -1,12 +1,17 @@ + dist_noinst_DATA = \ +- ipa.conf.in ++ ipa.conf.in \ ++ ipa-dnssec.conf.in + + systemdtmpfiles_DATA = \ + ipa.conf + +-CLEANFILES = $(systemdtmpfiles_DATA) ++appdir = $(IPA_DATA_DIR) ++dist_app_DATA = \ ++ ipa-dnssec.conf ++ ++CLEANFILES = $(systemdtmpfiles_DATA) $(app_DATA) + + %: %.in Makefile + sed \ +- -e 's|@HTTPD_GROUP[@]|$(HTTPD_GROUP)|g' \ ++ -e 's|@HTTPD_GROUP[@]|$(HTTPD_GROUP)|g;s|@ODS_USER[@]|$(ODS_USER)|g;s|@NAMED_GROUP[@]|$(NAMED_GROUP)|g' \ + '$(srcdir)/$@.in' >$@ +diff --git a/init/tmpfilesd/ipa-dnssec.conf.in b/init/tmpfilesd/ipa-dnssec.conf.in +new file mode 100644 +index 0000000000000000000000000000000000000000..1dd2b617045c405430749b304504dab1300583d4 +--- /dev/null ++++ b/init/tmpfilesd/ipa-dnssec.conf.in +@@ -0,0 +1,4 @@ ++d @DNSSEC_TOKENS_DIR@ 2770 @ODS_USER@ @NAMED_GROUP@ ++A+ @DNSSEC_TOKENS_DIR@ - - - - group:@NAMED_GROUP@:rw,user:@ODS_USER@:rw ++Z @DNSSEC_TOKENS_DIR@ - - - - - ++z @DNSSEC_SOFTHSM_PIN@ - @ODS_USER@ @NAMED_GROUP@ - - +diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py +index ae8a67a007cab36f81bf931e24755d3744265b8c..9c2bba11c08efb1ad1a9c537feced98463b6f398 100644 +--- a/ipaserver/install/dnskeysyncinstance.py ++++ b/ipaserver/install/dnskeysyncinstance.py +@@ -258,6 +258,16 @@ class DNSKeySyncInstance(service.Service): + 'SOFTHSM2_CONF', paths.DNSSEC_SOFTHSM2_CONF, + quotes=False, separator='=') + ++ directivesetter.set_directive( ++ sysconfig, ++ 'DNSSEC_TOKENS_DIR', paths.DNSSEC_TOKENS_DIR, ++ quotes=False, separator='=') ++ ++ directivesetter.set_directive( ++ sysconfig, ++ 'DNSSEC_SOFTHSM_PIN', paths.DNSSEC_SOFTHSM_PIN, ++ quotes=False, separator='=') ++ + if any([constants.NAMED_OPENSSL_ENGINE is not None, + constants.NAMED_OPENSSL_PROVIDER is not None]): + directivesetter.set_directive( +diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py +index fb716d4c2921b2658a6fc4c984600a4feb52afce..58896e33097dd1accb1c957066958f43caea8fbf 100644 +--- a/ipaserver/install/server/upgrade.py ++++ b/ipaserver/install/server/upgrade.py +@@ -547,7 +547,7 @@ def ca_initialize_hsm_state(ca): + ca.set_hsm_state(config) + + +-def dnssec_set_openssl_engine(dnskeysyncd): ++def dnssec_set_openssl_provider(dnskeysyncd): + """ + Setup OpenSSL engine or provider for BIND + """ +@@ -555,9 +555,9 @@ def dnssec_set_openssl_engine(dnskeysyncd): + constants.NAMED_OPENSSL_PROVIDER is None]): + return False + +- # Nothing to do if we are using OpenSSL engine already and not on the OS ++ # Nothing to do if we are using OpenSSL provider already and not on the OS + # that requires OpenSSL provider instead. +- if all([sysupgrade.get_upgrade_state('dns', 'openssl_engine'), ++ if all([sysupgrade.get_upgrade_state('dns', 'openssl_provider'), + constants.NAMED_OPENSSL_PROVIDER is None]): + return False + +@@ -565,7 +565,7 @@ def dnssec_set_openssl_engine(dnskeysyncd): + dnskeysyncd.setup_named_openssl_conf() + dnskeysyncd.setup_named_sysconfig() + dnskeysyncd.setup_ipa_dnskeysyncd_sysconfig() +- sysupgrade.set_upgrade_state('dns', 'openssl_engine', True) ++ sysupgrade.set_upgrade_state('dns', 'openssl_provider', True) + + return True + +@@ -1892,7 +1892,7 @@ def upgrade_configuration(): + dnskeysyncd.create_instance(fqdn, api.env.realm) + dnskeysyncd.start_dnskeysyncd() + else: +- if dnssec_set_openssl_engine(dnskeysyncd): ++ if dnssec_set_openssl_provider(dnskeysyncd): + dnskeysyncd.start_dnskeysyncd() + dnskeysyncd.set_dyndb_ldap_workdir_permissions() + +diff --git a/selinux/ipa.fc b/selinux/ipa.fc +index 15e8e41aa50228ff560e338044240b46bc24cc40..ffab59933c56791e5561d9d3a5888b6b96499337 100644 +--- a/selinux/ipa.fc ++++ b/selinux/ipa.fc +@@ -24,6 +24,9 @@ + + /var/lib/ipa/gssproxy/http.keytab -- gen_context(system_u:object_r:ipa_http_keytab_t,s0) + ++/var/lib/ipa/dnssec/tokens -- gen_context(system_u:object_r:ipa_dnskey_t,s0) ++/var/lib/ipa/dnssec/softhsm_pin -- gen_context(system_u:object_r:ipa_dnskey_t,s0) ++ + /var/log/ipa(/.*)? gen_context(system_u:object_r:ipa_log_t,s0) + + /var/log/ipabackup.log -- gen_context(system_u:object_r:ipa_log_t,s0) +diff --git a/selinux/ipa.te b/selinux/ipa.te +index e4ce66687a48b27e85591cdd8352f7cac94d3151..c6d40b148325ac317437e1bd6e7c6d50e609bf5a 100644 +--- a/selinux/ipa.te ++++ b/selinux/ipa.te +@@ -265,6 +265,13 @@ corenet_tcp_bind_generic_node(ipa_dnskey_t) + corenet_tcp_connect_kerberos_port(ipa_dnskey_t) + corenet_tcp_connect_rndc_port(ipa_dnskey_t) + ++# Allow rndc to access SoftHSM token in IPA directory ++gen_require(` ++ type ndc_t; ++') ++allow ndc_t ipa_dnskey_t:file { getattr open read }; ++ ++ + dev_read_rand(ipa_dnskey_t) + dev_read_sysfs(ipa_dnskey_t) + +-- +2.49.0 + diff --git a/0097-freeipa.spec.in-update-BIND-related-dependencies.patch b/0097-freeipa.spec.in-update-BIND-related-dependencies.patch new file mode 100644 index 0000000..0a22458 --- /dev/null +++ b/0097-freeipa.spec.in-update-BIND-related-dependencies.patch @@ -0,0 +1,74 @@ +From a66adf2618d8d92b80c79537c7bcaaedea2bd9a4 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Tue, 29 Apr 2025 09:37:44 +0300 +Subject: [PATCH] freeipa.spec.in: update BIND-related dependencies + +BIND in Fedora 42+ includes a custom backport for DNSSEC support when +using OpenSSL provider API. Make sure we have that support included. + +For RHEL 10 we should be using a similar build but it is not yet +available, so make sure we include the version that is up to date prior +to enabling DNSSEC with OpenSSL provider API. Once new BIND build is +available, we can enable OpenSSL provider API usage in ipaplatform.rhel. + +Fixes: https://pagure.io/freeipa/issue/9696 + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Alexander Bokovoy +Reviewed-By: Rob Crittenden +--- + freeipa.spec.in | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +diff --git a/freeipa.spec.in b/freeipa.spec.in +index 78004dc4fcec87079efcd235dcbf61ae2c20c669..78b044b026de6181264a3572779596325af89158 100755 +--- a/freeipa.spec.in ++++ b/freeipa.spec.in +@@ -90,7 +90,13 @@ + + # Fix for TLS 1.3 PHA, RHBZ#1775158 + %global httpd_version 2.4.37-21 ++ ++# DNSSEC support with OpenSSL provider API in RHEL 10 ++%if 0%{?rhel} < 10 + %global bind_version 9.11.20-6 ++%else ++%global bind_version 9.18.33-3 ++%endif + + # support for passkey + %global sssd_version 2.9.0 +@@ -139,11 +145,11 @@ + # Fix for TLS 1.3 PHA, RHBZ#1775146 + %global httpd_version 2.4.41-9 + +-# Fix for RHBZ#2117342 +-%if 0%{?fedora} < 37 +-%global bind_version 9.11.24-1 ++%if 0%{?fedora} < 42 ++%global bind_version 32:9.18.33-1 + %else +-%global bind_version 32:9.18.7-1 ++# BIND version with backport of DNSSEC support over OpenSSL provider API ++%global bind_version 32:9.18.35-2 + %endif + # Don't use Fedora's Python dependency generator on Fedora 30/rawhide yet. + # Some packages don't provide new dist aliases. +@@ -626,7 +632,12 @@ If you are installing an IPA server, you need to install this package. + Summary: IPA integrated DNS server with support for automatic DNSSEC signing + BuildArch: noarch + Requires: %{name}-server = %{version}-%{release} +-Requires: bind-dyndb-ldap >= 11.2-2 ++# Both Fedora 42+ and RHEL support newer bind-dyndb-ldap 11.11 ++%if 0%{?fedora} < 42 ++Requires: bind-dyndb-ldap >= 11.10-33 ++%else ++Requires: bind-dyndb-ldap >= 11.11 ++%endif + Requires: bind >= %{bind_version} + Requires: bind-utils >= %{bind_version} + # bind-dnssec-utils is required by the OpenDNSSec integration +-- +2.49.0 + diff --git a/0098-freeipa.spec.in-do-not-recommend-encrypted-DNS-on-pr.patch b/0098-freeipa.spec.in-do-not-recommend-encrypted-DNS-on-pr.patch new file mode 100644 index 0000000..3098282 --- /dev/null +++ b/0098-freeipa.spec.in-do-not-recommend-encrypted-DNS-on-pr.patch @@ -0,0 +1,43 @@ +From 13332be5931b2492b19121c083ab0e37aa1ae88f Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Mon, 5 May 2025 11:18:59 +0300 +Subject: [PATCH] freeipa.spec.in: do not recommend encrypted DNS on pre-F42 + systems + +Fedora 41 or earlier do not have infrastructure to run encrypted DNS +server side. + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Alexander Bokovoy +Reviewed-By: Rob Crittenden +--- + freeipa.spec.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/freeipa.spec.in b/freeipa.spec.in +index 78b044b026de6181264a3572779596325af89158..ccb37ff0a7e46292ea0b5c50346f6aff984eecc7 100755 +--- a/freeipa.spec.in ++++ b/freeipa.spec.in +@@ -652,7 +652,9 @@ Requires: %{openssl_pkcs11_name} >= %{openssl_pkcs11_version} + # See https://bugzilla.redhat.com/show_bug.cgi?id=1825812 + # RHEL 8.3+ and Fedora 32+ have 2.1 + Requires: opendnssec >= 2.1.6-5 ++%if 0%{?fedora} >= 42 || 0%{?rhel} > 9 + Recommends: %{name}-server-encrypted-dns ++%endif + %{?systemd_requires} + + Provides: %{alt_name}-server-dns = %{version} +@@ -670,6 +672,8 @@ Integrated DNS server is BIND 9. OpenDNSSEC provides key management. + %package server-encrypted-dns + Summary: support for encrypted DNS in IPA integrated DNS server + Requires: %{name}-client-encrypted-dns ++# Will need newer bind-dyndb-ldap to allow use of OpenSSL provider API ++Requires: bind-dyndb-ldap >= 11.11 + + %description server-encrypted-dns + Provides support for enabling DNS over TLS in the IPA integrated DNS +-- +2.49.0 + diff --git a/0099-dns-install-fix-selinux-avc-relabelto.patch b/0099-dns-install-fix-selinux-avc-relabelto.patch new file mode 100644 index 0000000..fd86f17 --- /dev/null +++ b/0099-dns-install-fix-selinux-avc-relabelto.patch @@ -0,0 +1,61 @@ +From 0aff65d9453d456c7a99c1294dde8c2e2ab57ca8 Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Mon, 12 May 2025 16:22:46 +0200 +Subject: [PATCH] dns install: fix selinux avc relabelto + +During the DNS server installation in SELinux enforcing mode, +ipa-dnskeysyncd.service fails to restart because of the AVC: +avc: denied { relabelto } for pid=29955 comm="systemd-tmpfile" name="softhsm_pin" dev="vda4" ino=38440 scontext=system_u:system_r:systemd_tmpfiles_t:s0 tcontext=system_u:object_r:ipa_dnskey_t:s0 tclass=file permissive=0 + +Add the missing policies +allow systemd_tmpfiles_t ipa_dnskey_t:file relabelto; +allow ipa_dnskey_t fs_t:filesystem associate; +allow ipa_ods_exporter_t ipa_dnskey_t:file { getattr ioctl open read }; +allow named_t ipa_dnskey_t:file { getattr open read }; + +Fixes: https://pagure.io/freeipa/issue/9782 +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: Alexander Bokovoy +Reviewed-By: Rob Crittenden +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Alexander Bokovoy +Reviewed-By: Rob Crittenden +--- + selinux/ipa.te | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/selinux/ipa.te b/selinux/ipa.te +index c6d40b148325ac317437e1bd6e7c6d50e609bf5a..b5354051830f6bd216e7b0caa9338de9f43b25a9 100644 +--- a/selinux/ipa.te ++++ b/selinux/ipa.te +@@ -271,6 +271,19 @@ gen_require(` + ') + allow ndc_t ipa_dnskey_t:file { getattr open read }; + ++# Allow relabel from systemd_tmpfiles_t ++gen_require(` ++ type systemd_tmpfiles_t; ++') ++allow systemd_tmpfiles_t ipa_dnskey_t:file { getattr relabelfrom relabelto }; ++gen_require(` ++ type fs_t; ++') ++allow ipa_dnskey_t fs_t:filesystem associate; ++gen_require(` ++ type named_t; ++') ++allow named_t ipa_dnskey_t:file { getattr open read }; + + dev_read_rand(ipa_dnskey_t) + dev_read_sysfs(ipa_dnskey_t) +@@ -320,6 +333,7 @@ optional_policy(` + allow ipa_ods_exporter_t self:netlink_route_socket { bind create getattr nlmsg_read }; + allow ipa_ods_exporter_t self:udp_socket { connect create getattr }; + allow ipa_ods_exporter_t self:unix_dgram_socket { create getopt setopt }; ++allow ipa_ods_exporter_t ipa_dnskey_t:file { getattr ioctl open read }; + + manage_files_pattern(ipa_ods_exporter_t, ipa_var_lib_t, ipa_var_lib_t) + list_dirs_pattern(ipa_ods_exporter_t, ipa_var_lib_t, ipa_var_lib_t) +-- +2.49.0 + diff --git a/0100-ipatests-test_manual_renewal_master_transfer-must-wa.patch b/0100-ipatests-test_manual_renewal_master_transfer-must-wa.patch new file mode 100644 index 0000000..eed91fb --- /dev/null +++ b/0100-ipatests-test_manual_renewal_master_transfer-must-wa.patch @@ -0,0 +1,35 @@ +From 17fdff8f2f1664a387147e13a851bc1248abc29c Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Mon, 19 May 2025 09:56:36 +0200 +Subject: [PATCH] ipatests: test_manual_renewal_master_transfer must wait for + replication + +The test is transferring the CA renewal role from master to replica. +It calls ipa config-mod on the replica then checks with ipa config-show +on the master. +Wait for replication to complete between the 2 steps. + +Fixes: https://pagure.io/freeipa/issue/9790 +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: Rob Crittenden +--- + ipatests/test_integration/test_replica_promotion.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py +index c754cef88cb275987f5afdaad43f2ea07e3b7476..3c67833d3101aef095539953e04c31d028c746d3 100644 +--- a/ipatests/test_integration/test_replica_promotion.py ++++ b/ipatests/test_integration/test_replica_promotion.py +@@ -417,6 +417,9 @@ class TestRenewalMaster(IntegrationTest): + replica = self.replicas[0] + replica.run_command(['ipa', 'config-mod', + '--ca-renewal-master-server', replica.hostname]) ++ # wait for replication to complete before checking on the master ++ tasks.wait_for_replication(replica.ldap_connect()) ++ + result = self.master.run_command(["ipa", "config-show"]).stdout_text + assert("IPA CA renewal master: %s" % replica.hostname in result), ( + "Replica hostname not found among CA renewal masters" +-- +2.49.0 + diff --git a/0101-Require-baserid-and-secondarybaserid.patch b/0101-Require-baserid-and-secondarybaserid.patch new file mode 100644 index 0000000..4e65b81 --- /dev/null +++ b/0101-Require-baserid-and-secondarybaserid.patch @@ -0,0 +1,225 @@ +From 6f1b9a4228e400ef23f0f411ebf8a98c30cd2f9f Mon Sep 17 00:00:00 2001 +From: David Hanina +Date: Mon, 5 May 2025 17:31:18 +0200 +Subject: [PATCH] Require baserid and secondarybaserid + +This has been already required for some time, just not really enforced. +Also adds few new tests, and removes test without providing rid. + +Fixes: https://pagure.io/freeipa/issue/9779 + +Signed-off-by: David Hanina +Reviewed-By: Florence Blanc-Renaud +--- + ipaclient/plugins/idrange.py | 31 +++------------ + ipaserver/plugins/idrange.py | 35 +++++++---------- + ipatests/test_cmdline/test_cli.py | 13 ------- + ipatests/test_xmlrpc/test_range_plugin.py | 46 +++++++++++++++++++++++ + 4 files changed, 66 insertions(+), 59 deletions(-) + +diff --git a/ipaclient/plugins/idrange.py b/ipaclient/plugins/idrange.py +index 1a8d68ed7ff724854d5ea2f3dd43ec9644b5c671..b62cb1e3526d33a0d762809142b6e372f6f608ea 100644 +--- a/ipaclient/plugins/idrange.py ++++ b/ipaclient/plugins/idrange.py +@@ -19,7 +19,6 @@ + + from ipaclient.frontend import MethodOverride + from ipalib.plugable import Registry +-from ipalib import api + + register = Registry() + +@@ -33,8 +32,7 @@ class idrange_add(MethodOverride): + Also ensure that secondary-rid-base is prompted for when rid-base is + specified and vice versa, in case that dom-sid was not specified. + +- Also ensure that rid-base and secondary-rid-base is prompted for +- if ipa-adtrust-install has been run on the system. ++ Also ensure that rid-base and secondary-rid-base is prompted for. + """ + + # dom-sid can be specified using dom-sid or dom-name options +@@ -63,27 +61,10 @@ class idrange_add(MethodOverride): + + else: + # This is a local range +- # Find out whether ipa-adtrust-install has been ran +- adtrust_is_enabled = api.Command['adtrust_is_enabled']()['result'] + +- if adtrust_is_enabled: +- # If ipa-adtrust-install has been ran, all local ranges +- # require both RID base and secondary RID base +- +- if rid_base is None: +- set_from_prompt('ipabaserid') +- +- if secondary_rid_base is None: +- set_from_prompt('ipasecondarybaserid') +- +- else: +- # This is a local range on a server with no adtrust support +- +- # Prompt for secondary RID base only if RID base was given +- if rid_base is not None and secondary_rid_base is None: +- set_from_prompt('ipasecondarybaserid') ++ # All local ranges require both RID base and secondary RID base ++ if rid_base is None: ++ set_from_prompt('ipabaserid') + +- # Symetrically, prompt for RID base if secondary RID base was +- # given +- if rid_base is None and secondary_rid_base is not None: +- set_from_prompt('ipabaserid') ++ if secondary_rid_base is None: ++ set_from_prompt('ipasecondarybaserid') +diff --git a/ipaserver/plugins/idrange.py b/ipaserver/plugins/idrange.py +index d155fb46da8240449a077d35e86a91ee9f95c132..1c8b5c6899ec927d753b7d9b116d35396b536339 100644 +--- a/ipaserver/plugins/idrange.py ++++ b/ipaserver/plugins/idrange.py +@@ -73,10 +73,14 @@ Both types have the following attributes in common: + With those two attributes a range object can reserve the Posix IDs starting + with base-id up to but not including base-id+range-size exclusively. + +-Additionally an ID range of the local domain may set ++Additionally an ID range of the local domain must set + - rid-base: the first RID(*) of the corresponding RID range + - secondary-rid-base: first RID of the secondary RID range + ++If the server is updated from a previous version and defines local ID ranges ++missing the rid-base and secondary-rid-base, it is recommended to use ++`ipa-idrange-fix` command to identify the missing values and fix the ID ranges. ++ + and an ID range of a trusted domain must set + - rid-base: the first RID of the corresponding RID range + - sid: domain SID of the trusted domain +@@ -519,11 +523,15 @@ class idrange_add(LDAPCreate): + 'or ipa-ad-trust-posix when ' + 'auto-private-groups is specified')) + +- # secondary base rid must be set if and only if base rid is set +- if is_set('ipasecondarybaserid') != is_set('ipabaserid'): +- raise errors.ValidationError(name='ID Range setup', +- error=_('Options secondary-rid-base and rid-base must ' +- 'be used together')) ++ # base rid and secondary base rid must be set for sidgen ++ if not (is_set('ipabaserid') and is_set('ipasecondarybaserid')): ++ raise errors.ValidationError( ++ name='ID Range setup', ++ error=_( ++ 'You must specify both rid-base and ' ++ 'secondary-rid-base options.' ++ ) ++ ) + + # and they must not overlap + if is_set('ipabaserid') and is_set('ipasecondarybaserid'): +@@ -534,21 +542,6 @@ class idrange_add(LDAPCreate): + raise errors.ValidationError(name='ID Range setup', + error=_("Primary RID range and secondary RID range" + " cannot overlap")) +- +- # rid-base and secondary-rid-base must be set if +- # ipa-adtrust-install has been run on the system +- adtrust_is_enabled = api.Command['adtrust_is_enabled']()['result'] +- +- if adtrust_is_enabled and not ( +- is_set('ipabaserid') and is_set('ipasecondarybaserid')): +- raise errors.ValidationError( +- name='ID Range setup', +- error=_( +- 'You must specify both rid-base and ' +- 'secondary-rid-base options, because ' +- 'ipa-adtrust-install has already been run.' +- ) +- ) + return dn + + def post_callback(self, ldap, dn, entry_attrs, *keys, **options): +diff --git a/ipatests/test_cmdline/test_cli.py b/ipatests/test_cmdline/test_cli.py +index 718798d68083285ce8aefe23af951bc819bdefdb..6c86bbb657a0d9a7b74ef34ad20a796a10073315 100644 +--- a/ipatests/test_cmdline/test_cli.py ++++ b/ipatests/test_cmdline/test_cli.py +@@ -276,25 +276,12 @@ class TestCLIParsing: + ipasecondarybaserid=u'500000', + ) + +- def test_without_options(): +- self.check_command( +- 'idrange_add range1 --base-id=1 --range-size=1', +- 'idrange_add', +- cn=u'range1', +- ipabaseid=u'1', +- ipaidrangesize=u'1', +- ) +- + adtrust_dn = 'cn=ADTRUST,cn=%s,cn=masters,cn=ipa,cn=etc,%s' % \ + (api.env.host, api.env.basedn) + adtrust_is_enabled = api.Command['adtrust_is_enabled']()['result'] + mockldap = None + + if not adtrust_is_enabled: +- # ipa-adtrust-install not run - no need to pass rid-base +- # and secondary-rid-base +- test_without_options() +- + # Create a mock service object to test against + adtrust_add = dict( + ipaconfigstring=b'enabledService', +diff --git a/ipatests/test_xmlrpc/test_range_plugin.py b/ipatests/test_xmlrpc/test_range_plugin.py +index 36469525b14ee507f2d8580b1f021ff09b82c99d..ffc89c028168740e7b8ae217259af512abff2d8a 100644 +--- a/ipatests/test_xmlrpc/test_range_plugin.py ++++ b/ipatests/test_xmlrpc/test_range_plugin.py +@@ -1086,4 +1086,50 @@ class test_range(Declarative): + ), + ), + ++ # Fail without baserid and secondarybaserid ++ ++ dict( ++ desc='Try creating ID range %r without both rid' % (testrange9), ++ command=('idrange_add', [testrange9], ++ dict(ipabaseid=testrange9_base_id, ++ ipaidrangesize=testrange9_size)), ++ expected=errors.ValidationError( ++ name='ID Range setup', ++ error=( ++ 'You must specify both rid-base and ' ++ 'secondary-rid-base options.' ++ ) ++ ) ++ ), ++ ++ dict( ++ desc='Try creating ID range %r without' ++ 'secondarybaserid' % (testrange9), ++ command=('idrange_add', [testrange9], ++ dict(ipabaseid=testrange9_base_id, ++ ipaidrangesize=testrange9_size, ++ ipabaserid=testrange9_base_rid)), ++ expected=errors.ValidationError( ++ name='ID Range setup', ++ error=( ++ 'You must specify both rid-base and ' ++ 'secondary-rid-base options.' ++ ) ++ ) ++ ), ++ ++ dict( ++ desc='Try creating ID range %r without baserid' % (testrange9), ++ command=('idrange_add', [testrange9], ++ dict(ipabaseid=testrange9_base_id, ++ ipaidrangesize=testrange9_size, ++ ipasecondarybaserid=testrange9_secondary_base_rid)), ++ expected=errors.ValidationError( ++ name='ID Range setup', ++ error=( ++ 'You must specify both rid-base and ' ++ 'secondary-rid-base options.' ++ ) ++ ) ++ ), + ] +-- +2.49.0 + diff --git a/0102-ipa-config-mod-fix-internalerror-when-setting-an-emp.patch b/0102-ipa-config-mod-fix-internalerror-when-setting-an-emp.patch new file mode 100644 index 0000000..acc805f --- /dev/null +++ b/0102-ipa-config-mod-fix-internalerror-when-setting-an-emp.patch @@ -0,0 +1,90 @@ +From 1c069653806ce8224132a35d6d3bd01ac53098b6 Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Mon, 26 May 2025 18:24:12 +0200 +Subject: [PATCH] ipa config-mod: fix internalerror when setting an empty + ipaconfigstring + +When ipa config-mod is called with --ipaconfigstring="", the command +fails with an InternalError. +This happens because the code added for 32bits uid did not properly +handle this case. + +Same issue if ipa subid-stats is called with a null ipaconfigstring. + +This commit now handles when ipaconfigstring is empty or None, and adds +a test. + +Fixes: https://pagure.io/freeipa/issue/9794 +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: Francisco Trivino +--- + ipaserver/plugins/config.py | 4 +-- + ipatests/test_integration/test_commands.py | 30 ++++++++++++++++++++++ + 2 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py +index c509c2c13adfb4950741f63ffcbc9f3f806c0c3b..d9769ab1fb8498c24ce41ad32af40938bdaee804 100644 +--- a/ipaserver/plugins/config.py ++++ b/ipaserver/plugins/config.py +@@ -524,7 +524,7 @@ class config(LDAPObject): + def is_config_option_present(self, option): + dn = DN(('cn', 'ipaconfig'), ('cn', 'etc'), self.api.env.basedn) + configentry = self.api.Backend.ldap2.get_entry(dn, ['ipaconfigstring']) +- configstring = configentry['ipaconfigstring'] ++ configstring = configentry.get('ipaconfigstring') or [] + return (option.lower() in map(str.lower, configstring)) + + +@@ -702,7 +702,7 @@ class config_mod(LDAPUpdate): + error=_('SELinux user map default user not in order list')) + + if 'ipaconfigstring' in entry_attrs: +- configstring = entry_attrs['ipaconfigstring'] ++ configstring = entry_attrs['ipaconfigstring'] or [] + if 'SubID:Disable'.lower() in map(str.lower, configstring): + # Check if SubIDs already allocated + try: +diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py +index f64152908b3e1cbca451697043c1fcc8ad37fee6..9cad5772127bcd860aeecc8dabe73d5f160faf7b 100644 +--- a/ipatests/test_integration/test_commands.py ++++ b/ipatests/test_integration/test_commands.py +@@ -2123,6 +2123,36 @@ class TestIPACommandWithoutReplica(IntegrationTest): + assert old_err_msg not in dirsrv_error_log + assert re.search(new_err_msg, dirsrv_error_log) + ++ @pytest.fixture ++ def update_ipaconfigstring(self): ++ """ ++ This fixture stores the value of ipaconfigstring parameter ++ and reverts to the initial value ++ """ ++ ldap = self.master.ldap_connect() ++ dn = DN( ++ ("cn", "ipaconfig"), ('cn', 'etc'), ++ self.master.domain.basedn ++ ) ++ entry = ldap.get_entry(dn) ++ val = entry.get("ipaconfigstring") ++ yield ++ ++ # re-read the entry as the value may have been changed by the test ++ entry = ldap.get_entry(dn) ++ entry["ipaconfigstring"] = val ++ ldap.update_entry(entry) ++ ++ def test_empty_ipaconfigstring(self, update_ipaconfigstring): ++ """ ++ Test for https://pagure.io/freeipa/issue/9794 ++ ++ Test that setting an empty ipaconfigstring does not fail. ++ Subsequent calls to ipa subid-stats should also succeed. ++ """ ++ self.master.run_command(['ipa', 'config-mod', "--ipaconfigstring="]) ++ self.master.run_command(['ipa', 'subid-stats']) ++ + def test_ipa_cacert_manage_prune(self): + """Test for ipa-cacert-manage prune + +-- +2.49.0 + diff --git a/0103-ipatests-Test-to-check-dot-forwarders-are-added-to-u.patch b/0103-ipatests-Test-to-check-dot-forwarders-are-added-to-u.patch new file mode 100644 index 0000000..eb87f96 --- /dev/null +++ b/0103-ipatests-Test-to-check-dot-forwarders-are-added-to-u.patch @@ -0,0 +1,52 @@ +From 383574be4e645155fb58a79612138e51c3bdc4eb Mon Sep 17 00:00:00 2001 +From: Sudhir Menon +Date: Tue, 13 May 2025 15:58:56 +0530 +Subject: [PATCH] ipatests: Test to check dot forwarders are added to unbound. + +This test checks that dns forwarder is listed in +dnsserver-show command and also the dot forwarder is +added to unbound and included in /etc/unbound/conf.d/zzz-ipa.conf + +Signed-off-by: Sudhir Menon +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Antonio Torres +--- + ipatests/test_integration/test_edns.py | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/ipatests/test_integration/test_edns.py b/ipatests/test_integration/test_edns.py +index b42570ffa2c1cba8271ff08e084da0107e57d054..dd046f226926d09074d8d6ce536999c5d452fcc4 100644 +--- a/ipatests/test_integration/test_edns.py ++++ b/ipatests/test_integration/test_edns.py +@@ -247,6 +247,7 @@ class TestDNSOverTLS(IntegrationTest): + + + class TestDNS_DoT(TestDNS): ++ + @classmethod + def install(cls, mh): + tasks.install_packages(cls.master, ['*ipa-server-encrypted-dns']) +@@ -255,3 +256,20 @@ class TestDNS_DoT(TestDNS): + "--dot-forwarder", "1.1.1.1#cloudflare-dns.com" + ] + tasks.install_master(cls.master, extra_args=args) ++ ++ def test_check_dot_forwarder_added_in_ipa_conf(self): ++ """ ++ This test checks that forwarders is listed in ++ dnsserver-show command and also the dot forwarder is ++ added to unbound and included in ++ /etc/unbound/conf.d/zzz-ipa.conf ++ """ ++ msg = 'Forwarders: 127.0.0.55' ++ cmd1 = self.master.run_command( ++ ["ipa", "dnsserver-show", self.master.hostname] ++ ) ++ assert msg in cmd1.stdout_text ++ contents = self.master.get_file_contents( ++ paths.UNBOUND_CONF, encoding='utf-8' ++ ) ++ assert 'forward-addr: 1.1.1.1#cloudflare-dns.com' in contents +-- +2.49.0 + diff --git a/0104-Fix-some-issues-identified-by-a-static-analyzer.patch b/0104-Fix-some-issues-identified-by-a-static-analyzer.patch new file mode 100644 index 0000000..3b630a6 --- /dev/null +++ b/0104-Fix-some-issues-identified-by-a-static-analyzer.patch @@ -0,0 +1,147 @@ +From 777f4c0ed631f70b64f6a972e7e6cb140155ef1f Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Thu, 8 May 2025 13:55:34 -0400 +Subject: [PATCH] Fix some issues identified by a static analyzer + +Remove resource leak when reading the IPA config in ipa-getkeytab +Free popt in ipa-getkeytab + +Initialize ret in ipa-otpd/passkey.c + +Use the correct free function in util/ipa_krb5.c + +Related: https://pagure.io/freeipa/issue/9468 +Fixes: https://pagure.io/freeipa/issue/9365 + +Signed-off-by: Rob Crittenden +Reviewed-By: David Hanina +--- + client/ipa-getkeytab.c | 13 ++++++++++++- + daemons/ipa-otpd/passkey.c | 2 +- + util/ipa_krb5.c | 2 +- + 3 files changed, 14 insertions(+), 3 deletions(-) + +diff --git a/client/ipa-getkeytab.c b/client/ipa-getkeytab.c +index 228b981c2c38c5f9227d84cbae20f598564b5dcf..8ca4b8130cd668cbbc03e969399b5fe47ce42f1e 100644 +--- a/client/ipa-getkeytab.c ++++ b/client/ipa-getkeytab.c +@@ -866,6 +866,7 @@ static int read_ipa_config(struct ipa_config **ipacfg) + (*ipacfg)->domain = ini_get_string_config_value(obj, &ret); + } + ++ ini_config_destroy(cfgctx); + return 0; + } + +@@ -984,7 +985,7 @@ int main(int argc, const char *argv[]) + krb5_context krbctx; + krb5_ccache ccache; + krb5_principal uprinc = NULL; +- krb5_principal sprinc; ++ krb5_principal sprinc = NULL; + krb5_error_code krberr; + struct keys_container keys = { 0 }; + krb5_keytab kt; +@@ -1026,6 +1027,7 @@ int main(int argc, const char *argv[]) + fprintf(stdout, "%s\n", enc); + } + ipa_krb5_free_ktypes(krbctx, ktypes); ++ poptFreeContext(pc); + exit (0); + } + +@@ -1033,6 +1035,7 @@ int main(int argc, const char *argv[]) + if (!quiet) { + poptPrintUsage(pc, stderr, 0); + } ++ poptFreeContext(pc); + exit(2); + } + +@@ -1041,12 +1044,14 @@ int main(int argc, const char *argv[]) + if (!quiet) { + poptPrintUsage(pc, stderr, 0); + } ++ poptFreeContext(pc); + exit(2); + } + + if (askbindpw) { + bindpw = ask_password(krbctx, _("Enter LDAP password"), NULL, false); + if (!bindpw) { ++ poptFreeContext(pc); + exit(2); + } + } +@@ -1056,6 +1061,7 @@ int main(int argc, const char *argv[]) + _("Bind password required when using a bind DN (-w or -W).\n")); + if (!quiet) + poptPrintUsage(pc, stderr, 0); ++ poptFreeContext(pc); + exit(10); + } + +@@ -1064,6 +1070,7 @@ int main(int argc, const char *argv[]) + "and bind DN simultaneously.\n")); + if (!quiet) + poptPrintUsage(pc, stderr, 0); ++ poptFreeContext(pc); + exit(2); + } + +@@ -1071,6 +1078,7 @@ int main(int argc, const char *argv[]) + fprintf(stderr, _("Invalid SASL bind mechanism\n")); + if (!quiet) + poptPrintUsage(pc, stderr, 0); ++ poptFreeContext(pc); + exit(2); + } + +@@ -1083,8 +1091,10 @@ int main(int argc, const char *argv[]) + "simultaneously.\n")); + if (!quiet) + poptPrintUsage(pc, stderr, 0); ++ poptFreeContext(pc); + exit(2); + } ++ poptFreeContext(pc); + + if (server && (strcasecmp(server, "_srv_") == 0)) { + struct srvrec *srvrecs, *srv; +@@ -1119,6 +1129,7 @@ int main(int argc, const char *argv[]) + /* Discovery failed, fall through to option methods */ + server = NULL; + } ++ free(ipacfg); + } + + if (!server && !ldap_uri) { +diff --git a/daemons/ipa-otpd/passkey.c b/daemons/ipa-otpd/passkey.c +index 8351f0fcf9e2245a83563eefe2c17b04c5b9f4e3..ad3c45467ba9af46cf2e333e2dbfd938c8c8d643 100644 +--- a/daemons/ipa-otpd/passkey.c ++++ b/daemons/ipa-otpd/passkey.c +@@ -307,7 +307,7 @@ bool is_passkey(struct otpd_queue_item *item) + + static json_t *ipa_passkey_to_json_array(char **ipa_passkey) + { +- int ret; ++ int ret = 0; + const char *sep; + char *start; + size_t c; +diff --git a/util/ipa_krb5.c b/util/ipa_krb5.c +index bb98ab897cf8ea933c025bdb9abf7d394cae4583..0087e53e689fc4dc5549908b3eadd6d963d94489 100644 +--- a/util/ipa_krb5.c ++++ b/util/ipa_krb5.c +@@ -80,7 +80,7 @@ static krb5_error_code ipa_get_random_salt(krb5_context krbctx, + void + ipa_krb5_free_ktypes(krb5_context context, krb5_enctype *val) + { +- free(val); ++ krb5_free_enctypes(context, val); + } + + /* +-- +2.49.0 + diff --git a/0105-ipatests-Ignore-run-log-journal-in-test_uninstallati.patch b/0105-ipatests-Ignore-run-log-journal-in-test_uninstallati.patch new file mode 100644 index 0000000..56b54c4 --- /dev/null +++ b/0105-ipatests-Ignore-run-log-journal-in-test_uninstallati.patch @@ -0,0 +1,30 @@ +From a31654e5c4ba61177928abede5885a247365d067 Mon Sep 17 00:00:00 2001 +From: PRANAV THUBE +Date: Mon, 19 May 2025 14:46:19 +0530 +Subject: [PATCH] ipatests: Ignore /run/log/journal in test_uninstallation.py + +Update - Add /run/log/journal to the allowed list for leftover files/directories + +Fixes: https://pagure.io/freeipa/issue/9788 + +Signed-off-by: PRANAV THUBE +Reviewed-By: Florence Blanc-Renaud +--- + ipatests/test_integration/test_uninstallation.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ipatests/test_integration/test_uninstallation.py b/ipatests/test_integration/test_uninstallation.py +index 049c50db536ae1070f5f958e76b12a1518da0aba..f1cc1917dd0f216be3b11803554e86d1d22c3888 100644 +--- a/ipatests/test_integration/test_uninstallation.py ++++ b/ipatests/test_integration/test_uninstallation.py +@@ -178,6 +178,7 @@ class TestUninstallCleanup(IntegrationTest): + '/var/log', + '/var/tmp/systemd-private', + '/run/systemd', ++ '/run/log/journal', + '/var/lib/authselect/backups/pre_ipaclient', + '/var/named/data/named.run', + paths.DNSSEC_SOFTHSM_PIN_SO, # See commit eb54814741 +-- +2.49.0 + diff --git a/0106-ipatests-Tests-for-krbLastSuccessfulAuth-warning.patch b/0106-ipatests-Tests-for-krbLastSuccessfulAuth-warning.patch new file mode 100644 index 0000000..4d8315d --- /dev/null +++ b/0106-ipatests-Tests-for-krbLastSuccessfulAuth-warning.patch @@ -0,0 +1,77 @@ +From 3ba0f6a34cb018a36bc548667e2b433d05da6a45 Mon Sep 17 00:00:00 2001 +From: Sudhir Menon +Date: Tue, 6 May 2025 15:37:54 +0530 +Subject: [PATCH] ipatests: Tests for krbLastSuccessfulAuth warning + +This testcase checks that ipa-healthcheck issues +warning when ipaconfigstring=AllowNThash + +Ref: https://github.com/freeipa/freeipa-healthcheck/issues/315 + +Signed-off-by: Sudhir Menon +Reviewed-By: Florence Blanc-Renaud +--- + .../test_integration/test_ipahealthcheck.py | 40 ++++++++++++++++++- + 1 file changed, 39 insertions(+), 1 deletion(-) + +diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py +index b8ee2884de51a2e0b2dcf2991452486c29c4ed00..0ebc7149f88394bf6b6355adbb88b3ad92697517 100644 +--- a/ipatests/test_integration/test_ipahealthcheck.py ++++ b/ipatests/test_integration/test_ipahealthcheck.py +@@ -1526,6 +1526,45 @@ class TestIpaHealthCheck(IntegrationTest): + ] + ) + ++ @pytest.fixture ++ def change_pwd_plugin_default(self): ++ """ ++ Fixture to change the password plugin feature ++ to AllowNThash and change it to default ++ """ ++ self.master.run_command( ++ [ ++ "ipa", "config-mod", "--delattr", ++ "ipaconfigstring=KDC:Disable Last Success" ++ ] ++ ) ++ yield ++ self.master.run_command( ++ [ ++ "ipa", "config-mod", "--addattr", ++ "ipaconfigstring=KDC:Disable Last Success" ++ ] ++ ) ++ ++ def test_krbLastSuccessfulAuth_warning(self, change_pwd_plugin_default): ++ """ ++ This test checks that warning message is displayed ++ when password plugin feature is modified to ++ AllowNThash ++ """ ++ err_msg = ( ++ "Last Successful Auth is enabled. " ++ "It may cause performance problems." ++ ) ++ returncode, data = run_healthcheck( ++ self.master, "ipahealthcheck.ipa.config", ++ "IPAkrbLastSuccessfulAuth", ++ ) ++ assert returncode == 1 ++ for check in data: ++ assert check["result"] == "WARNING" ++ assert check["kw"]["msg"] == err_msg ++ + @pytest.fixture + def expire_cert_critical(self): + """ +@@ -1553,7 +1592,6 @@ class TestIpaHealthCheck(IntegrationTest): + assert "Expired Certificate" in check["kw"]["items"] + assert check["kw"]["msg"] == msg + +- + def test_ipa_healthcheck_expiring(self, restart_service): + """ + There are two overlapping tests for expiring certs, check both. +-- +2.49.0 + diff --git a/0107-ipatests-ipahealthcheck-warns-for-user-provided-cert.patch b/0107-ipatests-ipahealthcheck-warns-for-user-provided-cert.patch new file mode 100644 index 0000000..6cdb119 --- /dev/null +++ b/0107-ipatests-ipahealthcheck-warns-for-user-provided-cert.patch @@ -0,0 +1,82 @@ +From cef199631109b91462bf25ae8893ca8980faf5bf Mon Sep 17 00:00:00 2001 +From: Sudhir Menon +Date: Wed, 21 May 2025 17:20:04 +0530 +Subject: [PATCH] ipatests: ipahealthcheck warns for user provided certificates + about to expire + +This patch tests that ipa-healthcheck tools warns when IPA server is +installed CALess and user provided certificates are about to expire. + +Signed-off-by: Sudhir Menon +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Florence Blanc-Renaud +--- + .../test_integration/test_ipahealthcheck.py | 48 +++++++++++++++++++ + 1 file changed, 48 insertions(+) + +diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py +index 0ebc7149f88394bf6b6355adbb88b3ad92697517..13fcc3d43545590e025598fcc9c9ee40f62dae76 100644 +--- a/ipatests/test_integration/test_ipahealthcheck.py ++++ b/ipatests/test_integration/test_ipahealthcheck.py +@@ -26,6 +26,7 @@ from ipatests.pytest_ipa.integration import tasks + from ipaplatform.paths import paths + from ipaplatform.osinfo import osinfo + from ipaserver.install.installutils import resolve_ip_addresses_nss ++from ipatests.test_integration.test_caless import CALessBase + from ipatests.test_integration.base import IntegrationTest + from pkg_resources import parse_version + from ipatests.test_integration.test_cert import get_certmonger_fs_id +@@ -3135,3 +3136,50 @@ class TestIpaHealthCheckSingleMaster(IntegrationTest): + finally: + # cleanup + tasks.uninstall_master(self.master) ++ ++ ++class TestIPAHealthcheckWithCALess(CALessBase): ++ """ ++ Install CALess server with user provided certificate. ++ """ ++ num_replicas = 0 ++ ++ @classmethod ++ def install(cls, mh): ++ super(TestIPAHealthcheckWithCALess, cls).install(mh) ++ cls.create_pkcs12('ca1/server') ++ cls.prepare_cacert('ca1') ++ result = cls.install_server() ++ assert result.returncode == 0 ++ ++ @pytest.fixture ++ def expire_cert_warn(self): ++ """ ++ Fixture to move the cert to about to expire, by moving the ++ system date using date -s command and revert it back ++ """ ++ self.master.run_command(['date','-s', '+11Months10Days']) ++ yield ++ self.master.run_command(['date','-s', '-11Months10Days']) ++ self.master.run_command(['ipactl', 'restart']) ++ ++ def test_ipahealthcheck_warns_on_expired_user_certs(self, expire_cert_warn): ++ """ ++ This testcase checks that ipa-healthcheck warns ++ on expiring user-provided certificates. ++ """ ++ msg = ( ++ 'Request id {key} expires in {days} days. ' ++ 'You need to manually renew this certificate.' ++ ) ++ returncode, data = run_healthcheck( ++ self.master, "ipahealthcheck.ipa.certs", ++ "IPAUserProvidedExpirationCheck", ++ ) ++ assert returncode == 1 ++ certs = [d["kw"]["key"] for d in data] ++ assert set(certs) == {'HTTP', 'LDAP', 'KDC'} ++ for check in data: ++ assert check["result"] == "WARNING" ++ assert check["kw"]["key"] in ("LDAP", "HTTP", "KDC") ++ assert check["kw"]["msg"] == msg +-- +2.49.0 + diff --git a/0108-Warn-when-UID-is-out-of-local-ID-ranges.patch b/0108-Warn-when-UID-is-out-of-local-ID-ranges.patch new file mode 100644 index 0000000..e60fe66 --- /dev/null +++ b/0108-Warn-when-UID-is-out-of-local-ID-ranges.patch @@ -0,0 +1,278 @@ +From 0c98af9f70c62da3d3dea02b91a9330a5f9f669a Mon Sep 17 00:00:00 2001 +From: David Hanina +Date: Thu, 22 May 2025 08:25:07 +0200 +Subject: [PATCH] Warn when UID is out of local ID ranges + +Provides simple warning when creating new user with uid out of +all local ranges, as this is the main culprit of breaking Kerberos, by +not generating ipantsecurityidentifier. We don't have to check for +user-mod, because modification never changes ipantsecurityidentifier. +We do not have to check groups, as groups are ignored for ipa without +AD trust. It's reasonable to revisit this in the future for group +creation and warn against groups out of ranges as well as +warn for users with groups without SID, in case AD trust is enabled. + +Fixes: https://pagure.io/freeipa/issue/9781 +Signed-off-by: David Hanina +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Rob Crittenden +--- + ipalib/messages.py | 12 +++++ + ipaserver/plugins/baseuser.py | 29 +++++++++++- + ipatests/test_xmlrpc/test_stageuser_plugin.py | 45 ++++++++++++++++++- + ipatests/test_xmlrpc/test_user_plugin.py | 43 ++++++++++++++++++ + .../test_xmlrpc/tracker/stageuser_plugin.py | 22 +++++++++ + 5 files changed, 148 insertions(+), 3 deletions(-) + +diff --git a/ipalib/messages.py b/ipalib/messages.py +index 6a70bbc7556126748cc2ec031fc2af36bfe76f74..a440ca6221d00e6d753c94f87396fc5d7ae177b5 100644 +--- a/ipalib/messages.py ++++ b/ipalib/messages.py +@@ -519,6 +519,18 @@ class ServerUpgradeRequired(PublicMessage): + ) + + ++class UidNumberOutOfLocalIDRange(PublicMessage): ++ """ ++ **13034** UID Number is out of all local ID Ranges ++ """ ++ errno = 13034 ++ type = "warning" ++ format = _( ++ "User '%(user)s', with UID Number '%(uidnumber)d' is out of all ID " ++ "Ranges, 'SID' will not be correctly generated." ++ ) ++ ++ + def iter_messages(variables, base): + """Return a tuple with all subclasses + """ +diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py +index 22393b8f6c5d3e40b57f11947d0a0358d3a087bc..21e05d4d983502fde76af549594d678d51451e9c 100644 +--- a/ipaserver/plugins/baseuser.py ++++ b/ipaserver/plugins/baseuser.py +@@ -23,7 +23,7 @@ from cryptography.hazmat.primitives.serialization import load_pem_public_key + import re + import six + +-from ipalib import api, errors, constants ++from ipalib import api, errors, constants, messages + from ipalib import ( + Flag, Int, Password, Str, Bool, StrEnum, DateTime, DNParam) + from ipalib.parameters import Principal, Certificate, MAX_UINT32 +@@ -198,6 +198,22 @@ def validate_passkey(ugettext, key): + return None + + ++def is_in_local_idrange(uidnumber): ++ result = api.Command.idrange_find( ++ iparangetype='ipa-local', ++ sizelimit=0, ++ ) ++ ++ for r in result['result']: ++ if 'ipabaserid' in r: ++ ipabaseid = int(r['ipabaseid'][0]) ++ ipaidrangesize = int(r['ipaidrangesize'][0]) ++ if ipabaseid <= uidnumber < ipabaseid + ipaidrangesize: ++ return True ++ ++ return False ++ ++ + class baseuser(LDAPObject): + """ + baseuser object. +@@ -621,6 +637,17 @@ class baseuser_add(LDAPCreate): + add_missing_object_class(ldap, 'ipaidpuser', dn, + entry_attrs, update=False) + ++ # Check and warn if we're out of local idrange ++ # Skip dynamically assigned uid, old clients say 999 ++ uidnumber = entry_attrs.get('uidnumber') ++ if ( ++ uidnumber != -1 ++ and uidnumber != 999 ++ and not is_in_local_idrange(uidnumber) ++ ): ++ self.add_message(messages.UidNumberOutOfLocalIDRange( ++ user=entry_attrs.get('uid'), uidnumber=uidnumber)) ++ + def post_common_callback(self, ldap, dn, entry_attrs, *keys, **options): + assert isinstance(dn, DN) + self.obj.convert_usercertificate_post(entry_attrs, **options) +diff --git a/ipatests/test_xmlrpc/test_stageuser_plugin.py b/ipatests/test_xmlrpc/test_stageuser_plugin.py +index 6ed593fbf24dd2e8ce087625b9cb4c21c9a3c145..dc4940a9983a410640d93efb1185ed4d394a8c2c 100644 +--- a/ipatests/test_xmlrpc/test_stageuser_plugin.py ++++ b/ipatests/test_xmlrpc/test_stageuser_plugin.py +@@ -80,9 +80,7 @@ options_def = OrderedDict([ + ('car license', {u'carlicense': u'abc1234'}), + ('SSH key', {u'ipasshpubkey': sshpubkey}), + ('manager', {u'manager': u'auser1'}), +- ('user ID number', {u'uidnumber': uid}), + ('group ID number', {u'gidnumber': gid}), +- ('UID and GID numbers', {u'uidnumber': uid, u'gidnumber': gid}), + ('password', {u'userpassword': u'Secret123'}), + ('random password', {u'random': True}), + ]) +@@ -90,6 +88,13 @@ options_def = OrderedDict([ + options_ok = list(options_def.values()) + options_ids = list(options_def.keys()) + ++warn_options_def = OrderedDict([ ++ ('user ID number', {u'uidnumber': uid}), ++ ('UID and GID numbers', {u'uidnumber': uid, u'gidnumber': gid}), ++]) ++ ++warn_options_ok = list(warn_options_def.values()) ++warn_options_ids = list(warn_options_def.keys()) + + @pytest.fixture(scope='class') + def stageduser(request, xmlrpc_setup): +@@ -108,6 +113,12 @@ def stageduser2(request, xmlrpc_setup): + return tracker.make_fixture_activate(request) + + ++@pytest.fixture(scope='class', params=warn_options_ok, ids=warn_options_ids) ++def warn_stageduser(request, xmlrpc_setup): ++ tracker = StageUserTracker(u'warnuser', u'staged', u'user', **request.param) ++ return tracker.make_fixture_activate(request) ++ ++ + @pytest.fixture(scope='class') + def user_activated(request, xmlrpc_setup): + tracker = UserTracker(u'suser2', u'staged', u'user') +@@ -273,6 +284,36 @@ class TestStagedUser(XMLRPC_test): + + user_activated.delete() + ++ def test_warn_create_with_attr(self, warn_stageduser, user, user_activated): ++ """ Tests creating a user with various valid attributes that throw ++ a warning listed in 'warn_options_ok' list""" ++ # create staged user with specified parameters ++ user.ensure_exists() # necessary for manager test ++ warn_stageduser.ensure_missing() ++ command = warn_stageduser.make_create_command() ++ result = command() ++ warn_stageduser.track_create() ++ warn_stageduser.check_create_with_warning(result, (13034,)) ++ ++ # activate user, verify that specified values were preserved ++ # after activation ++ user_activated.ensure_missing() ++ user_activated = UserTracker( ++ warn_stageduser.uid, warn_stageduser.givenname, ++ warn_stageduser.sn, **warn_stageduser.kwargs) ++ user_activated.create_from_staged(warn_stageduser) ++ command = warn_stageduser.make_activate_command() ++ result = command() ++ user_activated.check_activate(result) ++ ++ # verify the staged user does not exist after activation ++ command = warn_stageduser.make_retrieve_command() ++ with raises_exact(errors.NotFound( ++ reason=u'%s: stage user not found' % warn_stageduser.uid)): ++ command() ++ ++ user_activated.delete() ++ + def test_delete_stageduser(self, stageduser): + stageduser.delete() + +diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py +index c0415cae6eb0389c91b804ab28dc2d9f131930c6..420c80213177dc513e10451c0c53506e879ba93f 100644 +--- a/ipatests/test_xmlrpc/test_user_plugin.py ++++ b/ipatests/test_xmlrpc/test_user_plugin.py +@@ -826,6 +826,49 @@ class TestCreate(XMLRPC_test): + user_idp.check_create(result, ['ipaidpsub']) + user_idp.delete() + ++ def test_out_of_idrange(self): ++ """Test ensuring warning is thrown when uid is out of range""" ++ uidnumber = 2000 ++ testuser = UserTracker( ++ name="testwarning", givenname="test", ++ sn="warning", uidnumber=uidnumber ++ ) ++ testuser.attrs.update( ++ uidnumber=[u'2000'], ++ ) ++ command = testuser.make_create_command() ++ result = command() ++ result_messages = result['messages'] ++ assert len(result_messages) == 1 ++ assert result_messages[0]['type'] == 'warning' ++ assert result_messages[0]['code'] == 13034 ++ testuser.delete() ++ ++ def test_in_idrange(self): ++ """Test ensuring no warning is thrown when uid is in range""" ++ result = api.Command.idrange_find( ++ iparangetype='ipa-local', ++ sizelimit=0, ++ ) ++ ++ assert len(result) >= 1 ++ ipabaseid = int(result['result'][0]['ipabaseid'][0]) ++ ipaidrangesize = int(result['result'][0]['ipaidrangesize'][0]) ++ ++ # Take the last valid id, as we're not sure which has not yet been used ++ valid_id = ipabaseid + ipaidrangesize - 1 ++ testuser = UserTracker( ++ name="testnowarning", givenname="test", ++ sn="nowarning", uidnumber=valid_id ++ ) ++ testuser.attrs.update( ++ uidnumber=[str(valid_id)], ++ ) ++ command = testuser.make_create_command() ++ result = command() ++ assert "messages" not in result ++ testuser.delete() ++ + + @pytest.mark.tier1 + class TestUserWithGroup(XMLRPC_test): +diff --git a/ipatests/test_xmlrpc/tracker/stageuser_plugin.py b/ipatests/test_xmlrpc/tracker/stageuser_plugin.py +index 17744a98e9d4a8c5939e9c912b348689674becd9..93157ba3a44362c56a955c3d52d0d18678a9bc5d 100644 +--- a/ipatests/test_xmlrpc/tracker/stageuser_plugin.py ++++ b/ipatests/test_xmlrpc/tracker/stageuser_plugin.py +@@ -3,6 +3,7 @@ + # + + import six ++import copy + + from ipalib import api, errors + from ipaplatform.constants import constants as platformconstants +@@ -187,6 +188,27 @@ class StageUserTracker(PasskeyMixin, KerberosAliasMixin, Tracker): + result=self.filter_attrs(expected), + ), result) + ++ def check_create_with_warning(self, result, ++ warning_codes=(), extra_keys=()): ++ """ Check 'stageuser-add' command result """ ++ expected = self.filter_attrs(self.create_keys | set(extra_keys)) ++ ++ result = copy.deepcopy(result) ++ assert 'messages' in result ++ assert len(result['messages']) == len(warning_codes) ++ codes = [message['code'] for message in result['messages']] ++ for code in warning_codes: ++ assert code in codes ++ codes.pop(codes.index(code)) ++ ++ del result['messages'] ++ ++ assert_deepequal(dict( ++ value=self.uid, ++ summary=u'Added stage user "%s"' % self.uid, ++ result=self.filter_attrs(expected), ++ ), result) ++ + def check_delete(self, result): + """ Check 'stageuser-del' command result """ + assert_deepequal(dict( +-- +2.49.0 + diff --git a/0109-ipatests-fix-invalid-range-creation-in-test_ipa_idra.patch b/0109-ipatests-fix-invalid-range-creation-in-test_ipa_idra.patch new file mode 100644 index 0000000..26fef47 --- /dev/null +++ b/0109-ipatests-fix-invalid-range-creation-in-test_ipa_idra.patch @@ -0,0 +1,80 @@ +From 0155718308fa58f43f2ec8df240c1df1c929195e Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Mon, 2 Jun 2025 14:47:48 +0200 +Subject: [PATCH] ipatests: fix invalid range creation in + test_ipa_idrange_fix.py + +The test is creating a local ID range without rid-base and +secondary-rid-base in order to test the behavior of ipa-idrange-fix. + +Since the patch for ticket #9779 it is not possible any more to call +ipa idrange-add for local range without these parameters. The test needs +to create the invalid local range using a direct ldapmodify instead. + +Fixes: https://pagure.io/freeipa/issue/9801 +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: David Hanina +--- + .../test_integration/test_ipa_idrange_fix.py | 39 ++++++++++++------- + 1 file changed, 25 insertions(+), 14 deletions(-) + +diff --git a/ipatests/test_integration/test_ipa_idrange_fix.py b/ipatests/test_integration/test_ipa_idrange_fix.py +index 0c915bd0931ed11a3aa86c533ee8748aa8a7ec07..6559818d3b290211ed421b652be7a424a3b51052 100644 +--- a/ipatests/test_integration/test_ipa_idrange_fix.py ++++ b/ipatests/test_integration/test_ipa_idrange_fix.py +@@ -40,13 +40,18 @@ class TestIpaIdrangeFix(IntegrationTest): + + def test_idrange_no_rid_bases(self): + """Test ipa-idrange-fix command with IDrange with no RID bases.""" +- self.master.run_command([ +- "ipa", +- "idrange-add", +- "idrange_no_rid_bases", +- "--base-id", '10000', +- "--range-size", '20000', +- ]) ++ # Use ldapmodify to create the range without rid bases ++ idrange_ldif = ( ++ "dn: cn=idrange_no_rid_bases,cn=ranges,cn=etc,{suffix}\n" ++ "changetype: add\n" ++ "objectclass: top\n" ++ "objectclass: ipaIDrange\n" ++ "objectclass: ipadomainidrange\n" ++ "ipaRangeType: ipa-local\n" ++ "ipaBaseID: 10000\n" ++ "ipaIDRangeSize: 20000\n" ++ ).format(suffix=str(self.master.domain.basedn)) ++ tasks.ldapmodify_dm(self.master, idrange_ldif) + + result = self.master.run_command(["ipa-idrange-fix", "--unattended"]) + expected_text = "RID bases updated for range 'idrange_no_rid_bases'" +@@ -62,13 +67,19 @@ class TestIpaIdrangeFix(IntegrationTest): + previously had a range with RID bases reversed - secondary lower than + primary. It is a valid configuration, so we should fix no-RID range. + """ +- self.master.run_command([ +- "ipa", +- "idrange-add", +- "idrange_no_rid_bases", +- "--base-id", '10000', +- "--range-size", '20000', +- ]) ++ # Use ldapmodify to create the range without rid bases ++ idrange_ldif = ( ++ "dn: cn=idrange_no_rid_bases,cn=ranges,cn=etc,{suffix}\n" ++ "changetype: add\n" ++ "objectclass: top\n" ++ "objectclass: ipaIDrange\n" ++ "objectclass: ipadomainidrange\n" ++ "ipaRangeType: ipa-local\n" ++ "ipaBaseID: 10000\n" ++ "ipaIDRangeSize: 20000\n" ++ ).format(suffix=str(self.master.domain.basedn)) ++ tasks.ldapmodify_dm(self.master, idrange_ldif) ++ + self.master.run_command([ + "ipa", + "idrange-add", +-- +2.49.0 + diff --git a/0110-ipatests-fix-xfail-annotation-for-test_ipa_healthche.patch b/0110-ipatests-fix-xfail-annotation-for-test_ipa_healthche.patch new file mode 100644 index 0000000..b725ea8 --- /dev/null +++ b/0110-ipatests-fix-xfail-annotation-for-test_ipa_healthche.patch @@ -0,0 +1,43 @@ +From 982569fcb3d23d6e6578e5efbaafb99c32542a8d Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Tue, 20 May 2025 13:58:54 +0200 +Subject: [PATCH] ipatests: fix xfail annotation for + test_ipa_healthcheck_fips_enabled + +The test is expected to fail +- on rhel 10.0 with ipa-healthcheck < 0.17 + +On Fedora 41, the command fips-mode-check is still available. +On Fedora 42, it has been removed but ipa-healthcheck 0.18 has +been adapted. + +Fixes: https://pagure.io/freeipa/issue/9791 +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: David Hanina +Reviewed-By: Rob Crittenden +--- + ipatests/test_integration/test_ipahealthcheck.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py +index 13fcc3d43545590e025598fcc9c9ee40f62dae76..3dcc22411347b98853ef8b9551cc33f05ff13195 100644 +--- a/ipatests/test_integration/test_ipahealthcheck.py ++++ b/ipatests/test_integration/test_ipahealthcheck.py +@@ -375,11 +375,11 @@ class TestIpaHealthCheck(IntegrationTest): + if ( + parse_version(healthcheck_version) < parse_version("0.17") + and osinfo.id == 'rhel' +- and osinfo.version_number >= (10,0) ++ and osinfo.version_number == (10,0) + ): + # Patch: https://github.com/freeipa/freeipa-healthcheck/pull/349 +- pytest.xfail("Patch is unavailable for RHEL 10.0 and above" +- "freeipa-healtheck version 0.16 or less") ++ pytest.skip("Patch is unavailable for RHEL 10.0 " ++ "freeipa-healthcheck version 0.16 or less") + + returncode, check = run_healthcheck(self.master, + source="ipahealthcheck.meta.core", +-- +2.49.0 + diff --git a/freeipa.spec b/freeipa.spec index 9009168..050257b 100644 --- a/freeipa.spec +++ b/freeipa.spec @@ -85,7 +85,13 @@ # Fix for TLS 1.3 PHA, RHBZ#1775158 %global httpd_version 2.4.37-21 -%global bind_version 32:9.18.33-2 + +# DNSSEC support with OpenSSL provider API in RHEL 10 +%if 0%{?rhel} < 10 +%global bind_version 9.11.20-6 +%else +%global bind_version 9.18.33-3 +%endif # support for passkey %global sssd_version 2.10.0 @@ -127,9 +133,12 @@ # Fix for TLS 1.3 PHA, RHBZ#1775146 %global httpd_version 2.4.41-9 -# Fix for RHBZ#2117342 -%global bind_version 32:9.18.7-1 - +%if 0%{?fedora} < 42 +%global bind_version 32:9.18.33-1 +%else +# BIND version with backport of DNSSEC support over OpenSSL provider API +%global bind_version 32:9.18.35-2 +%endif # Don't use Fedora's Python dependency generator on Fedora 30/rawhide yet. # Some packages don't provide new dist aliases. # https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/ @@ -207,7 +216,7 @@ Name: %{package_name} Version: %{IPA_VERSION} -Release: 17%{?rc_version:.%rc_version}%{?dist} +Release: 18%{?rc_version:.%rc_version}%{?dist} Summary: The Identity, Policy and Audit system License: GPL-3.0-or-later @@ -269,7 +278,6 @@ Patch0028: 0028-ipa-migrate-should-migrate-dns-forward-zones.patch Patch0029: 0029-vault-handle-pyca-InternalError-exception-for-PKCS-1.patch Patch0030: 0030-ipatests-Tests-for-ipa-migrate-tool.patch Patch0031: 0031-Fix-Organization-field-in-Okta-not-required.patch -Patch0032: 0032-Use-OpenSSL-provider-with-BIND-for-Fedora-41-and-RHE.patch Patch0033: 0033-selinux-allow-Cockpit-to-use-HTTP-keytab-on-IPA-serv.patch Patch0034: 0034-Minimal-test-for-Cockpit-integration-on-IPA-master.patch Patch0035: 0035-ipatests-install-master-with-allow-zone-overlap.patch @@ -327,6 +335,27 @@ Patch0086: 0086-ipatests-Fix-for-ipa-healthcheck-test-in-FIPS-Mode.patch Patch0087: 0087-ipa-sidgen-fix-memory-leak-in-ipa_sidgen_add_post_op.patch Patch0088: 0088-Add-a-check-into-ipa-cert-fix-tool-to-avoid-updating.patch Patch0089: 0089-Test-fix-for-the-update.patch +Patch0090: 0090-ipa-migrate-remove-replication-state-information.patch +Patch0091: 0091-ipa-migrate-do-not-process-AD-entgries-in-staging-mo.patch +Patch0092: 0092-ipa-migrate-improve-suffix-replacement.patch +Patch0093: 0093-kdb-keep-ipadb_get_connection-from-succeeding-with-n.patch +Patch0094: 0094-Use-OpenSSL-provider-with-BIND-for-Fedora-42-and-RHE.patch +Patch0095: 0095-DNS-detect-when-OpenSSL-engine-should-be-removed-on-.patch +Patch0096: 0096-ipa-dnskeysyncd-use-systemd-tmpfiles-to-handle-token.patch +Patch0097: 0097-freeipa.spec.in-update-BIND-related-dependencies.patch +Patch0098: 0098-freeipa.spec.in-do-not-recommend-encrypted-DNS-on-pr.patch +Patch0099: 0099-dns-install-fix-selinux-avc-relabelto.patch +Patch0100: 0100-ipatests-test_manual_renewal_master_transfer-must-wa.patch +Patch0101: 0101-Require-baserid-and-secondarybaserid.patch +Patch0102: 0102-ipa-config-mod-fix-internalerror-when-setting-an-emp.patch +Patch0103: 0103-ipatests-Test-to-check-dot-forwarders-are-added-to-u.patch +Patch0104: 0104-Fix-some-issues-identified-by-a-static-analyzer.patch +Patch0105: 0105-ipatests-Ignore-run-log-journal-in-test_uninstallati.patch +Patch0106: 0106-ipatests-Tests-for-krbLastSuccessfulAuth-warning.patch +Patch0107: 0107-ipatests-ipahealthcheck-warns-for-user-provided-cert.patch +Patch0108: 0108-Warn-when-UID-is-out-of-local-ID-ranges.patch +Patch0109: 0109-ipatests-fix-invalid-range-creation-in-test_ipa_idra.patch +Patch0110: 0110-ipatests-fix-xfail-annotation-for-test_ipa_healthche.patch Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch %endif %endif @@ -680,7 +709,12 @@ If you are installing an IPA server, you need to install this package. Summary: IPA integrated DNS server with support for automatic DNSSEC signing BuildArch: noarch Requires: %{name}-server = %{version}-%{release} -Requires: bind-dyndb-ldap >= 11.11-1 +# Both Fedora 42+ and RHEL support newer bind-dyndb-ldap 11.11 +%if 0%{?fedora} < 42 +Requires: bind-dyndb-ldap >= 11.10-33 +%else +Requires: bind-dyndb-ldap >= 11.11 +%endif Requires: bind >= %{bind_version} Requires: bind-utils >= %{bind_version} # bind-dnssec-utils is required by the OpenDNSSec integration @@ -691,7 +725,9 @@ Requires: %{openssl_pkcs11_name} >= %{openssl_pkcs11_version} # See https://bugzilla.redhat.com/show_bug.cgi?id=1825812 # RHEL 8.3+ and Fedora 32+ have 2.1 Requires: opendnssec >= 2.1.6-5 +%if 0%{?fedora} >= 42 || 0%{?rhel} > 9 Recommends: %{name}-server-encrypted-dns +%endif %{?systemd_requires} Provides: %{alt_name}-server-dns = %{version} @@ -709,6 +745,8 @@ Integrated DNS server is BIND 9. OpenDNSSEC provides key management. %package server-encrypted-dns Summary: support for encrypted DNS in IPA integrated DNS server Requires: %{name}-client-encrypted-dns +# Will need newer bind-dyndb-ldap to allow use of OpenSSL provider API +Requires: bind-dyndb-ldap >= 11.11 %description server-encrypted-dns Provides support for enabling DNS over TLS in the IPA integrated DNS @@ -1797,6 +1835,7 @@ fi %{_libexecdir}/ipa/ipa-ods-exporter %{_sbindir}/ipa-dns-install %{_mandir}/man1/ipa-dns-install.1* +%{_usr}/share/ipa/ipa-dnssec.conf %attr(644,root,root) %{_unitdir}/ipa-dnskeysyncd.service %attr(644,root,root) %{_unitdir}/ipa-ods-exporter.socket %attr(644,root,root) %{_unitdir}/ipa-ods-exporter.service @@ -1978,6 +2017,16 @@ fi %endif %changelog +* Wed Jun 04 2025 Florence Blanc-Renaud - 4.12.2-18 +- Resolves: RHEL-89979 Support OpenSSL provider API +- Resolves: RHEL-25007 [RFE] Give warning when adding user with UID out of any ID range +- Resolves: RHEL-93484 Unable to modify IPA config; --ipaconfigstring="" causes internal error +- Resolves: RHEL-89834 Include latest fixes in python3-ipatests package +- Resolves: RHEL-88833 kdb: ipadb_get_connection() succeeds but returns null LDAP context +- Resolves: RHEL-79072 ipa idrange-add --help should be more clear about required options +- Resolves: RHEL-68803 ipa-migrate with LDIF file from backup of remote server, fails with error 'change collided with another change' +- Resolves: RHEL-30825 IDM - When creating an ID range, should require a RID + * Tue Apr 29 2025 Florence Blanc-Renaud - 4.12.2-17 - Resolves: RHEL-88043 Server installation: dot-forwarder not added as a forwarder - Resolves: RHEL-86481 Include latest fixes in python3-ipatests package