diff --git a/SOURCES/updates-add-ACIs-for-RBCD-self-management.patch b/SOURCES/0028-updates-add-ACIs-for-RBCD-self-management.patch similarity index 100% rename from SOURCES/updates-add-ACIs-for-RBCD-self-management.patch rename to SOURCES/0028-updates-add-ACIs-for-RBCD-self-management.patch diff --git a/SOURCES/0029-ipatests-restart-ipa-services-after-moving-date.patch b/SOURCES/0029-ipatests-restart-ipa-services-after-moving-date.patch new file mode 100644 index 0000000..8cffeba --- /dev/null +++ b/SOURCES/0029-ipatests-restart-ipa-services-after-moving-date.patch @@ -0,0 +1,33 @@ +From 2bbfd1454fc69c5975826d1a3f39b301d135abb5 Mon Sep 17 00:00:00 2001 +From: Mohammad Rizwan +Date: Sep 20 2023 06:05:00 +0000 +Subject: ipatests: restart ipa services after moving date + + +When system date is moved into future, it have unprecedented +behavior i.e CA becomes irresponsive or unexpected certificcate +state. Hence restart the ipa service after moving the date to +gracefully serve the request. + +Fixes: https://pagure.io/freeipa/issue/9379 + +Signed-off-by: Mohammad Rizwan +Reviewed-By: Florence Blanc-Renaud + +--- + +diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py +index 77076e7..ec9456e 100644 +--- a/ipatests/test_integration/test_ipa_cert_fix.py ++++ b/ipatests/test_integration/test_ipa_cert_fix.py +@@ -408,6 +408,9 @@ class TestCertFixReplica(IntegrationTest): + # move system date to expire certs + for host in self.master, self.replicas[0]: + tasks.move_date(host, 'stop', '+3years+1days') ++ host.run_command( ++ ['ipactl', 'restart', '--ignore-service-failures'] ++ ) + + yield + + diff --git a/SOURCES/0030-ipatests-ignore-nsslapd-accesslog-logbuffering-WARN-in-healthcheck.patch b/SOURCES/0030-ipatests-ignore-nsslapd-accesslog-logbuffering-WARN-in-healthcheck.patch new file mode 100644 index 0000000..0387be0 --- /dev/null +++ b/SOURCES/0030-ipatests-ignore-nsslapd-accesslog-logbuffering-WARN-in-healthcheck.patch @@ -0,0 +1,128 @@ +From 9bc582a2d78fd3ff9e70fa927b87ab06dcb7c9ae Mon Sep 17 00:00:00 2001 +From: Rob Crittenden +Date: Nov 17 2023 09:08:44 +0000 +Subject: ipatests: ignore nsslapd-accesslog-logbuffering WARN in healthcheck + + +Log buffering is disabled in the integration tests so we can have all +the logs at the end. This is causing a warning to show in the 389-ds +checks and causing tests to fail that expect all SUCCESS. + +Add an exclude for this specific key so tests will pass again. + +We may eventually want a more sophisiticated mechanism to handle +excludes, or updating the config in general, but this is fine for now. + +Fixes: https://pagure.io/freeipa/issue/9400 + +Signed-off-by: Rob Crittenden +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Michal Polovka + +--- + +diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py +index 5d79f2b..278f75a 100644 +--- a/ipatests/test_integration/test_ipahealthcheck.py ++++ b/ipatests/test_integration/test_ipahealthcheck.py +@@ -10,6 +10,7 @@ from __future__ import absolute_import + from configparser import RawConfigParser, NoOptionError + from datetime import datetime, timedelta, timezone + UTC = timezone.utc ++import io + import json + import os + import re +@@ -209,6 +210,28 @@ def run_healthcheck(host, source=None, check=None, output_type="json", + return result.returncode, data + + ++def set_excludes(host, option, value, ++ config_file='/etc/ipahealthcheck/ipahealthcheck.conf'): ++ """Mark checks that should be excluded from the results ++ ++ This will set in the [excludes] section on host: ++ option=value ++ """ ++ EXCLUDES = "excludes" ++ ++ conf = host.get_file_contents(config_file, encoding='utf-8') ++ cfg = RawConfigParser() ++ cfg.read_string(conf) ++ if not cfg.has_section(EXCLUDES): ++ cfg.add_section(EXCLUDES) ++ if not cfg.has_option(EXCLUDES, option): ++ cfg.set(EXCLUDES, option, value) ++ out = io.StringIO() ++ cfg.write(out) ++ out.seek(0) ++ host.put_file_contents(config_file, out.read()) ++ ++ + @pytest.fixture + def restart_service(): + """Shut down and restart a service as a fixture""" +@@ -266,6 +289,7 @@ class TestIpaHealthCheck(IntegrationTest): + setup_dns=True, + extra_args=['--no-dnssec-validation'] + ) ++ set_excludes(cls.master, "key", "DSCLE0004") + + def test_ipa_healthcheck_install_on_master(self): + """ +@@ -558,6 +582,7 @@ class TestIpaHealthCheck(IntegrationTest): + setup_dns=True, + extra_args=['--no-dnssec-validation'] + ) ++ set_excludes(self.replicas[0], "key", "DSCLE0004") + + # Init a user on replica to assign a DNA range + tasks.kinit_admin(self.replicas[0]) +@@ -698,6 +723,7 @@ class TestIpaHealthCheck(IntegrationTest): + 'output_type=human' + ]) + ) ++ set_excludes(self.master, "key", "DSCLE0004", config_file) + returncode, output = run_healthcheck( + self.master, failures_only=True, config=config_file + ) +@@ -713,6 +739,7 @@ class TestIpaHealthCheck(IntegrationTest): + 'output_file=%s' % HC_LOG, + ]) + ) ++ set_excludes(self.master, "key", "DSCLE0004") + returncode, _unused = run_healthcheck( + self.master, config=config_file + ) +@@ -2408,6 +2435,7 @@ class TestIpaHealthCLI(IntegrationTest): + cls.master, setup_dns=True, extra_args=['--no-dnssec-validation'] + ) + tasks.install_packages(cls.master, HEALTHCHECK_PKG) ++ set_excludes(cls.master, "key", "DSCLE0004") + + def test_indent(self): + """ +diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py +index d477c3a..b71f2d5 100644 +--- a/ipatests/test_integration/test_replica_promotion.py ++++ b/ipatests/test_integration/test_replica_promotion.py +@@ -13,7 +13,7 @@ import pytest + + from ipatests.test_integration.base import IntegrationTest + from ipatests.test_integration.test_ipahealthcheck import ( +- run_healthcheck, HEALTHCHECK_PKG ++ run_healthcheck, set_excludes, HEALTHCHECK_PKG + ) + from ipatests.pytest_ipa.integration import tasks + from ipatests.pytest_ipa.integration.tasks import ( +@@ -983,6 +983,9 @@ class TestHiddenReplicaPromotion(IntegrationTest): + # manually install KRA to verify that hidden state is synced + tasks.install_kra(cls.replicas[0]) + ++ set_excludes(cls.master, "key", "DSCLE0004") ++ set_excludes(cls.replicas[0], "key", "DSCLE0004") ++ + def _check_dnsrecords(self, hosts_expected, hosts_unexpected=()): + domain = DNSName(self.master.domain.name).make_absolute() + rset = [ + diff --git a/SOURCES/0031-ipatests-Skip-ds_encryption-tests-on-RHEL9-SUT.patch b/SOURCES/0031-ipatests-Skip-ds_encryption-tests-on-RHEL9-SUT.patch new file mode 100644 index 0000000..a3edd8f --- /dev/null +++ b/SOURCES/0031-ipatests-Skip-ds_encryption-tests-on-RHEL9-SUT.patch @@ -0,0 +1,44 @@ +From 96dd277ad960f57c36c38820a7b0542c97f9e67d Mon Sep 17 00:00:00 2001 +From: Sudhir Menon +Date: Jan 11 2024 22:26:57 +0000 +Subject: ipatests: Skip ds_encryption tests on RHEL9 SUT. + + +test_ipahealthcheck_ds_encryption tests are failing +in RHEL9 SUT because in this test tls protocol version +is set to TLS1.0 using the below command, but its +reset to TLS1.2 causing the test to fail. + +'dsconf', 'slapd-TESTREALM-TEST', 'security', 'set', '--tls-protocol-min=TLS1.0' + +Hence the test is skipped to be run on RHEL9.0 SUT. + +Signed-off-by: Sudhir Menon +Reviewed-By: Florence Blanc-Renaud + +--- + +diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py +index 785e9ab..40c8489 100644 +--- a/ipatests/test_integration/test_ipahealthcheck.py ++++ b/ipatests/test_integration/test_ipahealthcheck.py +@@ -158,7 +158,6 @@ TOMCAT_CONFIG_FILES = ( + paths.CA_CS_CFG_PATH, + ) + +- + def run_healthcheck(host, source=None, check=None, output_type="json", + failures_only=False, config=None): + """ +@@ -1262,6 +1261,10 @@ class TestIpaHealthCheck(IntegrationTest): + ) + self.master.run_command(cmd) + ++ @pytest.mark.skipif((osinfo.id == 'rhel' ++ and osinfo.version_number >= (9,0)), ++ reason=" TLS versions below 1.2 are not " ++ "supported anymore in RHEL9.0 and above.") + def test_ipahealthcheck_ds_encryption(self, modify_tls): + """ + This testcase modifies the default TLS version of + diff --git a/SOURCES/0032-adtrustinstance-make-sure-NetBIOS-name-defaults-are-set-properly.patch b/SOURCES/0032-adtrustinstance-make-sure-NetBIOS-name-defaults-are-set-properly.patch new file mode 100644 index 0000000..82de046 --- /dev/null +++ b/SOURCES/0032-adtrustinstance-make-sure-NetBIOS-name-defaults-are-set-properly.patch @@ -0,0 +1,32 @@ +From 3baa30ad3f6ee563089839a5ef56d5ac6eb43959 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Jan 18 2024 09:05:30 +0000 +Subject: adtrustinstance: make sure NetBIOS name defaults are set properly + + +Some tools may pass None as NetBIOS name if not put explicitly by a +user. This meant to use default NetBIOS name generator based on the +domain (realm) name. However, this wasn't done properly, so None is +passed later to python-ldap and it rejects such LDAP entry. + +Fixes: https://pagure.io/freeipa/issue/9514 + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud + +--- + +diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py +index d55ba84..2ff68df 100644 +--- a/ipaserver/install/adtrustinstance.py ++++ b/ipaserver/install/adtrustinstance.py +@@ -189,6 +189,8 @@ class ADTRUSTInstance(service.Service): + self.fqdn = self.fqdn or api.env.host + self.host_netbios_name = make_netbios_name(self.fqdn) + self.realm = self.realm or api.env.realm ++ if not self.netbios_name: ++ self.netbios_name = make_netbios_name(self.realm) + + self.suffix = ipautil.realm_to_suffix(self.realm) + self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \ + diff --git a/SOURCES/0033-ipatests-wait-for-replica-update-in-test_dns_locations.patch b/SOURCES/0033-ipatests-wait-for-replica-update-in-test_dns_locations.patch new file mode 100644 index 0000000..f596fb0 --- /dev/null +++ b/SOURCES/0033-ipatests-wait-for-replica-update-in-test_dns_locations.patch @@ -0,0 +1,40 @@ +From 257b2b470b4e3f83a0cbc476d54dc74ddf2cf311 Mon Sep 17 00:00:00 2001 +From: Masahiro Matsuya +Date: Jan 24 2024 16:42:45 +0000 +Subject: ipatests: wait for replica update in test_dns_locations + + +test_ipa_ca_records and test_adtrust_system_records can fail with +NXDOMAIN, because it doesn't wait enough for the update on replica. +It can be resolved by waiting for the update with wait_for_replication. + +Fixes: https://pagure.io/freeipa/issue/9504 +Reviewed-By: Florence Blanc-Renaud + +--- + +diff --git a/ipatests/test_integration/test_dns_locations.py b/ipatests/test_integration/test_dns_locations.py +index 44900af..89a3108 100644 +--- a/ipatests/test_integration/test_dns_locations.py ++++ b/ipatests/test_integration/test_dns_locations.py +@@ -534,6 +534,9 @@ class TestDNSLocations(IntegrationTest): + + expected_servers = (self.master.ip, self.replicas[1].ip) + ++ ldap = self.master.ldap_connect() ++ tasks.wait_for_replication(ldap) ++ + for ip in (self.master.ip, self.replicas[0].ip, self.replicas[1].ip): + self._test_A_rec_against_server(ip, self.domain, expected_servers) + +@@ -557,6 +560,9 @@ class TestDNSLocations(IntegrationTest): + (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)), + ) + ++ ldap = self.master.ldap_connect() ++ tasks.wait_for_replication(ldap) ++ + for ip in (self.master.ip, self.replicas[0].ip, self.replicas[1].ip): + self._test_SRV_rec_against_server( + ip, self.domain, expected_servers, + diff --git a/SOURCES/0034-ipapython-Clean-up-krb5_error.patch b/SOURCES/0034-ipapython-Clean-up-krb5_error.patch new file mode 100644 index 0000000..6bf24ca --- /dev/null +++ b/SOURCES/0034-ipapython-Clean-up-krb5_error.patch @@ -0,0 +1,142 @@ +From 2e649b26d1d8ec988ec64477af73cd1f033731fd Mon Sep 17 00:00:00 2001 +From: Stanislav Levin +Date: Jan 30 2024 15:07:56 +0000 +Subject: ipapython: Clean up krb5_error + + +`krb5_error` has different definition in MIT krb. +https://web.mit.edu/kerberos/krb5-latest/doc/appdev/refs/types/krb5_error.html + +> Error message structure. +> +> Declaration: +> typedef struct _krb5_error krb5_error + +While `krb5_error_code` +https://web.mit.edu/kerberos/www/krb5-latest/doc/appdev/refs/types/krb5_error_code.html#c.krb5_error_code + +> krb5_error_code +> Used to convey an operation status. +> +> The value 0 indicates success; any other values are com_err codes. Use krb5_get_error_message() to obtain a string describing the error. +> +> Declaration +> typedef krb5_int32 krb5_error_code + +And this is what was actually used. + +To prevent confusion of types `krb5_error` was replaced with +`krb5_error_code`. + +Fixes: https://pagure.io/freeipa/issue/9519 +Signed-off-by: Stanislav Levin +Reviewed-By: Alexander Bokovoy + +--- + +diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py +index c43ef7d..371cf15 100644 +--- a/ipapython/session_storage.py ++++ b/ipapython/session_storage.py +@@ -111,7 +111,7 @@ class KRB5Error(Exception): + + + def krb5_errcheck(result, func, arguments): +- """Error checker for krb5_error return value""" ++ """Error checker for krb5_error_code return value""" + if result != 0: + raise KRB5Error(result, func.__name__, arguments) + +@@ -119,14 +119,13 @@ def krb5_errcheck(result, func, arguments): + krb5_context = ctypes.POINTER(_krb5_context) + krb5_ccache = ctypes.POINTER(_krb5_ccache) + krb5_data_p = ctypes.POINTER(_krb5_data) +-krb5_error = ctypes.c_int32 + krb5_creds = _krb5_creds + krb5_pointer = ctypes.c_void_p + krb5_cc_cursor = krb5_pointer + + krb5_init_context = LIBKRB5.krb5_init_context + krb5_init_context.argtypes = (ctypes.POINTER(krb5_context), ) +-krb5_init_context.restype = krb5_error ++krb5_init_context.restype = krb5_error_code + krb5_init_context.errcheck = krb5_errcheck + + krb5_free_context = LIBKRB5.krb5_free_context +@@ -143,30 +142,30 @@ krb5_free_data_contents.restype = None + + krb5_cc_default = LIBKRB5.krb5_cc_default + krb5_cc_default.argtypes = (krb5_context, ctypes.POINTER(krb5_ccache), ) +-krb5_cc_default.restype = krb5_error ++krb5_cc_default.restype = krb5_error_code + krb5_cc_default.errcheck = krb5_errcheck + + krb5_cc_close = LIBKRB5.krb5_cc_close + krb5_cc_close.argtypes = (krb5_context, krb5_ccache, ) +-krb5_cc_close.restype = krb5_error ++krb5_cc_close.restype = krb5_error_code + krb5_cc_close.errcheck = krb5_errcheck + + krb5_parse_name = LIBKRB5.krb5_parse_name + krb5_parse_name.argtypes = (krb5_context, ctypes.c_char_p, + ctypes.POINTER(krb5_principal), ) +-krb5_parse_name.restype = krb5_error ++krb5_parse_name.restype = krb5_error_code + krb5_parse_name.errcheck = krb5_errcheck + + krb5_cc_set_config = LIBKRB5.krb5_cc_set_config + krb5_cc_set_config.argtypes = (krb5_context, krb5_ccache, krb5_principal, + ctypes.c_char_p, krb5_data_p, ) +-krb5_cc_set_config.restype = krb5_error ++krb5_cc_set_config.restype = krb5_error_code + krb5_cc_set_config.errcheck = krb5_errcheck + + krb5_cc_get_principal = LIBKRB5.krb5_cc_get_principal + krb5_cc_get_principal.argtypes = (krb5_context, krb5_ccache, + ctypes.POINTER(krb5_principal), ) +-krb5_cc_get_principal.restype = krb5_error ++krb5_cc_get_principal.restype = krb5_error_code + krb5_cc_get_principal.errcheck = krb5_errcheck + + # krb5_build_principal is a variadic function but that can't be expressed +@@ -177,26 +176,26 @@ krb5_build_principal.argtypes = (krb5_context, ctypes.POINTER(krb5_principal), + ctypes.c_uint, ctypes.c_char_p, + ctypes.c_char_p, ctypes.c_char_p, + ctypes.c_char_p, ctypes.c_char_p, ) +-krb5_build_principal.restype = krb5_error ++krb5_build_principal.restype = krb5_error_code + krb5_build_principal.errcheck = krb5_errcheck + + krb5_cc_start_seq_get = LIBKRB5.krb5_cc_start_seq_get + krb5_cc_start_seq_get.argtypes = (krb5_context, krb5_ccache, + ctypes.POINTER(krb5_cc_cursor), ) +-krb5_cc_start_seq_get.restype = krb5_error ++krb5_cc_start_seq_get.restype = krb5_error_code + krb5_cc_start_seq_get.errcheck = krb5_errcheck + + krb5_cc_next_cred = LIBKRB5.krb5_cc_next_cred + krb5_cc_next_cred.argtypes = (krb5_context, krb5_ccache, + ctypes.POINTER(krb5_cc_cursor), + ctypes.POINTER(krb5_creds), ) +-krb5_cc_next_cred.restype = krb5_error ++krb5_cc_next_cred.restype = krb5_error_code + krb5_cc_next_cred.errcheck = krb5_errcheck + + krb5_cc_end_seq_get = LIBKRB5.krb5_cc_end_seq_get + krb5_cc_end_seq_get.argtypes = (krb5_context, krb5_ccache, + ctypes.POINTER(krb5_cc_cursor), ) +-krb5_cc_end_seq_get.restype = krb5_error ++krb5_cc_end_seq_get.restype = krb5_error_code + krb5_cc_end_seq_get.errcheck = krb5_errcheck + + krb5_free_cred_contents = LIBKRB5.krb5_free_cred_contents +@@ -212,7 +211,7 @@ krb5_principal_compare.restype = krb5_boolean + krb5_unparse_name = LIBKRB5.krb5_unparse_name + krb5_unparse_name.argtypes = (krb5_context, krb5_principal, + ctypes.POINTER(ctypes.c_char_p), ) +-krb5_unparse_name.restype = krb5_error ++krb5_unparse_name.restype = krb5_error_code + krb5_unparse_name.errcheck = krb5_errcheck + + krb5_free_unparsed_name = LIBKRB5.krb5_free_unparsed_name + diff --git a/SOURCES/0035-ipapython-Correct-return-type-of-krb5_free_cred_contents.patch b/SOURCES/0035-ipapython-Correct-return-type-of-krb5_free_cred_contents.patch new file mode 100644 index 0000000..d3b1da1 --- /dev/null +++ b/SOURCES/0035-ipapython-Correct-return-type-of-krb5_free_cred_contents.patch @@ -0,0 +1,45 @@ +From 59f010774d13ea6a0148235db2ff05a3f3c93c7b Mon Sep 17 00:00:00 2001 +From: Stanislav Levin +Date: Jan 30 2024 15:07:56 +0000 +Subject: ipapython: Correct return type of krb5_free_cred_contents + + +According to https://web.mit.edu/kerberos/krb5-latest/doc/appdev/refs/api/krb5_free_cred_contents.html + +> krb5_free_cred_contents - Free the contents of a krb5_creds structure. +> +> void krb5_free_cred_contents(krb5_context context, krb5_creds * val) +> param: +> [in] context - Library context +> +> [in] val - Credential structure to free contents of +> +> This function frees the contents of val , but not the structure itself. + +https://github.com/krb5/krb5/blob/5b00197227231943bd2305328c8260dd0b0dbcf0/src/lib/krb5/krb/kfree.c#L166 + +This leads to undefined behavior and `krb5_free_cred_contents` can +raise KRB5Error (because of garbage data) while actually its foreign +function doesn't. + +Fixes: https://pagure.io/freeipa/issue/9519 +Signed-off-by: Stanislav Levin +Reviewed-By: Alexander Bokovoy + +--- + +diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py +index 371cf15..dc36f54 100644 +--- a/ipapython/session_storage.py ++++ b/ipapython/session_storage.py +@@ -200,8 +200,7 @@ krb5_cc_end_seq_get.errcheck = krb5_errcheck + + krb5_free_cred_contents = LIBKRB5.krb5_free_cred_contents + krb5_free_cred_contents.argtypes = (krb5_context, ctypes.POINTER(krb5_creds)) +-krb5_free_cred_contents.restype = krb5_error +-krb5_free_cred_contents.errcheck = krb5_errcheck ++krb5_free_cred_contents.restype = None + + krb5_principal_compare = LIBKRB5.krb5_principal_compare + krb5_principal_compare.argtypes = (krb5_context, krb5_principal, + diff --git a/SOURCES/0036-ipapython-Propagate-KRB5Error-exceptions-on-iterating-ccache.patch b/SOURCES/0036-ipapython-Propagate-KRB5Error-exceptions-on-iterating-ccache.patch new file mode 100644 index 0000000..5d98aaa --- /dev/null +++ b/SOURCES/0036-ipapython-Propagate-KRB5Error-exceptions-on-iterating-ccache.patch @@ -0,0 +1,51 @@ +From e69d98add55f25641459fc1dfb973260e85f9b95 Mon Sep 17 00:00:00 2001 +From: Stanislav Levin +Date: Jan 30 2024 15:07:56 +0000 +Subject: ipapython: Propagate KRB5Error exceptions on iterating ccache + + +`ipapython.session_storage.get_data` iterates over +credentials in a credential cache till `krb5_cc_next_cred` returns +an error. This function doesn't expect any error on calling +other kerberos foreign functions during iteration. But that can +actually happen and KRB5Error exceptions stop an iteration while +they should be propagated. + +With this change iteration will exactly stop on `krb5_cc_next_cred` +error as it was supposed to be. + +Fixes: https://pagure.io/freeipa/issue/9519 +Signed-off-by: Stanislav Levin +Reviewed-By: Alexander Bokovoy + +--- + +diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py +index dc36f54..e890dc9 100644 +--- a/ipapython/session_storage.py ++++ b/ipapython/session_storage.py +@@ -312,8 +312,12 @@ def get_data(princ_name, key): + checkcreds = krb5_creds() + # the next function will throw an error and break out of the + # while loop when we try to access past the last cred +- krb5_cc_next_cred(context, ccache, ctypes.byref(cursor), +- ctypes.byref(checkcreds)) ++ try: ++ krb5_cc_next_cred(context, ccache, ctypes.byref(cursor), ++ ctypes.byref(checkcreds)) ++ except KRB5Error: ++ break ++ + if (krb5_principal_compare(context, principal, + checkcreds.client) == 1 and + krb5_principal_compare(context, srv_princ, +@@ -328,8 +332,6 @@ def get_data(princ_name, key): + else: + krb5_free_cred_contents(context, + ctypes.byref(checkcreds)) +- except KRB5Error: +- pass + finally: + krb5_cc_end_seq_get(context, ccache, ctypes.byref(cursor)) + + diff --git a/SOURCES/0037-ipa-kdb-Fix-memory-leak-during-PAC-verification.patch b/SOURCES/0037-ipa-kdb-Fix-memory-leak-during-PAC-verification.patch new file mode 100644 index 0000000..c8f7357 --- /dev/null +++ b/SOURCES/0037-ipa-kdb-Fix-memory-leak-during-PAC-verification.patch @@ -0,0 +1,89 @@ +From e831416320fdc73a18fba7716209edec76681721 Mon Sep 17 00:00:00 2001 +From: Julien Rische +Date: Jan 30 2024 15:16:22 +0000 +Subject: ipa-kdb: Fix memory leak during PAC verification + + +Commit 0022bd70d93708d325855d5271516d6cd894d6e8 introduced a memory leak +during the copy of some PAC buffers, because of an unfreed memory +allocation context. + +Fixes: https://pagure.io/freeipa/issue/9520 + +Signed-off-by: Julien Rische +Reviewed-By: Alexander Bokovoy + +--- + +diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c +index 1558e2b..2866304 100644 +--- a/daemons/ipa-kdb/ipa_kdb_mspac.c ++++ b/daemons/ipa-kdb/ipa_kdb_mspac.c +@@ -2316,6 +2316,7 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context, + size_t i; + struct dom_sid *requester_sid = NULL; + struct dom_sid req_sid; ++ TALLOC_CTX *tmpctx = NULL; + + if (signing_krbtgt != NULL && + ipadb_is_cross_realm_krbtgt(signing_krbtgt->princ)) { +@@ -2371,6 +2372,12 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context, + goto done; + } + ++ tmpctx = talloc_new(NULL); ++ if (tmpctx == NULL) { ++ kerr = ENOMEM; ++ goto done; ++ } ++ + for (i = 0; i < num_buffers; i++) { + if (types[i] == KRB5_PAC_SERVER_CHECKSUM || + types[i] == KRB5_PAC_PRIVSVR_CHECKSUM || +@@ -2398,32 +2405,21 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context, + DATA_BLOB pac_attrs_data; + krb5_boolean pac_requested; + +- TALLOC_CTX *tmpctx = talloc_new(NULL); +- if (tmpctx == NULL) { +- kerr = ENOMEM; +- goto done; +- } +- + kerr = ipadb_client_requested_pac(context, old_pac, tmpctx, &pac_requested); +- if (kerr != 0) { +- talloc_free(tmpctx); ++ if (kerr) + goto done; +- } + + kerr = ipadb_get_pac_attrs_blob(tmpctx, &pac_requested, &pac_attrs_data); +- if (kerr) { +- talloc_free(tmpctx); ++ if (kerr) + goto done; +- } ++ + data.magic = KV5M_DATA; + data.data = (char *)pac_attrs_data.data; + data.length = pac_attrs_data.length; + + kerr = krb5_pac_add_buffer(context, new_pac, PAC_TYPE_ATTRIBUTES_INFO, &data); +- if (kerr) { +- talloc_free(tmpctx); ++ if (kerr) + goto done; +- } + + continue; + } +@@ -2470,6 +2466,8 @@ done: + if (kerr != 0 && (new_pac != *pac)) { + krb5_pac_free(context, new_pac); + } ++ if (tmpctx) ++ talloc_free(tmpctx); + krb5_free_data_contents(context, &pac_blob); + free(types); + return kerr; + diff --git a/SOURCES/0038-sidgen-ignore-staged-users-when-generating-SIDs.patch b/SOURCES/0038-sidgen-ignore-staged-users-when-generating-SIDs.patch new file mode 100644 index 0000000..c100263 --- /dev/null +++ b/SOURCES/0038-sidgen-ignore-staged-users-when-generating-SIDs.patch @@ -0,0 +1,80 @@ +From d4008aece36569131b6e81192cc7d7dfa9f9af2b Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Jan 31 2024 08:33:17 +0000 +Subject: sidgen: ignore staged users when generating SIDs + + +Staged users have + + uidNumber: -1 + gidNumber: -1 + ipaUniqueID: autogenerate + +We cannot generate ipaSecurityIdentifier based on those UID/GID numbers. +However, '-1' value will trigger an error + + find_sid_for_ldap_entry - [file ipa_sidgen_common.c, line 483]: ID value too large. + +And that, in turn, will cause stopping SID generation for all users. + +Detect 'ipaUniqueID: autogenerate' situation and ignore these entries. + +Fixes: https://pagure.io/freeipa/issue/9517 + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Thierry Bordaz + +--- + +diff --git a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h +index 0feff7e..bd46982 100644 +--- a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h ++++ b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h +@@ -45,6 +45,8 @@ + #define UID_NUMBER "uidnumber" + #define GID_NUMBER "gidnumber" + #define IPA_SID "ipantsecurityidentifier" ++#define IPA_UNIQUEID "ipauniqueid" ++#define IPA_UNIQUEID_AUTOGENERATE "autogenerate" + #define DOM_ATTRS_FILTER OBJECTCLASS"=ipantdomainattrs" + #define DOMAIN_ID_RANGE_FILTER OBJECTCLASS"=ipadomainidrange" + #define POSIX_ACCOUNT "posixaccount" +diff --git a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c +index 6f78480..cb763eb 100644 +--- a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c ++++ b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c +@@ -454,6 +454,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry, + uint32_t id; + char *sid = NULL; + char **objectclasses = NULL; ++ char *uniqueid = NULL; + Slapi_PBlock *mod_pb = NULL; + Slapi_Mods *smods = NULL; + int result; +@@ -479,6 +480,16 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry, + goto done; + } + ++ uniqueid = slapi_entry_attr_get_charptr(entry, IPA_UNIQUEID); ++ if (uniqueid != NULL && ++ strncmp(IPA_UNIQUEID_AUTOGENERATE, uniqueid, ++ sizeof(IPA_UNIQUEID_AUTOGENERATE)) == 0) { ++ LOG("Staged entry [%s] does not have Posix IDs, nothing to do.\n", ++ dn_str); ++ ret = 0; ++ goto done; ++ } ++ + if (uid_number >= UINT32_MAX || gid_number >= UINT32_MAX) { + LOG_FATAL("ID value too large.\n"); + ret = LDAP_CONSTRAINT_VIOLATION; +@@ -554,6 +565,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry, + } + + done: ++ slapi_ch_free_string(&uniqueid); + slapi_ch_free_string(&sid); + slapi_pblock_destroy(mod_pb); + slapi_mods_free(&smods); + diff --git a/SOURCES/0039-sidgen-fix-missing-prototypes.patch b/SOURCES/0039-sidgen-fix-missing-prototypes.patch new file mode 100644 index 0000000..2582d17 --- /dev/null +++ b/SOURCES/0039-sidgen-fix-missing-prototypes.patch @@ -0,0 +1,24 @@ +From e6f96a9f2edd55ef335eb430b8dd8f6c9faf008f Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Jan 31 2024 08:33:17 +0000 +Subject: sidgen: fix missing prototypes + + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Thierry Bordaz + +--- + +diff --git a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h +index bd46982..aec8627 100644 +--- a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h ++++ b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h +@@ -106,3 +106,6 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry, + const char *base_dn, + const char *dom_sid, + struct range_info **ranges); ++ ++int sidgen_task_init(Slapi_PBlock *pb); ++int ipa_sidgen_init(Slapi_PBlock *pb); + diff --git a/SOURCES/0040-kdb-PAC-generator-do-not-fail-if-canonical-principal-is-missing.patch b/SOURCES/0040-kdb-PAC-generator-do-not-fail-if-canonical-principal-is-missing.patch new file mode 100644 index 0000000..381613a --- /dev/null +++ b/SOURCES/0040-kdb-PAC-generator-do-not-fail-if-canonical-principal-is-missing.patch @@ -0,0 +1,45 @@ +From 196d63109730666f547f99814a54a5b2cd72c80e Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Jan 31 2024 08:33:17 +0000 +Subject: kdb: PAC generator: do not fail if canonical principal is missing + + +krbCanonicalName is mandatory for services but IPA services created +before commit e6ff83e (FreeIPA 4.4.0, ~2016) had no normalization done +to set krbCanonicalName; services created after that version were +upgraded to do have krbCanonicalName. + +Accept krbPrincipalName alone since they have no alias either */ + +Fixes: https://pagure.io/freeipa/issue/9465 + +Signed-off-by: Alexander Bokovoy +Reviewed-By: Florence Blanc-Renaud +Reviewed-By: Thierry Bordaz + +--- + +diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c +index 2866304..16374a5 100644 +--- a/daemons/ipa-kdb/ipa_kdb_mspac.c ++++ b/daemons/ipa-kdb/ipa_kdb_mspac.c +@@ -496,8 +496,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, + ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, + "krbCanonicalName", &strres); + if (ret) { +- /* krbCanonicalName is mandatory for services */ +- return ret; ++ /* krbCanonicalName is mandatory for services but IPA services ++ * created before commit e6ff83e (FreeIPA 4.4.0, ~2016) had no ++ * normalization to set krbCanonicalName; services created after ++ * that version were upgraded to do have krbCanonicalName. ++ * ++ * Accept krbPrincipalName alone since they have no alias either */ ++ ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, ++ "krbPrincipalName", &strres); ++ if (ret) ++ return ret; + } + + ret = krb5_parse_name(ipactx->kcontext, strres, &princ); + diff --git a/SOURCES/0041-ipatests-fix-tasks.wait_for_replication-method.patch b/SOURCES/0041-ipatests-fix-tasks.wait_for_replication-method.patch new file mode 100644 index 0000000..8b1a3da --- /dev/null +++ b/SOURCES/0041-ipatests-fix-tasks.wait_for_replication-method.patch @@ -0,0 +1,34 @@ +From 278c2cbb193496302f8c0abc4ce502ec83f47a12 Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Feb 14 2024 12:23:15 +0000 +Subject: ipatests: fix tasks.wait_for_replication method + + +With the fix for https://pagure.io/freeipa/issue/9171, the +method entry.single_value['nsds5replicaupdateinprogress'] now +returns a Boolean instead of a string "TRUE"/"FALSE". + +The method tasks.wait_for_replication needs to be fixed so that +it properly detects when replication is not done. + +Fixes: https://pagure.io/freeipa/issue/9530 + +Signed-off-by: Florence Blanc-Renaud +Reviewed-By: Rob Crittenden + +--- + +diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py +index 3dd32cf..9c73ac4 100755 +--- a/ipatests/pytest_ipa/integration/tasks.py ++++ b/ipatests/pytest_ipa/integration/tasks.py +@@ -1520,7 +1520,7 @@ def wait_for_replication(ldap, timeout=30, + statuses = [entry.single_value[status_attr] for entry in entries] + wrong_statuses = [s for s in statuses + if not re.match(target_status_re, s)] +- if any(e.single_value[progress_attr] == 'TRUE' for e in entries): ++ if any(e.single_value[progress_attr] for e in entries): + msg = 'Replication not finished' + logger.debug(msg) + elif wrong_statuses: + diff --git a/SOURCES/0042-ipa-kdb-Rework-ipadb_reinit_mspac.patch b/SOURCES/0042-ipa-kdb-Rework-ipadb_reinit_mspac.patch new file mode 100644 index 0000000..f04c7ce --- /dev/null +++ b/SOURCES/0042-ipa-kdb-Rework-ipadb_reinit_mspac.patch @@ -0,0 +1,699 @@ +From 7b7f5c3f806e53ff883865c7b7f4d17453d63ce6 Mon Sep 17 00:00:00 2001 +From: Julien Rische +Date: Feb 16 2024 11:58:21 +0000 +Subject: ipa-kdb: Rework ipadb_reinit_mspac() + + +Modify ipadb_reinit_mspac() to allocate and initialize ipactx->mspac +only if all its attributes can be set. If not, ipactx->mspac is set to +NULL. This makes easier to determine if the KDC is able to generate PACs +or not. + +Also ipadb_reinit_mspac() is now able to return a status message +explaining why initialization of the PAC generator failed. This message +is printed in KDC logs. + +Fixes: https://pagure.io/freeipa/issue/9535 + +Signed-off-by: Julien Rische +Reviewed-By: Alexander Bokovoy + +--- + +diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c +index a60f16c..f17cb11 100644 +--- a/daemons/ipa-kdb/ipa_kdb.c ++++ b/daemons/ipa-kdb/ipa_kdb.c +@@ -448,6 +448,7 @@ int ipadb_get_connection(struct ipadb_context *ipactx) + struct timeval tv = { 5, 0 }; + LDAPMessage *res = NULL; + LDAPMessage *first; ++ const char *stmsg; + int ret; + int v3; + +@@ -527,16 +528,9 @@ int ipadb_get_connection(struct ipadb_context *ipactx) + } + + /* get adtrust options using default refresh interval */ +- ret = ipadb_reinit_mspac(ipactx, false); +- if (ret && ret != ENOENT) { +- /* TODO: log that there is an issue with adtrust settings */ +- if (ipactx->lcontext == NULL) { +- /* for some reason ldap connection was reset in ipadb_reinit_mspac +- * and is no longer established => failure of ipadb_get_connection +- */ +- goto done; +- } +- } ++ ret = ipadb_reinit_mspac(ipactx, false, &stmsg); ++ if (ret && stmsg) ++ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg); + + ret = 0; + +diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h +index 7b7c03b..3647ecd 100644 +--- a/daemons/ipa-kdb/ipa_kdb.h ++++ b/daemons/ipa-kdb/ipa_kdb.h +@@ -369,7 +369,9 @@ krb5_error_code ipadb_v9_issue_pac(krb5_context context, unsigned int flags, + krb5_data ***auth_indicators); + #endif + +-krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit); ++krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, ++ bool force_reinit, ++ const char **stmsg); + + void ipadb_mspac_struct_free(struct ipadb_mspac **mspac); + krb5_error_code ipadb_check_transited_realms(krb5_context kcontext, +diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c +index 16374a5..b0eb332 100644 +--- a/daemons/ipa-kdb/ipa_kdb_mspac.c ++++ b/daemons/ipa-kdb/ipa_kdb_mspac.c +@@ -793,16 +793,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, + return ret; + } + ++ if (!ipactx->mspac) { ++ /* can't give a PAC without server NetBIOS name or primary group RID */ ++ return ENOENT; ++ } ++ + if (info3->base.primary_gid == 0) { + if (is_host || is_service) { + info3->base.primary_gid = 515; /* Well known RID for domain computers group */ + } else { +- if (ipactx->mspac->fallback_rid) { +- info3->base.primary_gid = ipactx->mspac->fallback_rid; +- } else { +- /* can't give a pack without a primary group rid */ +- return ENOENT; +- } ++ info3->base.primary_gid = ipactx->mspac->fallback_rid; + } + } + +@@ -812,26 +812,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, + /* always zero out, not used for Krb, only NTLM */ + memset(&info3->base.key, '\0', sizeof(info3->base.key)); + +- if (ipactx->mspac->flat_server_name) { +- info3->base.logon_server.string = +- talloc_strdup(memctx, ipactx->mspac->flat_server_name); +- if (!info3->base.logon_server.string) { +- return ENOMEM; +- } +- } else { +- /* can't give a pack without Server NetBIOS Name :-| */ +- return ENOENT; ++ info3->base.logon_server.string = ++ talloc_strdup(memctx, ipactx->mspac->flat_server_name); ++ if (!info3->base.logon_server.string) { ++ return ENOMEM; + } + +- if (ipactx->mspac->flat_domain_name) { +- info3->base.logon_domain.string = +- talloc_strdup(memctx, ipactx->mspac->flat_domain_name); +- if (!info3->base.logon_domain.string) { +- return ENOMEM; +- } +- } else { +- /* can't give a pack without Domain NetBIOS Name :-| */ +- return ENOENT; ++ info3->base.logon_domain.string = ++ talloc_strdup(memctx, ipactx->mspac->flat_domain_name); ++ if (!info3->base.logon_domain.string) { ++ return ENOMEM; + } + + if (is_host || is_service) { +@@ -1044,6 +1034,11 @@ krb5_error_code ipadb_get_pac(krb5_context kcontext, + return KRB5_KDB_DBNOTINITED; + } + ++ /* Check if PAC generator is initialized */ ++ if (!ipactx->mspac) { ++ return ENOENT; ++ } ++ + ied = (struct ipadb_e_data *)client->e_data; + if (ied->magic != IPA_E_DATA_MAGIC) { + return EINVAL; +@@ -1626,14 +1621,14 @@ static struct ipadb_adtrusts *get_domain_from_realm(krb5_context context, + { + struct ipadb_context *ipactx; + struct ipadb_adtrusts *domain; +- int i; ++ size_t i; + + ipactx = ipadb_get_context(context); + if (!ipactx) { + return NULL; + } + +- if (ipactx->mspac == NULL) { ++ if (!ipactx->mspac) { + return NULL; + } + +@@ -1655,6 +1650,7 @@ static struct ipadb_adtrusts *get_domain_from_realm_update(krb5_context context, + { + struct ipadb_context *ipactx; + struct ipadb_adtrusts *domain; ++ const char *stmsg = NULL; + krb5_error_code kerr; + + ipactx = ipadb_get_context(context); +@@ -1663,8 +1659,10 @@ static struct ipadb_adtrusts *get_domain_from_realm_update(krb5_context context, + } + + /* re-init MS-PAC info using default update interval */ +- kerr = ipadb_reinit_mspac(ipactx, false); ++ kerr = ipadb_reinit_mspac(ipactx, false, &stmsg); + if (kerr != 0) { ++ if (stmsg) ++ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg); + return NULL; + } + domain = get_domain_from_realm(context, realm); +@@ -1717,6 +1715,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context, + struct ipadb_e_data *ied = NULL; + int flags = 0; + struct dom_sid client_sid; ++ const char *stmsg = NULL; + #ifdef KRB5_KDB_FLAG_ALIAS_OK + flags = KRB5_KDB_FLAG_ALIAS_OK; + #endif +@@ -1730,10 +1729,14 @@ static krb5_error_code check_logon_info_consistent(krb5_context context, + * check that our own view on the PAC details is up to date */ + if (ipactx->mspac->domsid.num_auths == 0) { + /* Force re-init of KDB's view on our domain */ +- kerr = ipadb_reinit_mspac(ipactx, true); ++ kerr = ipadb_reinit_mspac(ipactx, true, &stmsg); + if (kerr != 0) { +- krb5_klog_syslog(LOG_ERR, +- "PAC issue: unable to update realm's view on PAC info"); ++ if (stmsg) { ++ krb5_klog_syslog(LOG_ERR, "MS-PAC generator: %s", stmsg); ++ } else { ++ krb5_klog_syslog(LOG_ERR, "PAC issue: unable to update " \ ++ "realm's view on PAC info"); ++ } + return KRB5KDC_ERR_POLICY; + } + } +@@ -1746,7 +1749,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context, + if (is_s4u && (ipactx->mspac->trusts != NULL)) { + /* Iterate through list of trusts and check if this SID belongs to + * one of the domains we trust */ +- for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) { ++ for(size_t i = 0 ; i < ipactx->mspac->num_trusts ; i++) { + result = dom_sid_check(&ipactx->mspac->trusts[i].domsid, + info->info->info3.base.domain_sid, true); + if (result) { +@@ -1858,11 +1861,11 @@ krb5_error_code filter_logon_info(krb5_context context, + struct ipadb_mspac *mspac_ctx = ipactx->mspac; + result = FALSE; + /* Didn't match but perhaps the original PAC was issued by a child domain's DC? */ +- for (k = 0; k < mspac_ctx->num_trusts; k++) { +- result = dom_sid_check(&mspac_ctx->trusts[k].domsid, ++ for (size_t m = 0; m < mspac_ctx->num_trusts; m++) { ++ result = dom_sid_check(&mspac_ctx->trusts[m].domsid, + info->info->info3.base.domain_sid, true); + if (result) { +- domain = &mspac_ctx->trusts[k]; ++ domain = &mspac_ctx->trusts[m]; + break; + } + } +@@ -2091,10 +2094,10 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context, + return KRB5_KDB_DBNOTINITED; + } + /* In S4U case we might be dealing with the PAC issued by the trusted domain */ +- if ((ipactx->mspac->trusts != NULL)) { ++ if (ipactx->mspac->trusts) { + /* Iterate through list of trusts and check if this SID belongs to + * one of the domains we trust */ +- for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) { ++ for(size_t i = 0 ; i < ipactx->mspac->num_trusts ; i++) { + result = dom_sid_check(&ipactx->mspac->trusts[i].domsid, + &client_sid, false); + if (result) { +@@ -2634,7 +2637,7 @@ static char *get_server_netbios_name(struct ipadb_context *ipactx) + + void ipadb_mspac_struct_free(struct ipadb_mspac **mspac) + { +- int i, j; ++ size_t i, j; + + if (!*mspac) return; + +@@ -2789,7 +2792,8 @@ ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx) + LDAPDN dn = NULL; + char **sid_blocklist_incoming = NULL; + char **sid_blocklist_outgoing = NULL; +- int ret, n, i; ++ size_t i, n; ++ int ret; + + ret = asprintf(&base, "cn=ad,cn=trusts,%s", ipactx->base); + if (ret == -1) { +@@ -2874,7 +2878,7 @@ ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx) + + t[n].upn_suffixes_len = NULL; + if (t[n].upn_suffixes != NULL) { +- int len = 0; ++ size_t len = 0; + + for (; t[n].upn_suffixes[len] != NULL; len++); + +@@ -2989,108 +2993,114 @@ done: + return ret; + } + +-krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit) ++krb5_error_code ++ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit, ++ const char **stmsg) + { + char *dom_attrs[] = { "ipaNTFlatName", + "ipaNTFallbackPrimaryGroup", + "ipaNTSecurityIdentifier", + NULL }; + char *grp_attrs[] = { "ipaNTSecurityIdentifier", NULL }; +- krb5_error_code kerr; + LDAPMessage *result = NULL; + LDAPMessage *lentry; +- struct dom_sid gsid; +- char *resstr; +- int ret; ++ struct dom_sid gsid, domsid; ++ char *resstr = NULL; ++ char *flat_domain_name = NULL; ++ char *flat_server_name = NULL; ++ char *fallback_group = NULL; ++ uint32_t fallback_rid; + time_t now; ++ const char *in_stmsg = NULL; ++ int err; ++ krb5_error_code trust_kerr = 0; ++ + + /* Do not update the mspac struct more than once a minute. This would + * avoid heavy load on the directory server if there are lots of requests + * from domains which we do not trust. */ + now = time(NULL); + +- if (ipactx->mspac != NULL && +- (force_reinit == false) && +- (now > ipactx->mspac->last_update) && +- (now - ipactx->mspac->last_update) < 60) { +- return 0; +- } +- +- if (ipactx->mspac && ipactx->mspac->num_trusts == 0) { +- /* Check if there is any trust configured. If not, just return +- * and do not re-initialize the MS-PAC structure. */ +- kerr = ipadb_mspac_check_trusted_domains(ipactx); +- if (kerr == KRB5_KDB_NOENTRY) { +- kerr = 0; +- goto done; +- } else if (kerr != 0) { +- goto done; ++ if (ipactx->mspac) { ++ if (!force_reinit && ++ (now > ipactx->mspac->last_update) && ++ (now - ipactx->mspac->last_update) < 60) { ++ /* SKIP */ ++ err = 0; ++ goto end; ++ } ++ ++ if (ipactx->mspac->num_trusts == 0) { ++ /* Check if there is any trust configured. If not, just return ++ * and do not re-initialize the MS-PAC structure. */ ++ err = ipadb_mspac_check_trusted_domains(ipactx); ++ if (err) { ++ if (err == KRB5_KDB_NOENTRY) { ++ /* SKIP */ ++ err = 0; ++ } else { ++ in_stmsg = "Failed to fetch trusted domains information"; ++ } ++ goto end; ++ } + } + } + +- /* clean up in case we had old values around */ +- ipadb_mspac_struct_free(&ipactx->mspac); +- +- ipactx->mspac = calloc(1, sizeof(struct ipadb_mspac)); +- if (!ipactx->mspac) { +- kerr = ENOMEM; +- goto done; +- } +- +- ipactx->mspac->last_update = now; +- +- kerr = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE, +- "(objectclass=ipaNTDomainAttrs)", dom_attrs, +- &result); +- if (kerr == KRB5_KDB_NOENTRY) { +- return ENOENT; +- } else if (kerr != 0) { +- return EIO; ++ err = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE, ++ "(objectclass=ipaNTDomainAttrs)", dom_attrs, ++ &result); ++ if (err == KRB5_KDB_NOENTRY) { ++ err = ENOENT; ++ in_stmsg = "Local domain NT attributes not configured"; ++ goto end; ++ } else if (err) { ++ err = EIO; ++ in_stmsg = "Failed to fetch local domain NT attributes"; ++ goto end; + } + + lentry = ldap_first_entry(ipactx->lcontext, result); + if (!lentry) { +- kerr = ENOENT; +- goto done; ++ err = ENOENT; ++ in_stmsg = "Local domain NT attributes not configured"; ++ goto end; + } + +- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, +- "ipaNTFlatName", +- &ipactx->mspac->flat_domain_name); +- if (ret) { +- kerr = ret; +- goto done; ++ err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, "ipaNTFlatName", ++ &flat_domain_name); ++ if (err) { ++ in_stmsg = "Local domain NT flat name not configured"; ++ goto end; + } + +- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, +- "ipaNTSecurityIdentifier", +- &resstr); +- if (ret) { +- kerr = ret; +- goto done; ++ err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, ++ "ipaNTSecurityIdentifier", &resstr); ++ if (err) { ++ in_stmsg = "Local domain SID not configured"; ++ goto end; + } + +- ret = ipadb_string_to_sid(resstr, &ipactx->mspac->domsid); +- if (ret) { +- kerr = ret; +- free(resstr); +- goto done; ++ err = ipadb_string_to_sid(resstr, &domsid); ++ if (err) { ++ in_stmsg = "Malformed local domain SID"; ++ goto end; + } ++ + free(resstr); + +- free(ipactx->mspac->flat_server_name); +- ipactx->mspac->flat_server_name = get_server_netbios_name(ipactx); +- if (!ipactx->mspac->flat_server_name) { +- kerr = ENOMEM; +- goto done; ++ flat_server_name = get_server_netbios_name(ipactx); ++ if (!flat_server_name) { ++ err = ENOMEM; ++ goto end; + } + +- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, +- "ipaNTFallbackPrimaryGroup", +- &ipactx->mspac->fallback_group); +- if (ret && ret != ENOENT) { +- kerr = ret; +- goto done; ++ err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, ++ "ipaNTFallbackPrimaryGroup", &fallback_group); ++ if (err) { ++ in_stmsg = (err == ENOENT) ++ ? "Local fallback primary group not configured" ++ : "Failed to fetch local fallback primary group"; ++ goto end; + } + + /* result and lentry not valid any more from here on */ +@@ -3098,53 +3108,81 @@ krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_rein + result = NULL; + lentry = NULL; + +- if (ret != ENOENT) { +- kerr = ipadb_simple_search(ipactx, ipactx->mspac->fallback_group, +- LDAP_SCOPE_BASE, +- "(objectclass=posixGroup)", +- grp_attrs, &result); +- if (kerr && kerr != KRB5_KDB_NOENTRY) { +- kerr = ret; +- goto done; +- } ++ err = ipadb_simple_search(ipactx, fallback_group, LDAP_SCOPE_BASE, ++ "(objectclass=posixGroup)", grp_attrs, &result); ++ if (err) { ++ in_stmsg = (err == KRB5_KDB_NOENTRY) ++ ? "Local fallback primary group has no POSIX definition" ++ : "Failed to fetch SID of POSIX group mapped as local fallback " \ ++ "primary group"; ++ goto end; ++ } + +- lentry = ldap_first_entry(ipactx->lcontext, result); +- if (!lentry) { +- kerr = ENOENT; +- goto done; +- } ++ lentry = ldap_first_entry(ipactx->lcontext, result); ++ if (!lentry) { ++ err = ENOENT; ++ goto end; ++ } + +- if (kerr == 0) { +- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, +- "ipaNTSecurityIdentifier", +- &resstr); +- if (ret && ret != ENOENT) { +- kerr = ret; +- goto done; +- } +- if (ret == 0) { +- ret = ipadb_string_to_sid(resstr, &gsid); +- if (ret) { +- free(resstr); +- kerr = ret; +- goto done; +- } +- ret = sid_split_rid(&gsid, &ipactx->mspac->fallback_rid); +- if (ret) { +- free(resstr); +- kerr = ret; +- goto done; +- } +- free(resstr); +- } +- } ++ err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, ++ "ipaNTSecurityIdentifier", &resstr); ++ if (err) { ++ in_stmsg = (err == ENOENT) ++ ? "The POSIX group set as fallback primary group has no SID " \ ++ "configured" ++ : "Failed to fetch SID of POSIX group set as local fallback " \ ++ "primary group"; ++ goto end; + } + +- kerr = ipadb_mspac_get_trusted_domains(ipactx); ++ err = ipadb_string_to_sid(resstr, &gsid); ++ if (err) { ++ in_stmsg = "Malformed SID of POSIX group set as local fallback " \ ++ "primary group"; ++ goto end; ++ } + +-done: ++ err = sid_split_rid(&gsid, &fallback_rid); ++ if (err) { ++ in_stmsg = "Malformed SID of POSIX group mapped as local fallback " \ ++ "primary group"; ++ goto end; ++ } ++ ++ /* clean up in case we had old values around */ ++ ipadb_mspac_struct_free(&ipactx->mspac); ++ ++ ipactx->mspac = calloc(1, sizeof(struct ipadb_mspac)); ++ if (!ipactx->mspac) { ++ err = ENOMEM; ++ goto end; ++ } ++ ++ ipactx->mspac->last_update = now; ++ ipactx->mspac->flat_domain_name = flat_domain_name; ++ ipactx->mspac->flat_server_name = flat_server_name; ++ ipactx->mspac->domsid = domsid; ++ ipactx->mspac->fallback_group = fallback_group; ++ ipactx->mspac->fallback_rid = fallback_rid; ++ ++ trust_kerr = ipadb_mspac_get_trusted_domains(ipactx); ++ if (trust_kerr) ++ in_stmsg = "Failed to assemble trusted domains information"; ++ ++end: ++ if (stmsg) ++ *stmsg = in_stmsg; ++ ++ if (resstr) free(resstr); + ldap_msgfree(result); +- return kerr; ++ ++ if (err) { ++ if (flat_domain_name) free(flat_domain_name); ++ if (flat_server_name) free(flat_server_name); ++ if (fallback_group) free(fallback_group); ++ } ++ ++ return err ? (krb5_error_code)err : trust_kerr; + } + + krb5_error_code ipadb_check_transited_realms(krb5_context kcontext, +@@ -3154,11 +3192,11 @@ krb5_error_code ipadb_check_transited_realms(krb5_context kcontext, + { + struct ipadb_context *ipactx; + bool has_transited_contents, has_client_realm, has_server_realm; +- int i; ++ size_t i; + krb5_error_code ret; + + ipactx = ipadb_get_context(kcontext); +- if (!ipactx || !ipactx->mspac) { ++ if (!ipactx) { + return KRB5_KDB_DBNOTINITED; + } + +@@ -3220,7 +3258,7 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext, + char **trusted_realm) + { + struct ipadb_context *ipactx; +- int i, j, length; ++ size_t i, j, length; + const char *name; + bool result = false; + +diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_private.h b/daemons/ipa-kdb/ipa_kdb_mspac_private.h +index 7f0ca7a..e650cfa 100644 +--- a/daemons/ipa-kdb/ipa_kdb_mspac_private.h ++++ b/daemons/ipa-kdb/ipa_kdb_mspac_private.h +@@ -31,7 +31,7 @@ struct ipadb_mspac { + char *fallback_group; + uint32_t fallback_rid; + +- int num_trusts; ++ size_t num_trusts; + struct ipadb_adtrusts *trusts; + time_t last_update; + }; +diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_v6.c b/daemons/ipa-kdb/ipa_kdb_mspac_v6.c +index faf47ad..96cd50e 100644 +--- a/daemons/ipa-kdb/ipa_kdb_mspac_v6.c ++++ b/daemons/ipa-kdb/ipa_kdb_mspac_v6.c +@@ -233,6 +233,7 @@ krb5_error_code ipadb_sign_authdata(krb5_context context, + krb5_db_entry *client_entry = NULL; + krb5_boolean is_equal; + bool force_reinit_mspac = false; ++ const char *stmsg = NULL; + + + is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0); +@@ -309,7 +310,9 @@ krb5_error_code ipadb_sign_authdata(krb5_context context, + force_reinit_mspac = true; + } + +- (void)ipadb_reinit_mspac(ipactx, force_reinit_mspac); ++ kerr = ipadb_reinit_mspac(ipactx, force_reinit_mspac, &stmsg); ++ if (kerr && stmsg) ++ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg); + + kerr = ipadb_get_pac(context, flags, client, server, NULL, authtime, &pac); + if (kerr != 0 && kerr != ENOENT) { +diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_v9.c b/daemons/ipa-kdb/ipa_kdb_mspac_v9.c +index 3badd5b..60db048 100644 +--- a/daemons/ipa-kdb/ipa_kdb_mspac_v9.c ++++ b/daemons/ipa-kdb/ipa_kdb_mspac_v9.c +@@ -46,6 +46,7 @@ ipadb_v9_issue_pac(krb5_context context, unsigned int flags, + bool with_pad; + krb5_error_code kerr = 0; + bool is_as_req = flags & CLIENT_REFERRALS_FLAGS; ++ const char *stmsg = NULL; + + if (is_as_req) { + get_authz_data_types(context, client, &with_pac, &with_pad); +@@ -110,12 +111,19 @@ ipadb_v9_issue_pac(krb5_context context, unsigned int flags, + force_reinit_mspac = TRUE; + } + } +- (void)ipadb_reinit_mspac(ipactx, force_reinit_mspac); + +- /* MS-PAC needs proper configuration and if it is missing, we simply skip issuing one */ +- if (ipactx->mspac->flat_server_name == NULL) { ++ /* MS-PAC generator has to be initalized */ ++ kerr = ipadb_reinit_mspac(ipactx, force_reinit_mspac, &stmsg); ++ if (kerr && stmsg) ++ krb5_klog_syslog(LOG_ERR, "MS-PAC generator: %s", stmsg); ++ ++ /* Continue even if initilization of PAC generator failed. ++ * It may caused by the trust objects part only. */ ++ ++ /* At least the core part of the PAC generator is required. */ ++ if (!ipactx->mspac) + return KRB5_PLUGIN_OP_NOTSUPP; +- } ++ + kerr = ipadb_get_pac(context, flags, + client, server, replaced_reply_key, + authtime, &new_pac); +diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c +index 00387d4..ffc0fd8 100644 +--- a/daemons/ipa-kdb/ipa_kdb_principals.c ++++ b/daemons/ipa-kdb/ipa_kdb_principals.c +@@ -1567,6 +1567,7 @@ static krb5_error_code dbget_alias(krb5_context kcontext, + -1, + }; + size_t i = 0; ++ const char *stmsg = NULL; + + /* For TGS-REQ server principal lookup, KDC asks with KRB5_KDB_FLAG_REFERRAL_OK + * and client usually asks for an KRB5_NT_PRINCIPAL type principal. */ +@@ -1654,8 +1655,11 @@ static krb5_error_code dbget_alias(krb5_context kcontext, + if (kerr == KRB5_KDB_NOENTRY) { + /* If no trusted realm found, refresh trusted domain data and try again + * because it might be a freshly added trust to AD */ +- kerr = ipadb_reinit_mspac(ipactx, false); ++ kerr = ipadb_reinit_mspac(ipactx, false, &stmsg); + if (kerr != 0) { ++ if (stmsg) ++ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", ++ stmsg); + kerr = KRB5_KDB_NOENTRY; + goto done; + } + diff --git a/SOURCES/0043-ipa-kdb-Fix-double-free-in-ipadb_reinit_mspac.patch b/SOURCES/0043-ipa-kdb-Fix-double-free-in-ipadb_reinit_mspac.patch new file mode 100644 index 0000000..71df74e --- /dev/null +++ b/SOURCES/0043-ipa-kdb-Fix-double-free-in-ipadb_reinit_mspac.patch @@ -0,0 +1,26 @@ +From f1efe4490c1e33b81178ba887600a3a5826c11c2 Mon Sep 17 00:00:00 2001 +From: Julien Rische +Date: Feb 20 2024 18:12:39 +0000 +Subject: ipa-kdb: Fix double free in ipadb_reinit_mspac() + + +Fixes: https://pagure.io/freeipa/issue/9535 + +Signed-off-by: Julien Rische +Reviewed-By: Florence Blanc-Renaud + +--- + +diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c +index b0eb332..9723103 100644 +--- a/daemons/ipa-kdb/ipa_kdb_mspac.c ++++ b/daemons/ipa-kdb/ipa_kdb_mspac.c +@@ -3087,6 +3087,7 @@ ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit, + } + + free(resstr); ++ resstr = NULL; + + flat_server_name = get_server_netbios_name(ipactx); + if (!flat_server_name) { + diff --git a/SPECS/freeipa.spec b/SPECS/freeipa.spec index 9f6c06d..87c6d3b 100644 --- a/SPECS/freeipa.spec +++ b/SPECS/freeipa.spec @@ -223,7 +223,7 @@ Name: %{package_name} Version: %{IPA_VERSION} -Release: 5%{?rc_version:.%rc_version}%{?dist}.alma.1 +Release: 8%{?rc_version:.%rc_version}%{?dist}.alma.1 Summary: The Identity, Policy and Audit system License: GPL-3.0-or-later @@ -279,7 +279,37 @@ Patch0026: 0026-Check-the-HTTP-Referer-header-on-all-requests.patch # https://github.com/freeipa/freeipa/commit/48ec350051ead9c17e58a91405b3ab6935347f1b Patch0027: 0027-Integration-tests-for-verifying-Referer-header-in-th.patch # https://github.com/freeipa/freeipa/commit/f123b01d81696c52e9a4008d46e549864e4a8069 -Patch0028: updates-add-ACIs-for-RBCD-self-management.patch +Patch0028: 0028-updates-add-ACIs-for-RBCD-self-management.patch +# https://pagure.io/freeipa/c/2bbfd1454fc69c5975826d1a3f39b301d135abb5 +Patch0029: 0029-ipatests-restart-ipa-services-after-moving-date.patch +# https://pagure.io/freeipa/c/9bc582a2d78fd3ff9e70fa927b87ab06dcb7c9ae +Patch0030: 0030-ipatests-ignore-nsslapd-accesslog-logbuffering-WARN-in-healthcheck.patch +# https://pagure.io/freeipa/c/96dd277ad960f57c36c38820a7b0542c97f9e67d +Patch0031: 0031-ipatests-Skip-ds_encryption-tests-on-RHEL9-SUT.patch +# https://pagure.io/freeipa/c/3baa30ad3f6ee563089839a5ef56d5ac6eb43959 +Patch0032: 0032-adtrustinstance-make-sure-NetBIOS-name-defaults-are-set-properly.patch +# https://pagure.io/freeipa/c/257b2b470b4e3f83a0cbc476d54dc74ddf2cf311 +Patch0033: 0033-ipatests-wait-for-replica-update-in-test_dns_locations.patch +# https://pagure.io/freeipa/c/2e649b26d1d8ec988ec64477af73cd1f033731fd +Patch0034: 0034-ipapython-Clean-up-krb5_error.patch +# https://pagure.io/freeipa/c/59f010774d13ea6a0148235db2ff05a3f3c93c7b +Patch0035: 0035-ipapython-Correct-return-type-of-krb5_free_cred_contents.patch +# https://pagure.io/freeipa/c/e69d98add55f25641459fc1dfb973260e85f9b95 +Patch0036: 0036-ipapython-Propagate-KRB5Error-exceptions-on-iterating-ccache.patch +# https://pagure.io/freeipa/c/e831416320fdc73a18fba7716209edec76681721 +Patch0037: 0037-ipa-kdb-Fix-memory-leak-during-PAC-verification.patch +# https://pagure.io/freeipa/c/d4008aece36569131b6e81192cc7d7dfa9f9af2b +Patch0038: 0038-sidgen-ignore-staged-users-when-generating-SIDs.patch +# https://pagure.io/freeipa/c/e6f96a9f2edd55ef335eb430b8dd8f6c9faf008f +Patch0039: 0039-sidgen-fix-missing-prototypes.patch +# https://pagure.io/freeipa/c/196d63109730666f547f99814a54a5b2cd72c80e +Patch0040: 0040-kdb-PAC-generator-do-not-fail-if-canonical-principal-is-missing.patch +# https://pagure.io/freeipa/c/278c2cbb193496302f8c0abc4ce502ec83f47a12 +Patch0041: 0041-ipatests-fix-tasks.wait_for_replication-method.patch +# https://pagure.io/freeipa/c/7b7f5c3f806e53ff883865c7b7f4d17453d63ce6 +Patch0042: 0042-ipa-kdb-Rework-ipadb_reinit_mspac.patch +# https://pagure.io/freeipa/c/f1efe4490c1e33b81178ba887600a3a5826c11c2 +Patch0043: 0043-ipa-kdb-Fix-double-free-in-ipadb_reinit_mspac.patch Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch %endif @@ -1772,6 +1802,23 @@ fi %endif %changelog +* Fri Mar 15 2024 Eduard Abdullin - 4.10.2-8.alma.1 +- ipatests: restart ipa services after moving date +- ipatests: ignore nsslapd-accesslog-logbuffering WARN in healthcheck +- ipatests: Skip ds_encryption tests on RHEL9 SUT. +- adtrustinstance: make sure NetBIOS name defaults are set properly +- ipatests: wait for replica update in test_dns_locations +- ipapython: Clean up krb5_error +- ipapython: Correct return type of krb5_free_cred_contents +- ipapython: Propagate KRB5Error exceptions on iterating ccache +- ipa-kdb: Fix memory leak during PAC verification +- sidgen: ignore staged users when generating SIDs +- sidgen: fix missing prototypes +- kdb: PAC generator: do not fail if canonical principal is missing +- ipatests: fix tasks.wait_for_replication method +- ipa-kdb: Rework ipadb_reinit_mspac() +- ipa-kdb: Fix double free in ipadb_reinit_mspac() + * Thu Jan 11 2024 Andrew Lukoshko - 4.10.2-5.alma.1 - Resolves: Invalid CSRF protection (CVE-2023-5455)