diff --git a/.gitignore b/.gitignore index 78c395b..2d90848 100644 --- a/.gitignore +++ b/.gitignore @@ -132,3 +132,5 @@ /freeipa-4.11.0.tar.gz.asc /freeipa-4.11.1.tar.gz /freeipa-4.11.1.tar.gz.asc +/freeipa-4.12.0.tar.gz +/freeipa-4.12.0.tar.gz.asc diff --git a/0001-Restore-selinux-states-if-they-exist-at-uninstall-ti.patch b/0001-Restore-selinux-states-if-they-exist-at-uninstall-ti.patch deleted file mode 100644 index 3bd93d1..0000000 --- a/0001-Restore-selinux-states-if-they-exist-at-uninstall-ti.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 499f1e3e996aadbd4f26a90db81a0b1b68b61c57 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 12 Sep 2023 17:07:52 +0300 -Subject: [PATCH] Restore selinux states if they exist at uninstall time - -Related: https://pagure.io/freeipa/issue/9434 - -Signed-off-by: Alexander Bokovoy ---- - ipaclient/install/client.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py -index 1aaa4ed60..01a5f2339 100644 ---- a/ipaclient/install/client.py -+++ b/ipaclient/install/client.py -@@ -3624,7 +3624,7 @@ def uninstall(options): - "Failed to disable automatic startup of the SSSD daemon: %s", - e) - -- if was_sssd_installed and selinux_works: -+ if statestore.has_state('selinux'): - # Restore SELinux boolean states - boolean_states = {name: statestore.restore_state('selinux', name) - for name in constants.SELINUX_BOOLEAN_SSSD} --- -2.41.0 - diff --git a/0001-Revert-Replace-netifaces-with-ifaddr.patch b/0001-Revert-Replace-netifaces-with-ifaddr.patch new file mode 100644 index 0000000..f52bacf --- /dev/null +++ b/0001-Revert-Replace-netifaces-with-ifaddr.patch @@ -0,0 +1,238 @@ +From dfeb01d5e4e8934bae8f495bbbd5b6570f3dc862 Mon Sep 17 00:00:00 2001 +From: Florence Blanc-Renaud +Date: Tue, 4 Jun 2024 13:56:56 +0200 +Subject: [PATCH] Revert "Replace netifaces with ifaddr" + +This reverts commit 6c6b9354b5f970983655ca5423c726763d9015fa. +--- + doc/requirements.txt | 1 - + freeipa.spec.in | 4 +-- + ipaclient/install/client.py | 43 ++++++++++++++----------------- + ipapython/ipautil.py | 51 ++++++++++++++++++++----------------- + ipapython/setup.py | 2 +- + ipasetup.py.in | 2 +- + pylintrc | 1 + + 7 files changed, 52 insertions(+), 52 deletions(-) + +diff --git a/doc/requirements.txt b/doc/requirements.txt +index 8d91b893fbcb5de784f5abdf802b976c6b2ae277..cdaa42658c73e495379d87b7c50195fbd79533ee 100644 +--- a/doc/requirements.txt ++++ b/doc/requirements.txt +@@ -11,7 +11,6 @@ m2r2 + ## ipa dependencies + dnspython + jwcrypto +-ifaddr + netaddr + qrcode + six +diff --git a/freeipa.spec.in b/freeipa.spec.in +index 6803de752bc122bf6e1eafd610d399cde994cad5..a532fe85c34a523519187b6fd1297c198d9f4a4e 100755 +--- a/freeipa.spec.in ++++ b/freeipa.spec.in +@@ -403,7 +403,7 @@ BuildRequires: python3-libipa_hbac + BuildRequires: python3-libsss_nss_idmap + BuildRequires: python3-lxml + BuildRequires: python3-netaddr >= %{python_netaddr_version} +-BuildRequires: python3-ifaddr ++BuildRequires: python3-netifaces + BuildRequires: python3-pki >= %{pki_version} + BuildRequires: python3-polib + BuildRequires: python3-pyasn1 +@@ -885,7 +885,7 @@ Requires: python3-gssapi >= 1.2.0 + Requires: python3-jwcrypto >= 0.4.2 + Requires: python3-libipa_hbac + Requires: python3-netaddr >= %{python_netaddr_version} +-Requires: python3-ifaddr ++Requires: python3-netifaces >= 0.10.4 + Requires: python3-pyasn1 >= 0.3.2-2 + Requires: python3-pyasn1-modules >= 0.3.2-2 + Requires: python3-pyusb +diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py +index 29aff5f413e7f27136e236382031171f068284c5..263dc8e302cccd76412c294e0740af9744a2c62d 100644 +--- a/ipaclient/install/client.py ++++ b/ipaclient/install/client.py +@@ -18,7 +18,7 @@ import logging + import dns + import getpass + import gssapi +-import ifaddr ++import netifaces + import os + import re + import SSSDConfig +@@ -1374,36 +1374,31 @@ def unconfigure_nisdomain(statestore): + + + def get_iface_from_ip(ip_addr): +- for adapter in ifaddr.get_adapters(): +- for ips in adapter.ips: +- # IPv6 is reported as a tuple, IPv4 is reported as str +- if ip_addr in (ips.ip[0], ips.ip): +- return adapter.name ++ for interface in netifaces.interfaces(): ++ if_addrs = netifaces.ifaddresses(interface) ++ for family in [netifaces.AF_INET, netifaces.AF_INET6]: ++ for ip in if_addrs.get(family, []): ++ if ip['addr'] == ip_addr: ++ return interface + raise RuntimeError("IP %s not assigned to any interface." % ip_addr) + + +-def __get_ifaddr_adapters(iface=None): ++def get_local_ipaddresses(iface=None): + if iface: +- interfaces = set(iface if isinstance(iface, (list, tuple)) else [iface]) ++ interfaces = [iface] + else: +- interfaces = set(adapter.name for adapter in ifaddr.get_adapters()) +- return [ +- adapter +- for adapter in ifaddr.get_adapters() +- if adapter.name in interfaces or adapter.nice_name in interfaces +- ] ++ interfaces = netifaces.interfaces() + +- +-def get_local_ipaddresses(iface=None): + ips = [] +- for adapter in __get_ifaddr_adapters(iface): +- for ifip in adapter.ips: +- try: +- ip_addr = ifip.ip[0] if isinstance(ifip.ip, tuple) else ifip.ip +- ips.append(ipautil.CheckedIPAddress(ip_addr)) +- logger.debug('IP check successful: %s', ip_addr) +- except ValueError as e: +- logger.debug('IP check failed: %s', e) ++ for interface in interfaces: ++ if_addrs = netifaces.ifaddresses(interface) ++ for family in [netifaces.AF_INET, netifaces.AF_INET6]: ++ for ip in if_addrs.get(family, []): ++ try: ++ ips.append(ipautil.CheckedIPAddress(ip['addr'])) ++ logger.debug('IP check successful: %s', ip['addr']) ++ except ValueError as e: ++ logger.debug('IP check failed: %s', e) + return ips + + +diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py +index b02d58839ed74215d7253fc23be94846d689f91e..6802dde574d179b2d4bf868a2c38546cc01fc46b 100644 +--- a/ipapython/ipautil.py ++++ b/ipapython/ipautil.py +@@ -48,9 +48,9 @@ import six + from six.moves import input + + try: +- import ifaddr ++ import netifaces + except ImportError: +- ifaddr = None ++ netifaces = None + + from ipapython.dn import DN + from ipaplatform.paths import paths +@@ -203,37 +203,42 @@ class CheckedIPAddress(UnsafeIPAddress): + :return: InterfaceDetails named tuple or None if no interface has + this address + """ +- if ifaddr is None: +- raise ImportError("ifaddr") ++ if netifaces is None: ++ raise ImportError("netifaces") + logger.debug("Searching for an interface of IP address: %s", self) +- + if self.version == 4: +- family_ips = ( +- (ip.ip, ip.network_prefix, ip.nice_name) +- for ips in [a.ips for a in ifaddr.get_adapters()] +- for ip in ips if not isinstance(ip.ip, tuple) +- ) ++ family = netifaces.AF_INET + elif self.version == 6: +- family_ips = ( +- (ip.ip[0], ip.network_prefix, ip.nice_name) +- for ips in [a.ips for a in ifaddr.get_adapters()] +- for ip in ips if isinstance(ip.ip, tuple) +- ) ++ family = netifaces.AF_INET6 + else: + raise ValueError( + "Unsupported address family ({})".format(self.version) + ) + +- for ip, prefix, ifname in family_ips: +- ifaddrmask = "{ip}/{prefix}".format(ip=ip, prefix=prefix) +- logger.debug( +- "Testing local IP address: %s (interface: %s)", +- ifaddrmask, ifname) +- ifnet = netaddr.IPNetwork(ifaddrmask) ++ for interface in netifaces.interfaces(): ++ for ifdata in netifaces.ifaddresses(interface).get(family, []): ++ ++ # link-local addresses contain '%suffix' that causes parse ++ # errors in IPNetwork ++ ifaddr = ifdata['addr'].split(u'%', 1)[0] ++ ++ # newer versions of netifaces provide IPv6 netmask in format ++ # 'ffff:ffff:ffff:ffff::/64'. We have to split and use prefix ++ # or the netmask with older versions ++ ifmask = ifdata['netmask'].split(u'/')[-1] ++ ++ ifaddrmask = '{addr}/{netmask}'.format( ++ addr=ifaddr, ++ netmask=ifmask ++ ) ++ logger.debug( ++ "Testing local IP address: %s (interface: %s)", ++ ifaddrmask, interface) + +- if ifnet.ip == self: +- return InterfaceDetails(ifname, ifnet) ++ ifnet = netaddr.IPNetwork(ifaddrmask) + ++ if ifnet.ip == self: ++ return InterfaceDetails(interface, ifnet) + return None + + def set_ip_net(self, ifnet): +diff --git a/ipapython/setup.py b/ipapython/setup.py +index b7b25c8b480f0dc80ae20c4027554b27fe6d87b3..ea55f5c729e8ba65a4436ebf3eb4898870558648 100644 +--- a/ipapython/setup.py ++++ b/ipapython/setup.py +@@ -48,6 +48,6 @@ if __name__ == '__main__': + extras_require={ + "ldap": ["python-ldap"], # ipapython.ipaldap + # CheckedIPAddress.get_matching_interface +- "ifaddr": ["ifaddr"], ++ "netifaces": ["netifaces"], + }, + ) +diff --git a/ipasetup.py.in b/ipasetup.py.in +index 56a1f3b066c70385949c86d0d35ce393331ad1c5..25eac3b214b4e6443fe29dd3d656c2fdbe84343a 100644 +--- a/ipasetup.py.in ++++ b/ipasetup.py.in +@@ -75,7 +75,7 @@ PACKAGE_VERSION = { + 'ipaserver': 'ipaserver == {}'.format(VERSION), + 'jwcrypto': 'jwcrypto >= 0.4.2', + 'kdcproxy': 'kdcproxy >= 0.3', +- 'ifaddr': 'ifaddr >= 0.1.7', ++ 'netifaces': 'netifaces >= 0.10.4', + 'python-ldap': 'python-ldap >= 3.0.0', + 'python-yubico': 'python-yubico >= 1.2.3', + 'qrcode': 'qrcode >= 5.0', +diff --git a/pylintrc b/pylintrc +index 50278cc76031af68959a138f6ea185c4288c7155..22053a9b55e9dc8e71c1835a63c9393e8ad6803d 100644 +--- a/pylintrc ++++ b/pylintrc +@@ -13,6 +13,7 @@ extension-pkg-allow-list= + _ldap, + cryptography, + gssapi, ++ netifaces, + lxml.etree, + pysss_murmur, + +-- +2.45.1 + diff --git a/0001-Revert-cert_find-fix-call-with-all.patch b/0001-Revert-cert_find-fix-call-with-all.patch deleted file mode 100644 index f81b3b7..0000000 --- a/0001-Revert-cert_find-fix-call-with-all.patch +++ /dev/null @@ -1,107 +0,0 @@ -From a44fd5a7691d263d670312e0c8e02efd868618c1 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Tue, 6 Jun 2023 17:15:11 +0200 -Subject: [PATCH] Revert "cert_find: fix call with --all" - -This reverts commit 918b6e011795ba4854d178d18c86ad54f3cf75ab. - -Revert "Use the OpenSSL certificate parser in cert-find" - -This reverts commit 50dd79d1a35549034bc281fbdffea4399baed3c7. ---- - freeipa.spec.in | 2 -- - ipaserver/plugins/cert.py | 27 +++------------------------ - 2 files changed, 3 insertions(+), 26 deletions(-) - -diff --git a/freeipa.spec.in b/freeipa.spec.in -index 3e23bbfe9d054a3a9febf468de0bcb4a6e81bb32..bec9780a82fe0d9bc5a50a93bdce8aa7e27a9f30 100755 ---- a/freeipa.spec.in -+++ b/freeipa.spec.in -@@ -412,7 +412,6 @@ BuildRequires: python3-pylint - BuildRequires: python3-pytest-multihost - BuildRequires: python3-pytest-sourceorder - BuildRequires: python3-qrcode-core >= 5.0.0 --BuildRequires: python3-pyOpenSSL - BuildRequires: python3-samba - BuildRequires: python3-six - BuildRequires: python3-sss -@@ -884,7 +883,6 @@ Requires: python3-netifaces >= 0.10.4 - Requires: python3-pyasn1 >= 0.3.2-2 - Requires: python3-pyasn1-modules >= 0.3.2-2 - Requires: python3-pyusb --Requires: python3-pyOpenSSL - Requires: python3-qrcode-core >= 5.0.0 - Requires: python3-requests - Requires: python3-six -diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py -index 400b1b3cec0aba82e699a4a981516e121f3e0c77..36a0e8cb31b4dbdd9bff09165d1d8aa203936d37 100644 ---- a/ipaserver/plugins/cert.py -+++ b/ipaserver/plugins/cert.py -@@ -30,7 +30,6 @@ import cryptography.x509 - from cryptography.hazmat.primitives import hashes, serialization - from dns import resolver, reversename - import six --import sys - - from ipalib import Command, Str, Int, Flag, StrEnum, SerialNumber - from ipalib import api -@@ -1618,19 +1617,7 @@ class cert_find(Search, CertMethod): - ) - - def _get_cert_key(self, cert): -- # for cert-find with a certificate value -- if isinstance(cert, x509.IPACertificate): -- return (DN(cert.issuer), cert.serial_number) -- -- issuer = [] -- for oid, value in cert.get_issuer().get_components(): -- issuer.append( -- '{}={}'.format(oid.decode('utf-8'), value.decode('utf-8')) -- ) -- issuer = ','.join(issuer) -- # Use this to flip from OpenSSL reverse to X500 ordering -- issuer = DN(issuer).x500_text() -- return (DN(issuer), cert.get_serial_number()) -+ return (DN(cert.issuer), cert.serial_number) - - def _cert_search(self, pkey_only, **options): - result = collections.OrderedDict() -@@ -1750,11 +1737,6 @@ class cert_find(Search, CertMethod): - return result, False, complete - - def _ldap_search(self, all, pkey_only, no_members, **options): -- # defer import of the OpenSSL module to not affect the requests -- # module which will use pyopenssl if this is available. -- if sys.modules.get('OpenSSL.SSL', False) is None: -- del sys.modules["OpenSSL.SSL"] -- import OpenSSL.crypto - ldap = self.api.Backend.ldap2 - - filters = [] -@@ -1813,21 +1795,18 @@ class cert_find(Search, CertMethod): - ca_enabled = getattr(context, 'ca_enabled') - for entry in entries: - for attr in ('usercertificate', 'usercertificate;binary'): -- for der in entry.raw.get(attr, []): -- cert = OpenSSL.crypto.load_certificate( -- OpenSSL.crypto.FILETYPE_ASN1, der) -+ for cert in entry.get(attr, []): - cert_key = self._get_cert_key(cert) - try: - obj = result[cert_key] - except KeyError: -- obj = {'serial_number': cert.get_serial_number()} -+ obj = {'serial_number': cert.serial_number} - if not pkey_only and (all or not ca_enabled): - # Retrieving certificate details is now deferred - # until after all certificates are collected. - # For the case of CA-less we need to keep - # the certificate because getting it again later - # would require unnecessary LDAP searches. -- cert = cert.to_cryptography() - obj['certificate'] = ( - base64.b64encode( - cert.public_bytes(x509.Encoding.DER)) --- -2.40.1 - diff --git a/0001-Use-ssl.match_hostname-from-urllib3-as-it-was-remove.patch b/0001-Use-ssl.match_hostname-from-urllib3-as-it-was-remove.patch deleted file mode 100644 index 4a65e09..0000000 --- a/0001-Use-ssl.match_hostname-from-urllib3-as-it-was-remove.patch +++ /dev/null @@ -1,82 +0,0 @@ -From a96dae1a9918cfc1413e199336eece447920ef8e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Wed, 5 Jul 2023 08:52:59 +0200 -Subject: [PATCH] Use ssl.match_hostname from urllib3 as it was removed from - Python 3.12 - -See https://pagure.io/freeipa/issue/9409 -and https://github.com/python/cpython/pull/94224#issuecomment-1621097418 ---- - ipalib/x509.py | 5 +++-- - ipaserver/install/cainstance.py | 4 +++- - ipaserver/install/server/upgrade.py | 4 +++- - 3 files changed, 9 insertions(+), 4 deletions(-) - -diff --git a/ipalib/x509.py b/ipalib/x509.py -index 5adb511..faf62d4 100644 ---- a/ipalib/x509.py -+++ b/ipalib/x509.py -@@ -385,6 +385,8 @@ class IPACertificate(crypto_x509.Certificate): - return result - - def match_hostname(self, hostname): -+ from urllib3.util import ssl_match_hostname -+ - match_cert = {} - - match_cert['subject'] = match_subject = [] -@@ -401,8 +403,7 @@ class IPACertificate(crypto_x509.Certificate): - for value in values: - match_san.append(('DNS', value)) - -- # deprecated in Python3.7 without replacement -- ssl.match_hostname( # pylint: disable=deprecated-method -+ ssl_match_hostname.match_hostname( - match_cert, DNSName(hostname).ToASCII() - ) - -diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py -index fa8942d..e9f3ecb 100644 ---- a/ipaserver/install/cainstance.py -+++ b/ipaserver/install/cainstance.py -@@ -2373,12 +2373,14 @@ def check_ipa_ca_san(cert): - - On success returns None, on failure raises ValidationError - """ -+ from urllib3.util import ssl_match_hostname -+ - expect = f'{ipalib.constants.IPA_CA_RECORD}.' \ - f'{ipautil.format_netloc(api.env.domain)}' - - try: - cert.match_hostname(expect) -- except ssl.CertificateError: -+ except ssl_match_hostname.CertificateError: - raise errors.ValidationError( - name='certificate', - error='Does not have a \'{}\' SAN'.format(expect) -diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py -index f8701c8..9e5f5aa 100644 ---- a/ipaserver/install/server/upgrade.py -+++ b/ipaserver/install/server/upgrade.py -@@ -710,6 +710,8 @@ def http_certificate_ensure_ipa_ca_dnsname(http): - steps. - - """ -+ from urllib3.util import ssl_match_hostname -+ - logger.info('[Adding ipa-ca alias to HTTP certificate]') - - expect = f'{IPA_CA_RECORD}.{ipautil.format_netloc(api.env.domain)}' -@@ -717,7 +719,7 @@ def http_certificate_ensure_ipa_ca_dnsname(http): - - try: - cert.match_hostname(expect) -- except ssl.CertificateError: -+ except ssl_match_hostname.CertificateError: - if certs.is_ipa_issued_cert(api, cert): - request_id = certmonger.get_request_id( - {'cert-file': paths.HTTPD_CERT_FILE}) --- -2.40.1 - diff --git a/0001-ipa-client-install-enable-SELinux-for-SSSD.patch b/0001-ipa-client-install-enable-SELinux-for-SSSD.patch deleted file mode 100644 index 723f0d7..0000000 --- a/0001-ipa-client-install-enable-SELinux-for-SSSD.patch +++ /dev/null @@ -1,140 +0,0 @@ -From d355761f23fae412bb01a1d737cee342c7bd04f9 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 29 Aug 2023 12:37:57 +0300 -Subject: [PATCH] ipa-client-install: enable SELinux for SSSD - -For passkeys (FIDO2) support, SSSD uses libfido2 library which needs -access to USB devices. Add SELinux booleans handling to ipa-client-install -so that correct SELinux booleans can be enabled and disabled during -install and uninstall. Ignore and record a warning when SELinux policy -does not support the boolean. - -Fixes: https://pagure.io/freeipa/issue/9434 - -Signed-off-by: Alexander Bokovoy -Reviewed-By: Francisco Trivino -Reviewed-By: Rob Crittenden ---- - ipaclient/install/client.py | 35 ++++++++++++++++++++++++++++++++++- - ipaplatform/base/constants.py | 3 +++ - 2 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py -index 07d62a748..1aaa4ed60 100644 ---- a/ipaclient/install/client.py -+++ b/ipaclient/install/client.py -@@ -67,6 +67,7 @@ from ipapython.ipautil import ( - ) - from ipapython.ssh import SSHPublicKey - from ipapython import version -+from ipapython.errors import SetseboolError - - from . import automount, timeconf, sssd - from ipaclient import discovery -@@ -98,6 +99,7 @@ cli_realm = None - cli_kdc = None - client_domain = None - cli_basedn = None -+selinux_works = None - # end of global variables - - -@@ -2153,6 +2155,7 @@ def install_check(options): - global cli_kdc - global client_domain - global cli_basedn -+ global selinux_works - - print("This program will set up IPA client.") - print("Version {}".format(version.VERSION)) -@@ -2166,7 +2169,7 @@ def install_check(options): - "You must be root to run ipa-client-install.", - rval=CLIENT_INSTALL_ERROR) - -- tasks.check_selinux_status() -+ selinux_works = tasks.check_selinux_status() - - if is_ipa_client_configured(on_master=options.on_master): - logger.error("IPA client is already configured on this system.") -@@ -2674,6 +2677,20 @@ def restore_time_sync(statestore, fstore): - logger.error('Failed to restore time synchronization service: %s', e) - - -+def configure_selinux_for_client(statestore): -+ def backup_state(key, value): -+ statestore.backup_state('selinux', key, value) -+ -+ try: -+ tasks.set_selinux_booleans(constants.SELINUX_BOOLEAN_SSSD, -+ backup_state) -+ except SetseboolError as e: -+ for c in constants.SELINUX_BOOLEAN_SSSD: -+ if c in e.failed: -+ logger.warning( -+ "SELinux does not support SSSD boolean %s, ignoring", c) -+ -+ - def install(options): - try: - _install(options, dict()) -@@ -3198,6 +3215,9 @@ def _install(options, tdict): - logger.info("%s enabled", "SSSD" if options.sssd else "LDAP") - - if options.sssd: -+ if selinux_works: -+ configure_selinux_for_client(statestore) -+ - sssd = services.service('sssd', api) - try: - sssd.restart() -@@ -3322,6 +3342,8 @@ def _install(options, tdict): - - - def uninstall_check(options): -+ global selinux_works -+ - if not is_ipa_client_configured(): - if options.on_master: - rval = SUCCESS -@@ -3337,6 +3359,8 @@ def uninstall_check(options): - logger.info("Refer to ipa-server-install for uninstallation.") - raise ScriptError(rval=CLIENT_NOT_CONFIGURED) - -+ selinux_works = tasks.check_selinux_status() -+ - - def uninstall(options): - env = {'PATH': SECURE_PATH} -@@ -3600,6 +3624,15 @@ def uninstall(options): - "Failed to disable automatic startup of the SSSD daemon: %s", - e) - -+ if was_sssd_installed and selinux_works: -+ # Restore SELinux boolean states -+ boolean_states = {name: statestore.restore_state('selinux', name) -+ for name in constants.SELINUX_BOOLEAN_SSSD} -+ try: -+ tasks.set_selinux_booleans(boolean_states) -+ except SetseboolError as e: -+ logger.warning("Unable to reset SELinux variable: %s", str(e)) -+ - tasks.restore_hostname(fstore, statestore) - - if fstore.has_files(): -diff --git a/ipaplatform/base/constants.py b/ipaplatform/base/constants.py -index 61b864376..1689efe52 100644 ---- a/ipaplatform/base/constants.py -+++ b/ipaplatform/base/constants.py -@@ -151,6 +151,9 @@ class BaseConstantsNamespace: - 'samba_share_nfs': 'on', - }, - } -+ SELINUX_BOOLEAN_SSSD = { -+ 'sssd_use_usb': 'on', -+ } - SELINUX_MCS_MAX = 1023 - SELINUX_MCS_REGEX = r"^c(\d+)([.,-]c(\d+))*$" - SELINUX_MLS_MAX = 15 --- -2.41.0 - diff --git a/0002-selinux-usb-access.patch b/0002-selinux-usb-access.patch deleted file mode 100644 index 4846361..0000000 --- a/0002-selinux-usb-access.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5fe447532f573fc3f73511073070f5dfe6b6535a Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Fri, 15 Sep 2023 10:12:16 +0300 -Subject: [PATCH] Allow ipa-otpd to access USB devices for passkeys - -Main SELinux policy will allow transition of passkey_child (SSSD) to -ipa_otpd_t context to perform FIDO2 operations with USB devices. -This means ipa-otpd will need to be able to read data from sysfs and -connect to USB devices. - -Add required permissions to IPA subpolicy as well. See rhbz#2238224 for -discussion. - -Related: https://pagure.io/freeipa/issue/9434 - -Signed-off-by: Alexander Bokovoy ---- - selinux/ipa.te | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/selinux/ipa.te b/selinux/ipa.te -index 92e6b295b19..c8a44b64e82 100644 ---- a/selinux/ipa.te -+++ b/selinux/ipa.te -@@ -106,6 +106,8 @@ corenet_tcp_connect_radius_port(ipa_otpd_t) - - dev_read_urand(ipa_otpd_t) - dev_read_rand(ipa_otpd_t) -+dev_read_sysfs(ipa_otpd_t) -+dev_rw_generic_usb_dev(ipa_otpd_t) - - sysnet_dns_name_resolve(ipa_otpd_t) - diff --git a/0003-kdb-memory-leak.patch b/0003-kdb-memory-leak.patch deleted file mode 100644 index bfb4b07..0000000 --- a/0003-kdb-memory-leak.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 34b58d8ee93ab385c1f3ba1166377fc1008a9c17 Mon Sep 17 00:00:00 2001 -From: Julien Rische -Date: Wed, 24 Jan 2024 15:50:17 +0100 -Subject: [PATCH] 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 ---- - daemons/ipa-kdb/ipa_kdb_mspac.c | 28 +++++++++++++--------------- - 1 file changed, 13 insertions(+), 15 deletions(-) - -diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c -index 1558e2bea..2866304e1 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; --- -2.43.0 - diff --git a/0004-ipa-cli-krb5-crash.patch b/0004-ipa-cli-krb5-crash.patch deleted file mode 100644 index 9a04289..0000000 --- a/0004-ipa-cli-krb5-crash.patch +++ /dev/null @@ -1,247 +0,0 @@ -From 33638de180a8157e369ad6c61f9e3406d9e85404 Mon Sep 17 00:00:00 2001 -From: Stanislav Levin -Date: Tue, 23 Jan 2024 19:12:53 +0300 -Subject: [PATCH 1/3] 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 ---- - ipapython/session_storage.py | 25 ++++++++++++------------- - 1 file changed, 12 insertions(+), 13 deletions(-) - -diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py -index c43ef7d4e..371cf1524 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 --- -2.43.0 - - -From f8a616dc6196324145372713da772fe9b2352e53 Mon Sep 17 00:00:00 2001 -From: Stanislav Levin -Date: Tue, 23 Jan 2024 19:19:43 +0300 -Subject: [PATCH 2/3] 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 ---- - ipapython/session_storage.py | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py -index 371cf1524..dc36f5493 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, --- -2.43.0 - - -From 59b8a9fb7169561c7ba9168fe84f47ae94e5ce23 Mon Sep 17 00:00:00 2001 -From: Stanislav Levin -Date: Tue, 23 Jan 2024 19:52:34 +0300 -Subject: [PATCH 3/3] 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 ---- - ipapython/session_storage.py | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py -index dc36f5493..e890dc9b1 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)) - --- -2.43.0 - diff --git a/0005-pyca-42.0.0-support.patch b/0005-pyca-42.0.0-support.patch deleted file mode 100644 index 8318ac4..0000000 --- a/0005-pyca-42.0.0-support.patch +++ /dev/null @@ -1,424 +0,0 @@ -From fa46b41af42797dba8dcd04b8cacbc78d602ab80 Mon Sep 17 00:00:00 2001 -From: Christian Heimes -Date: Wed, 24 Jan 2024 09:23:22 +0100 -Subject: [PATCH 1/2] Compatibility fix for PyCA cryptography 42.0.0 - -Cryptography 42.0.0 introduced two new abstract properties -`not_valid_before_utc` and `not_valid_after_utc`, which are non-naive UTC -variants of the `not_valid_before` and `not_valid_after` properties. - -The old properties are deprecated. The changeset also modifies code and -tests to use the new `_utc` variants. - -Fixes: https://pagure.io/freeipa/issue/9518 -Signed-off-by: Christian Heimes -Reviewed-By: Florence Blanc-Renaud ---- - ipaclient/install/client.py | 4 ++-- - ipalib/x509.py | 22 +++++++++++++++++++ - ipapython/certdb.py | 15 +++++++------ - ipaserver/install/ipa_cacert_manage.py | 2 +- - ipaserver/install/ipa_cert_fix.py | 12 +++++----- - ipaserver/plugins/cert.py | 4 ++-- - ipaserver/plugins/dogtag.py | 12 +++++----- - ipaserver/plugins/service.py | 5 +++-- - ipatests/test_integration/test_acme.py | 4 ++-- - .../test_integration/test_installation.py | 2 +- - .../test_integration/test_ipa_cert_fix.py | 2 +- - .../test_integration/test_ipahealthcheck.py | 2 +- - ipatests/test_ipalib/test_x509.py | 6 +++++ - 13 files changed, 61 insertions(+), 31 deletions(-) - -diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py -index 976d3821d..5b97a37f2 100644 ---- a/ipaclient/install/client.py -+++ b/ipaclient/install/client.py -@@ -1727,8 +1727,8 @@ def cert_summary(msg, certs, indent=' '): - for cert in certs: - s += '%sSubject: %s\n' % (indent, DN(cert.subject)) - s += '%sIssuer: %s\n' % (indent, DN(cert.issuer)) -- s += '%sValid From: %s\n' % (indent, cert.not_valid_before) -- s += '%sValid Until: %s\n' % (indent, cert.not_valid_after) -+ s += '%sValid From: %s\n' % (indent, cert.not_valid_before_utc) -+ s += '%sValid Until: %s\n' % (indent, cert.not_valid_after_utc) - s += '\n' - s = s[:-1] - -diff --git a/ipalib/x509.py b/ipalib/x509.py -index 769d48007..daeea8195 100644 ---- a/ipalib/x509.py -+++ b/ipalib/x509.py -@@ -272,6 +272,28 @@ class IPACertificate(crypto_x509.Certificate): - def not_valid_after(self): - return self._cert.not_valid_after.replace(tzinfo=datetime.timezone.utc) - -+ if hasattr(crypto_x509.Certificate, "not_valid_before_utc"): -+ # added in python-cryptography 42.0.0 -+ @property -+ def not_valid_before_utc(self): -+ return self._cert.not_valid_before_utc -+ -+ @property -+ def not_valid_after_utc(self): -+ return self._cert.not_valid_after_utc -+ else: -+ @property -+ def not_valid_before_utc(self): -+ return self._cert.not_valid_before.replace( -+ tzinfo=datetime.timezone.utc -+ ) -+ -+ @property -+ def not_valid_after_utc(self): -+ return self._cert.not_valid_after.replace( -+ tzinfo=datetime.timezone.utc -+ ) -+ - @property - def tbs_certificate_bytes(self): - return self._cert.tbs_certificate_bytes -diff --git a/ipapython/certdb.py b/ipapython/certdb.py -index 21af42d23..e3a80bcec 100644 ---- a/ipapython/certdb.py -+++ b/ipapython/certdb.py -@@ -944,19 +944,20 @@ class NSSDatabase: - """Common checks for cert validity - """ - utcnow = datetime.datetime.now(tz=datetime.timezone.utc) -- if cert.not_valid_before > utcnow: -+ if cert.not_valid_before_utc > utcnow: - raise ValueError( -- f"not valid before {cert.not_valid_before} UTC is in the " -- "future." -+ f"not valid before {cert.not_valid_before_utc} UTC is in " -+ "the future." - ) -- if cert.not_valid_after < utcnow: -+ if cert.not_valid_after_utc < utcnow: - raise ValueError( -- f"has expired {cert.not_valid_after} UTC" -+ f"has expired {cert.not_valid_after_utc} UTC" - ) - # make sure the cert does not expire during installation -- if cert.not_valid_after + datetime.timedelta(hours=1) < utcnow: -+ if cert.not_valid_after_utc + datetime.timedelta(hours=1) < utcnow: - raise ValueError( -- f"expires in less than one hour ({cert.not_valid_after} UTC)" -+ f"expires in less than one hour ({cert.not_valid_after_utc} " -+ "UTC)" - ) - - def verify_server_cert_validity(self, nickname, hostname): -diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py -index d371a854b..f6ab736fa 100644 ---- a/ipaserver/install/ipa_cacert_manage.py -+++ b/ipaserver/install/ipa_cacert_manage.py -@@ -558,7 +558,7 @@ class CACertManage(admintool.AdminTool): - - now = datetime.datetime.now(tz=datetime.timezone.utc) - for ca_cert, ca_nickname, _ca_trust_flags in ca_certs: -- if ca_cert.not_valid_after < now: -+ if ca_cert.not_valid_after_utc < now: - expired_certs.append(ca_nickname) - - -diff --git a/ipaserver/install/ipa_cert_fix.py b/ipaserver/install/ipa_cert_fix.py -index 834e9557d..8e02d1e75 100644 ---- a/ipaserver/install/ipa_cert_fix.py -+++ b/ipaserver/install/ipa_cert_fix.py -@@ -208,7 +208,7 @@ def expired_dogtag_certs(now): - except RuntimeError: - pass # unfortunately certdb doesn't give us a better exception - else: -- if cert.not_valid_after <= now: -+ if cert.not_valid_after_utc <= now: - certs.append((certid, cert)) - - return certs -@@ -226,12 +226,12 @@ def expired_ipa_certs(now): - - # IPA RA - cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM) -- if cert.not_valid_after <= now: -+ if cert.not_valid_after_utc <= now: - certs.append((IPACertType.IPARA, cert)) - - # Apache HTTPD - cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE) -- if cert.not_valid_after <= now: -+ if cert.not_valid_after_utc <= now: - if not is_ipa_issued_cert(api, cert): - non_renewed.append((IPACertType.HTTPS, cert)) - else: -@@ -244,7 +244,7 @@ def expired_ipa_certs(now): - ds_nickname = ds.get_server_cert_nickname(serverid) - db = NSSDatabase(nssdir=ds_dbdir) - cert = db.get_cert(ds_nickname) -- if cert.not_valid_after <= now: -+ if cert.not_valid_after_utc <= now: - if not is_ipa_issued_cert(api, cert): - non_renewed.append((IPACertType.LDAPS, cert)) - else: -@@ -252,7 +252,7 @@ def expired_ipa_certs(now): - - # KDC - cert = x509.load_certificate_from_file(paths.KDC_CERT) -- if cert.not_valid_after <= now: -+ if cert.not_valid_after_utc <= now: - if not is_ipa_issued_cert(api, cert): - non_renewed.append((IPACertType.HTTPS, cert)) - else: -@@ -286,7 +286,7 @@ def print_cert_info(context, desc, cert): - print("{} {} certificate:".format(context, desc)) - print(" Subject: {}".format(DN(cert.subject))) - print(" Serial: {}".format(cert.serial_number)) -- print(" Expires: {}".format(cert.not_valid_after)) -+ print(" Expires: {}".format(cert.not_valid_after_utc)) - print() - - -diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py -index 4fb85069a..d52cdc1e2 100644 ---- a/ipaserver/plugins/cert.py -+++ b/ipaserver/plugins/cert.py -@@ -486,9 +486,9 @@ class BaseCertObject(Object): - obj['serial_number'] = str(cert.serial_number) - obj['serial_number_hex'] = '0x%X' % cert.serial_number - obj['valid_not_before'] = x509.format_datetime( -- cert.not_valid_before) -+ cert.not_valid_before_utc) - obj['valid_not_after'] = x509.format_datetime( -- cert.not_valid_after) -+ cert.not_valid_after_utc) - if full: - obj['sha1_fingerprint'] = x509.to_hex_with_colons( - cert.fingerprint(hashes.SHA1())) -diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py -index 7cd51ae58..23667c3dd 100644 ---- a/ipaserver/plugins/dogtag.py -+++ b/ipaserver/plugins/dogtag.py -@@ -1475,14 +1475,14 @@ class ra(rabase.rabase, RestClient): - if issuer_dn: - response_request['issuer'] = issuer_dn - -- not_valid_before = cert.get('NotValidBefore') -- if not_valid_before: -+ not_valid_before_utc = cert.get('NotValidBefore') -+ if not_valid_before_utc: - response_request['valid_not_before'] = ( -- not_valid_before) -+ not_valid_before_utc) - -- not_valid_after = cert.get('NotValidAfter') -- if not_valid_after: -- response_request['valid_not_after'] = (not_valid_after) -+ not_valid_after_utc = cert.get('NotValidAfter') -+ if not_valid_after_utc: -+ response_request['valid_not_after'] = (not_valid_after_utc) - - status = cert.get('Status') - if status: -diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py -index f4b107213..075a1be8a 100644 ---- a/ipaserver/plugins/service.py -+++ b/ipaserver/plugins/service.py -@@ -303,8 +303,9 @@ def set_certificate_attrs(entry_attrs): - entry_attrs['serial_number_hex'] = u'0x%X' % cert.serial_number - entry_attrs['issuer'] = unicode(DN(cert.issuer)) - entry_attrs['valid_not_before'] = x509.format_datetime( -- cert.not_valid_before) -- entry_attrs['valid_not_after'] = x509.format_datetime(cert.not_valid_after) -+ cert.not_valid_before_utc) -+ entry_attrs['valid_not_after'] = x509.format_datetime( -+ cert.not_valid_after_utc) - entry_attrs['sha1_fingerprint'] = x509.to_hex_with_colons( - cert.fingerprint(hashes.SHA1())) - entry_attrs['sha256_fingerprint'] = x509.to_hex_with_colons( -diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py -index ee13eb4a0..8e6243d4c 100644 ---- a/ipatests/test_integration/test_acme.py -+++ b/ipatests/test_integration/test_acme.py -@@ -670,7 +670,7 @@ class TestACMERenew(IntegrationTest): - f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem' - ) - cert = x509.load_pem_x509_certificate(data, backend=default_backend()) -- initial_expiry = cert.not_valid_after -+ initial_expiry = cert.not_valid_after_utc - - self.clients[0].run_command(['certbot', 'renew']) - -@@ -678,7 +678,7 @@ class TestACMERenew(IntegrationTest): - f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem' - ) - cert = x509.load_pem_x509_certificate(data, backend=default_backend()) -- renewed_expiry = cert.not_valid_after -+ renewed_expiry = cert.not_valid_after_utc - - assert initial_expiry != renewed_expiry - -diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py -index 36142447f..217aae019 100644 ---- a/ipatests/test_integration/test_installation.py -+++ b/ipatests/test_integration/test_installation.py -@@ -1565,7 +1565,7 @@ class TestKRAinstallAfterCertRenew(IntegrationTest): - certs = x509.load_certificate_list(cmd.stdout_text.encode('utf-8')) - - # get expiry date of agent cert -- cert_expiry = certs[0].not_valid_after -+ cert_expiry = certs[0].not_valid_after_utc - - # move date to grace period so that certs get renewed - self.master.run_command(['systemctl', 'stop', 'chronyd']) -diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py -index ec9456e51..219e7d0e1 100644 ---- a/ipatests/test_integration/test_ipa_cert_fix.py -+++ b/ipatests/test_integration/test_ipa_cert_fix.py -@@ -92,7 +92,7 @@ def get_cert_expiry(host, nssdb_path, cert_nick): - ]) - data = host.get_file_contents('/root/cert.pem') - cert = x509.load_pem_x509_certificate(data, backend=default_backend()) -- return cert.not_valid_after -+ return cert.not_valid_after_utc - - - @pytest.fixture -diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py -index 40c848988..28200e096 100644 ---- a/ipatests/test_integration/test_ipahealthcheck.py -+++ b/ipatests/test_integration/test_ipahealthcheck.py -@@ -1595,7 +1595,7 @@ class TestIpaHealthCheck(IntegrationTest): - # Pick a cert to find the upcoming expiration - certfile = self.master.get_file_contents(paths.RA_AGENT_PEM) - cert = x509.load_certificate_list(certfile) -- cert_expiry = cert[0].not_valid_after -+ cert_expiry = cert[0].not_valid_after_utc - - # Stop chronyd so it doesn't freak out with time so off - restart_service(self.master, 'chronyd') -diff --git a/ipatests/test_ipalib/test_x509.py b/ipatests/test_ipalib/test_x509.py -index 74287c84a..8ab2ea8c3 100644 ---- a/ipatests/test_ipalib/test_x509.py -+++ b/ipatests/test_ipalib/test_x509.py -@@ -246,6 +246,8 @@ class test_x509: - assert cert.serial_number == 1093 - assert cert.not_valid_before == not_before - assert cert.not_valid_after == not_after -+ assert cert.not_valid_before_utc == not_before -+ assert cert.not_valid_after_utc == not_after - assert cert.san_general_names == [] - assert cert.san_a_label_dns_names == [] - assert cert.extended_key_usage == {'1.3.6.1.5.5.7.3.1'} -@@ -277,6 +279,8 @@ class test_x509: - # ensure the timezone doesn't mess with not_before and not_after - assert cert.not_valid_before == not_before - assert cert.not_valid_after == not_after -+ assert cert.not_valid_before_utc == not_before -+ assert cert.not_valid_after_utc == not_after - - def test_load_pkcs7_pem(self): - certlist = x509.pkcs7_to_certs(good_pkcs7, datatype=x509.PEM) -@@ -312,6 +316,8 @@ class test_x509: - datetime.timezone.utc) - assert cert.not_valid_before == not_before - assert cert.not_valid_after == not_after -+ assert cert.not_valid_before_utc == not_before -+ assert cert.not_valid_after_utc == not_after - assert cert.san_general_names == [DNSName('ipa.demo1.freeipa.org')] - assert cert.san_a_label_dns_names == ['ipa.demo1.freeipa.org'] - assert cert.extended_key_usage == { --- -2.43.0 - - -From 18244d7ec1103ec6fba0f94c385e62dba774ed3d Mon Sep 17 00:00:00 2001 -From: Christian Heimes -Date: Thu, 25 Jan 2024 08:56:11 +0100 -Subject: [PATCH 2/2] test_acme: Use ipalib.x509 - -Use IPA's x509 module instead of `cryptography.x509`. This fixes a -regression which was introduced in commit a45a7a20. - -Related: https://pagure.io/freeipa/issue/9518 -Signed-off-by: Christian Heimes -Reviewed-By: Florence Blanc-Renaud -Reviewed-By: Mohammad Rizwan Yusuf ---- - ipatests/test_integration/test_acme.py | 9 ++++----- - ipatests/test_integration/test_ipa_cert_fix.py | 5 ++--- - 2 files changed, 6 insertions(+), 8 deletions(-) - -diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py -index 8e6243d4c..4032d266a 100644 ---- a/ipatests/test_integration/test_acme.py -+++ b/ipatests/test_integration/test_acme.py -@@ -4,11 +4,10 @@ - - import time - --from cryptography.hazmat.backends import default_backend --from cryptography import x509 - import pytest - - from ipalib.constants import IPA_CA_RECORD -+from ipalib import x509 - from ipatests.test_integration.base import IntegrationTest - from ipatests.pytest_ipa.integration.firewall import Firewall - from ipatests.pytest_ipa.integration import tasks -@@ -278,7 +277,7 @@ class TestACME(CALessBase): - cert_path = \ - f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem' - data = self.clients[0].get_file_contents(cert_path) -- cert = x509.load_pem_x509_certificate(data, backend=default_backend()) -+ cert = x509.load_pem_x509_certificate(data) - - # revoke cert via ACME - self.clients[0].run_command( -@@ -669,7 +668,7 @@ class TestACMERenew(IntegrationTest): - data = self.clients[0].get_file_contents( - f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem' - ) -- cert = x509.load_pem_x509_certificate(data, backend=default_backend()) -+ cert = x509.load_pem_x509_certificate(data) - initial_expiry = cert.not_valid_after_utc - - self.clients[0].run_command(['certbot', 'renew']) -@@ -677,7 +676,7 @@ class TestACMERenew(IntegrationTest): - data = self.clients[0].get_file_contents( - f'/etc/letsencrypt/live/{self.clients[0].hostname}/cert.pem' - ) -- cert = x509.load_pem_x509_certificate(data, backend=default_backend()) -+ cert = x509.load_pem_x509_certificate(data) - renewed_expiry = cert.not_valid_after_utc - - assert initial_expiry != renewed_expiry -diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py -index 219e7d0e1..e6ec30de1 100644 ---- a/ipatests/test_integration/test_ipa_cert_fix.py -+++ b/ipatests/test_integration/test_ipa_cert_fix.py -@@ -5,13 +5,12 @@ - """ - Module provides tests for ipa-cert-fix CLI. - """ --from cryptography.hazmat.backends import default_backend --from cryptography import x509 - from datetime import datetime, date - import pytest - import time - - import logging -+from ipalib import x509 - from ipaplatform.paths import paths - from ipapython.ipaldap import realm_to_serverid - from ipatests.pytest_ipa.integration import tasks -@@ -91,7 +90,7 @@ def get_cert_expiry(host, nssdb_path, cert_nick): - '-o', '/root/cert.pem' - ]) - data = host.get_file_contents('/root/cert.pem') -- cert = x509.load_pem_x509_certificate(data, backend=default_backend()) -+ cert = x509.load_pem_x509_certificate(data) - return cert.not_valid_after_utc - - --- -2.43.0 - diff --git a/0006-ca-affinity-fix.patch b/0006-ca-affinity-fix.patch deleted file mode 100644 index bca4f30..0000000 --- a/0006-ca-affinity-fix.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 5dbb3101cee7a96ec8eef40be8e802d456c0d06c Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Mon, 22 Jan 2024 08:36:27 -0500 -Subject: [PATCH] Server affinity: call ca.install() if there is a CA in the - topology - -This should not have been gated on options.setup_ca because we need -the RA agent on all servers if there is a CA in the topology otherwise -the non-CA servers won't be able to communicate with the CA. - -Fixes: https://pagure.io/freeipa/issue/9510 - -Signed-off-by: Rob Crittenden -Reviewed-By: Florence Blanc-Renaud ---- - ipaserver/install/ca.py | 7 ++++--- - ipaserver/install/server/replicainstall.py | 7 +++++-- - 2 files changed, 9 insertions(+), 5 deletions(-) - -diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py -index c93ae1fce..187f8032b 100644 ---- a/ipaserver/install/ca.py -+++ b/ipaserver/install/ca.py -@@ -387,9 +387,10 @@ def install_step_0(standalone, replica_config, options, custodia): - promote = False - else: - cafile = os.path.join(replica_config.dir, 'cacert.p12') -- custodia.get_ca_keys( -- cafile, -- replica_config.dirman_password) -+ if replica_config.setup_ca: -+ custodia.get_ca_keys( -+ cafile, -+ replica_config.dirman_password) - - ca_signing_algorithm = None - ca_type = None -diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py -index 191913ddb..b3fd27e6a 100644 ---- a/ipaserver/install/server/replicainstall.py -+++ b/ipaserver/install/server/replicainstall.py -@@ -1382,11 +1382,13 @@ def install(installer): - custodia = custodiainstance.get_custodia_instance(config, mode) - custodia.create_instance() - -- if options.setup_ca and ca_enabled: -+ if ca_enabled: - options.realm_name = config.realm_name - options.domain_name = config.domain_name - options.host_name = config.host_name - options.dm_password = config.dirman_password -+ # Always call ca.install() if there is a CA in the topology -+ # to ensure the RA agent is present. - ca.install(False, config, options, custodia=custodia) - - # configure PKINIT now that all required services are in place -@@ -1398,7 +1400,8 @@ def install(installer): - service.print_msg("Finalize replication settings") - ds.finalize_replica_config() - -- if options.setup_kra and kra_enabled: -+ if kra_enabled: -+ # The KRA installer checks for itself the status of setup_kra - kra.install(api, config, options, custodia=custodia) - - service.print_msg("Restarting the KDC") --- -2.43.0 - diff --git a/0008-netbios-defaults.patch b/0008-netbios-defaults.patch deleted file mode 100644 index 524e537..0000000 --- a/0008-netbios-defaults.patch +++ /dev/null @@ -1,35 +0,0 @@ -From eab52d3cda9bbec716008c040551bd11facd0e11 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Wed, 17 Jan 2024 12:27:26 +0200 -Subject: [PATCH] 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 ---- - ipaserver/install/adtrustinstance.py | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py -index d55ba8491..2ff68dfb4 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" % \ --- -2.43.0 - diff --git a/0009-host-keytab-permission.patch b/0009-host-keytab-permission.patch deleted file mode 100644 index 7e96ebe..0000000 --- a/0009-host-keytab-permission.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 3842116185de6ae8714f30b57bd75c7eddde53d8 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Thu, 21 Dec 2023 09:38:57 +0200 -Subject: [PATCH] host: update System: Manage Host Keytab permission - -Since commit 5c0e7a5fb420377dcc06a956695afdcb35196444, a new extended -operation to get a keytab is supposed to be used. This keytab -setting/retrieval extended operation checks access rights of the bound -DN to write to a virtual attribute 'ipaProtectedOperation;write_keys'. - -If the write isn't allowed, the operation is rejected and ipa-getkeytab -tool falls back to an older code that generates the keytab on the client -and forcibly sets to the LDAP entry. For the latter, a check is done to -make sure the bound DN is allowed to write to 'krbPrincipalKey' attribute. - -This fallback should never happen for newer deployments. When enrollemnt -operation is delegated to non-administrative user with the help of 'Host -Enrollment' role, a host can be pre-created or created at enrollment -time, if this non-administrative user has 'Host Administrators' role. In -the latter case a system permission 'System: Manage Host Keytab' grants -write access to 'krbPrincipalKey' attribute but lacks any access to the -virtual attributes expected by the new extended operation. - -There is a second virtual attribute, 'ipaProtectedOperation;read_keys', -that allows to retrieve existing keys for a host. However, during -initial enrollment we do not allow to retrieve and reuse existing -Kerberos key: while 'ipa-getkeytab -r' would give ability to retrieve -the existing key, 'ipa-join' has no way to trigger that operation. -Hence, permission 'System: Manage Host Keytab' will not grant the right -to read the Kerberos key via extended operation used by 'ipa-getkeytab --r'. Such operation can be done later by utilizing 'ipa -service/host-allow-retrieve-keytab' commands. - -Fix 'System: Manage Host Keytab' permission and extend a permission test -to see that we do not fallback to the old extended operation. - -Fixes: https://pagure.io/freeipa/issue/9496 - -Signed-off-by: Alexander Bokovoy -Reviewed-By: Rob Crittenden ---- - ACI.txt | 2 +- - ipaserver/plugins/host.py | 3 ++- - ipatests/test_integration/test_user_permissions.py | 7 +++++++ - 3 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/ACI.txt b/ACI.txt -index e6d6e3d15..236bb4367 100644 ---- a/ACI.txt -+++ b/ACI.txt -@@ -147,7 +147,7 @@ aci: (targetattr = "usercertificate")(targetfilter = "(objectclass=ipahost)")(ve - dn: cn=computers,cn=accounts,dc=ipa,dc=example - aci: (targetattr = "userpassword")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Enrollment Password";allow (write) groupdn = "ldap:///cn=System: Manage Host Enrollment Password,cn=permissions,cn=pbac,dc=ipa,dc=example";) - dn: cn=computers,cn=accounts,dc=ipa,dc=example --aci: (targetattr = "krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(memberOf=cn=ipaservers,cn=hostgroups,cn=accounts,dc=ipa,dc=example))(objectclass=ipahost))")(version 3.0;acl "permission:System: Manage Host Keytab";allow (write) groupdn = "ldap:///cn=System: Manage Host Keytab,cn=permissions,cn=pbac,dc=ipa,dc=example";) -+aci: (targetattr = "ipaprotectedoperation;write_keys || krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(memberOf=cn=ipaservers,cn=hostgroups,cn=accounts,dc=ipa,dc=example))(objectclass=ipahost))")(version 3.0;acl "permission:System: Manage Host Keytab";allow (write) groupdn = "ldap:///cn=System: Manage Host Keytab,cn=permissions,cn=pbac,dc=ipa,dc=example";) - dn: cn=computers,cn=accounts,dc=ipa,dc=example - aci: (targetattr = "createtimestamp || entryusn || ipaallowedtoperform;read_keys || ipaallowedtoperform;write_keys || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Keytab Permissions";allow (compare,read,search,write) groupdn = "ldap:///cn=System: Manage Host Keytab Permissions,cn=permissions,cn=pbac,dc=ipa,dc=example";) - dn: cn=computers,cn=accounts,dc=ipa,dc=example -diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py -index 3ef510edc..b02c8b55f 100644 ---- a/ipaserver/plugins/host.py -+++ b/ipaserver/plugins/host.py -@@ -409,7 +409,8 @@ class host(LDAPObject): - api.env.container_hostgroup, - api.env.basedn), - ], -- 'ipapermdefaultattr': {'krblastpwdchange', 'krbprincipalkey'}, -+ 'ipapermdefaultattr': {'krblastpwdchange', 'krbprincipalkey', -+ 'ipaprotectedoperation;write_keys'}, - 'replaces': [ - '(targetattr = "krbprincipalkey || krblastpwdchange")(target = "ldap:///fqdn=*,cn=computers,cn=accounts,$SUFFIX")(version 3.0;acl "permission:Manage host keytab";allow (write) groupdn = "ldap:///cn=Manage host keytab,cn=permissions,cn=pbac,$SUFFIX";)', - ], -diff --git a/ipatests/test_integration/test_user_permissions.py b/ipatests/test_integration/test_user_permissions.py -index 3333a4f6b..cd1096ff3 100644 ---- a/ipatests/test_integration/test_user_permissions.py -+++ b/ipatests/test_integration/test_user_permissions.py -@@ -277,6 +277,9 @@ class TestInstallClientNoAdmin(IntegrationTest): - self.master.run_command(['ipa', 'privilege-add-permission', - '--permissions', 'System: Add Hosts', - 'Add Hosts']) -+ self.master.run_command(['ipa', 'privilege-add-permission', -+ '--permissions', 'System: Manage Host Keytab', -+ 'Add Hosts']) - - self.master.run_command(['ipa', 'role-add-privilege', 'useradmin', - '--privileges', 'Host Enrollment']) -@@ -301,6 +304,10 @@ class TestInstallClientNoAdmin(IntegrationTest): - encoding='utf-8') - assert msg in install_log - -+ # Make sure we do not fallback to an old keytab retrieval method anymore -+ msg = "Retrying with pre-4.0 keytab retrieval method..." -+ assert msg not in install_log -+ - # check that user is able to request a host cert, too - result = tasks.run_certutil(client, ['-L'], paths.IPA_NSSDB_DIR) - assert 'Local IPA host' in result.stdout_text --- -2.43.0 - diff --git a/0010-support-samba-4.20.patch b/0010-support-samba-4.20.patch deleted file mode 100644 index a716385..0000000 --- a/0010-support-samba-4.20.patch +++ /dev/null @@ -1,50 +0,0 @@ -From f8b444c563094173c17c3327d72ce9b70da254af Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 30 Jan 2024 19:58:05 +0200 -Subject: [PATCH] ipa-kdb: support Samba 4.20 private libraries - -Samba 4.20 will change name extension of the private libraries from -'samba4' to 'private-samba'. Detect private extension through configure -step and make sure to use the right library name in Makefile. - -Signed-off-by: Alexander Bokovoy ---- - daemons/ipa-kdb/Makefile.am | 2 +- - server.m4 | 8 ++++++++ - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/daemons/ipa-kdb/Makefile.am b/daemons/ipa-kdb/Makefile.am -index 777c6b4bd..ca1593bc8 100644 ---- a/daemons/ipa-kdb/Makefile.am -+++ b/daemons/ipa-kdb/Makefile.am -@@ -116,7 +116,7 @@ ipa_kdb_tests_LDADD = \ - $(top_builddir)/util/libutil.la \ - -lkdb5 \ - -lsss_idmap \ -- -lsamba-security-samba4 \ -+ -l$(SAMBA_SECURITY_LIBS)\ - -lsamba-errors \ - $(NULL) - -diff --git a/server.m4 b/server.m4 -index 2ee2cf519..f97ceddea 100644 ---- a/server.m4 -+++ b/server.m4 -@@ -182,6 +182,14 @@ AC_CHECK_LIB([smbldap],[smbldap_set_bind_callback], - [AC_DEFINE([HAVE_SMBLDAP_SET_BIND_CALLBACK], [1], [struct smbldap_state is opaque])], - [AC_MSG_WARN([libsmbldap is not opaque, not using smbldap_set_bind_callback])], - [$SAMBA40EXTRA_LIBPATH]) -+AC_CHECK_LIB([samba-security-private-samba],[dom_sid_string], -+ [SAMBA_SECURITY_LIBS=samba-security-private-samba], -+ [AC_CHECK_LIB([samba-security-samba4],[dom_sid_string], -+ [SAMBA_SECURITY_LIBS=samba-security-samba4], -+ [AC_MSG_ERROR([Cannot find private samba-security library])], -+ [$SAMBA40EXTRA_LIBPATH])], -+ [$SAMBA40EXTRA_LIBPATH]) -+AC_SUBST(SAMBA_SECURITY_LIBS) - - dnl --------------------------------------------------------------------------- - dnl Check for libunistring --- -2.43.0 - diff --git a/freeipa-4.11-pki-revocation-changes.patch b/freeipa-4.11-pki-revocation-changes.patch deleted file mode 100644 index 0519ae4..0000000 --- a/freeipa-4.11-pki-revocation-changes.patch +++ /dev/null @@ -1,153 +0,0 @@ -From d4271391adc45c781092db0fb89b802743a9dda8 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Mon, 11 Sep 2023 21:37:05 +0000 -Subject: [PATCH 1/2] The PKI JSON API the revocation reason key may be - case-sensitive - -PKI 11.4.0 changed the reason keyword in the REST API from lower-case -to camel-case in https://github.com/dogtagpki/pki/commit/926eb221ce6 - -Use Reason instead of reason as the keyword for revocations -for PKI 11.4.0+ - -Related: https://pagure.io/freeipa/issue/9345 - -Signed-off-by: Rob Crittenden -Reviewed-By: Florence Blanc-Renaud -Reviewed-By: Thomas Woerner ---- - ipaserver/plugins/dogtag.py | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py -index 1c2c51824..0036803c8 100644 ---- a/ipaserver/plugins/dogtag.py -+++ b/ipaserver/plugins/dogtag.py -@@ -274,6 +274,8 @@ if six.PY3: - - logger = logging.getLogger(__name__) - -+pki_version = pki.util.Version(pki.specification_version()) -+ - # These are general status return values used when - # CMSServlet.outputError() is invoked. - CMS_SUCCESS = 0 -@@ -1130,7 +1132,11 @@ class ra(rabase.rabase, RestClient): - serial_number = int(serial_number, 0) - - path = 'agent/certs/{}/revoke'.format(serial_number) -- data = '{{"reason":"{}"}}'.format(reasons[revocation_reason]) -+ if pki_version < pki.util.Version("11.4.0"): -+ keyword = "reason" -+ else: -+ keyword = "Reason" -+ data = '{{"{}":"{}"}}'.format(keyword, reasons[revocation_reason]) - - http_status, _http_headers, http_body = self._ssldo( - 'POST', path, --- -2.41.0 - - -From 0539d97f3e9d2b7d80549ff08d78fe55afcc2dbb Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Thu, 26 Oct 2023 13:59:21 -0400 -Subject: [PATCH 2/2] WIP: Get the PKI version from the remote to determine the - argument - -Reviewed-By: Florence Blanc-Renaud -Reviewed-By: Thomas Woerner ---- - ipaserver/plugins/dogtag.py | 55 ++++++++++++++++++++++++++++++++----- - 1 file changed, 48 insertions(+), 7 deletions(-) - -diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py -index 0036803c8..7cd51ae58 100644 ---- a/ipaserver/plugins/dogtag.py -+++ b/ipaserver/plugins/dogtag.py -@@ -274,8 +274,6 @@ if six.PY3: - - logger = logging.getLogger(__name__) - --pki_version = pki.util.Version(pki.specification_version()) -- - # These are general status return values used when - # CMSServlet.outputError() is invoked. - CMS_SUCCESS = 0 -@@ -1059,6 +1057,39 @@ class ra(rabase.rabase, RestClient): - - return cmd_result - -+ def get_pki_version(self): -+ """ -+ Retrieve the version of a remote PKI server. -+ -+ The REST API request is a GET to the info URI: -+ GET /pki/rest/info HTTP/1.1 -+ -+ The response is: {"Version":"11.5.0","Attributes":{"Attribute":[]}} -+ """ -+ path = "/pki/rest/info" -+ logger.debug('%s.get_pki_version()', type(self).__name__) -+ http_status, _http_headers, http_body = self._ssldo( -+ 'GET', path, -+ headers={ -+ 'Content-Type': 'application/json', -+ 'Accept': 'application/json', -+ }, -+ use_session=False, -+ ) -+ if http_status != 200: -+ self.raise_certificate_operation_error('get_pki_version', -+ detail=http_status) -+ -+ try: -+ response = json.loads(ipautil.decode_json(http_body)) -+ except ValueError as e: -+ logger.debug("Response from CA was not valid JSON: %s", e) -+ raise errors.RemoteRetrieveError( -+ reason=_("Response from CA was not valid JSON") -+ ) -+ -+ return response.get('Version') -+ - - def revoke_certificate(self, serial_number, revocation_reason=0): - """ -@@ -1125,6 +1156,20 @@ class ra(rabase.rabase, RestClient): - detail='7 is not a valid revocation reason' - ) - -+ # dogtag changed the argument case for revocation from -+ # "reason" to "Reason" in PKI 11.4.0. Detect that change -+ # based on the remote version and pass the expected value -+ # in. -+ pki_version = pki.util.Version(self.get_pki_version()) -+ if pki_version is None: -+ self.raise_certificate_operation_error('revoke_certificate', -+ detail="Remove version not " -+ "detected") -+ if pki_version < pki.util.Version("11.4.0"): -+ reason = "reason" -+ else: -+ reason = "Reason" -+ - # Convert serial number to integral type from string to properly handle - # radix issues. Note: the int object constructor will properly handle - # large magnitude integral values by returning a Python long type -@@ -1132,11 +1177,7 @@ class ra(rabase.rabase, RestClient): - serial_number = int(serial_number, 0) - - path = 'agent/certs/{}/revoke'.format(serial_number) -- if pki_version < pki.util.Version("11.4.0"): -- keyword = "reason" -- else: -- keyword = "Reason" -- data = '{{"{}":"{}"}}'.format(keyword, reasons[revocation_reason]) -+ data = '{{"{}":"{}"}}'.format(reason, reasons[revocation_reason]) - - http_status, _http_headers, http_body = self._ssldo( - 'POST', path, --- -2.41.0 - diff --git a/freeipa-4.11-pwpolicy-minlength.patch b/freeipa-4.11-pwpolicy-minlength.patch deleted file mode 100644 index 2920d87..0000000 --- a/freeipa-4.11-pwpolicy-minlength.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 9b0b723a0e62f18d41be53900ab8a3e710708563 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Thu, 18 May 2023 09:23:32 -0400 -Subject: [PATCH] Allow password policy minlength to be removed like other - values - -This is a side-effect of adding the libpwquality options. It -imposes its own hardcoded minimum password length so some care -was needed to ensure that it isn't set too low. - -So if there are no libpwquality options used then it's fine to -have no minlength in the policy. - -Fixes: https://pagure.io/freeipa/issue/9297 - -Signed-off-by: Rob Crittenden -Reviewed-By: Alexander Bokovoy -Reviewed-By: Florence Blanc-Renaud ---- - ipaserver/plugins/pwpolicy.py | 10 +++-- - ipatests/test_integration/test_pwpolicy.py | 45 +++++++++++++++++++++- - 2 files changed, 50 insertions(+), 5 deletions(-) - -diff --git a/ipaserver/plugins/pwpolicy.py b/ipaserver/plugins/pwpolicy.py -index 5ea3e6b78..15cfef45b 100644 ---- a/ipaserver/plugins/pwpolicy.py -+++ b/ipaserver/plugins/pwpolicy.py -@@ -462,6 +462,7 @@ class pwpolicy(LDAPObject): - return False - - has_pwquality_value = False -+ min_length = 0 - if not add: - if len(keys) > 0: - existing_entry = self.api.Command.pwpolicy_show( -@@ -470,14 +471,15 @@ class pwpolicy(LDAPObject): - existing_entry = self.api.Command.pwpolicy_show( - all=True,)['result'] - existing_entry.update(entry_attrs) -- min_length = int(get_val(existing_entry, 'krbpwdminlength')) -- -+ if existing_entry.get('krbpwdminlength'): -+ min_length = int(get_val(existing_entry, 'krbpwdminlength')) - has_pwquality_value = has_pwquality_set(existing_entry) - else: -- min_length = int(get_val(entry_attrs, 'krbpwdminlength')) -+ if entry_attrs.get('krbpwdminlength'): -+ min_length = int(get_val(entry_attrs, 'krbpwdminlength')) - has_pwquality_value = has_pwquality_set(entry_attrs) - -- if min_length and min_length < 6 and has_pwquality_value: -+ if min_length < 6 and has_pwquality_value: - raise errors.ValidationError( - name='minlength', - error=_('Minimum length must be >= 6 if maxrepeat, ' -diff --git a/ipatests/test_integration/test_pwpolicy.py b/ipatests/test_integration/test_pwpolicy.py -index 41d6e9070..652c95e47 100644 ---- a/ipatests/test_integration/test_pwpolicy.py -+++ b/ipatests/test_integration/test_pwpolicy.py -@@ -36,7 +36,9 @@ class TestPWPolicy(IntegrationTest): - cls.master.run_command(['ipa', 'group-add-member', POLICY, - '--users', USER]) - cls.master.run_command(['ipa', 'pwpolicy-add', POLICY, -- '--priority', '1', '--gracelimit', '-1']) -+ '--priority', '1', -+ '--gracelimit', '-1', -+ '--minlength', '6']) - cls.master.run_command(['ipa', 'passwd', USER], - stdin_text='{password}\n{password}\n'.format( - password=PASSWORD -@@ -92,6 +94,12 @@ class TestPWPolicy(IntegrationTest): - "--minlength", "0", - "--minclasses", "0",], - ) -+ # minlength => 6 is required for any of the libpwquality settings -+ self.master.run_command( -+ ["ipa", "pwpolicy-mod", POLICY, -+ "--minlength", "6"], -+ raiseonerr=False, -+ ) - - @pytest.fixture - def reset_pwpolicy(self): -@@ -212,6 +220,7 @@ class TestPWPolicy(IntegrationTest): - assert 'Password is too simple' in \ - result.stdout_text - -+ self.reset_password(self.master) - # test with valid password - for valid in ('Passw0rd', 'password1!', 'Password!'): - self.kinit_as_user(self.master, PASSWORD, valid) -@@ -252,6 +261,40 @@ class TestPWPolicy(IntegrationTest): - assert result.returncode != 0 - assert 'minlength' in result.stderr_text - -+ def test_minlength_empty(self, reset_pwpolicy): -+ """Test that the pwpolicy minlength can be blank -+ """ -+ # Ensure it is set to a non-zero value to avoid EmptyModlist -+ self.master.run_command( -+ ["ipa", "pwpolicy-mod", POLICY, -+ "--minlength", "10",] -+ ) -+ # Enable one of the libpwquality options, removing minlength -+ # should fail. -+ self.master.run_command( -+ ["ipa", "pwpolicy-mod", POLICY, -+ "--maxrepeat", "4",] -+ ) -+ result = self.master.run_command( -+ ["ipa", "pwpolicy-mod", POLICY, -+ "--minlength", "",], raiseonerr=False -+ ) -+ assert result.returncode != 0 -+ -+ # Remove the blocking value -+ self.master.run_command( -+ ["ipa", "pwpolicy-mod", POLICY, -+ "--maxrepeat", "",] -+ ) -+ -+ # Now erase it -+ result = self.master.run_command( -+ ["ipa", "pwpolicy-mod", POLICY, -+ "--minlength", "",] -+ ) -+ assert result.returncode == 0 -+ assert 'minlength' not in result.stderr_text -+ - def test_minlength_add(self): - """Test that adding a new policy with minlength is caught. - """ --- -2.41.0 - diff --git a/freeipa-4.11-py3.12-timezone-changes.patch b/freeipa-4.11-py3.12-timezone-changes.patch deleted file mode 100644 index b90bac3..0000000 --- a/freeipa-4.11-py3.12-timezone-changes.patch +++ /dev/null @@ -1,88 +0,0 @@ -From d9ad56155e76f97ad9326d5c1bcc6e19eea3a0da Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Mon, 9 Oct 2023 13:54:17 +0200 -Subject: [PATCH] ipalib: fix the IPACertificate validity dates - -The class IPACertificate builds objects from x509 Certificate -objects and creates the not_valid_before and not_valid_after values -by converting to a timestamp + applying timezone delta to UTC + reading -from the timestamp. This results in applying twice the delta. - -Use a simpler method that replaces the timezone info with UTC in the -datetime object. - -Fixes: https://pagure.io/freeipa/issue/9462 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipalib/x509.py | 6 ++---- - ipatests/test_ipalib/test_x509.py | 25 +++++++++++++++++++++++++ - 2 files changed, 27 insertions(+), 4 deletions(-) - -diff --git a/ipalib/x509.py b/ipalib/x509.py -index 7396688ae..769d48007 100644 ---- a/ipalib/x509.py -+++ b/ipalib/x509.py -@@ -266,13 +266,11 @@ class IPACertificate(crypto_x509.Certificate): - - @property - def not_valid_before(self): -- return datetime.datetime.fromtimestamp( -- self._cert.not_valid_before.timestamp(), tz=datetime.timezone.utc) -+ return self._cert.not_valid_before.replace(tzinfo=datetime.timezone.utc) - - @property - def not_valid_after(self): -- return datetime.datetime.fromtimestamp( -- self._cert.not_valid_after.timestamp(), tz=datetime.timezone.utc) -+ return self._cert.not_valid_after.replace(tzinfo=datetime.timezone.utc) - - @property - def tbs_certificate_bytes(self): -diff --git a/ipatests/test_ipalib/test_x509.py b/ipatests/test_ipalib/test_x509.py -index c25e8a0b5..74287c84a 100644 ---- a/ipatests/test_ipalib/test_x509.py -+++ b/ipatests/test_ipalib/test_x509.py -@@ -26,6 +26,7 @@ from binascii import hexlify - from configparser import RawConfigParser - import datetime - from io import StringIO -+import os - import pickle - - import pytest -@@ -253,6 +254,30 @@ class test_x509: - b'+\x06\x01\x05\x05\x07\x03\x01' - ) - -+ def test_cert_with_timezone(self): -+ """ -+ Test the not_before and not_after values in a diffent timezone -+ -+ Test for https://pagure.io/freeipa/issue/9462 -+ """ -+ # Store initial timezone, then set to New York -+ tz = os.environ.get('TZ', None) -+ os.environ['TZ'] = 'America/New_York' -+ # Load the cert, extract not before and not after -+ cert = x509.load_pem_x509_certificate(goodcert_headers) -+ not_before = datetime.datetime(2010, 6, 25, 13, 0, 42, 0, -+ datetime.timezone.utc) -+ not_after = datetime.datetime(2015, 6, 25, 13, 0, 42, 0, -+ datetime.timezone.utc) -+ # Reset timezone to previous value -+ if tz: -+ os.environ['TZ'] = tz -+ else: -+ del os.environ['TZ'] -+ # ensure the timezone doesn't mess with not_before and not_after -+ assert cert.not_valid_before == not_before -+ assert cert.not_valid_after == not_after -+ - def test_load_pkcs7_pem(self): - certlist = x509.pkcs7_to_certs(good_pkcs7, datatype=x509.PEM) - assert len(certlist) == 1 --- -2.41.0 - diff --git a/freeipa-4.11-samba-changes.patch b/freeipa-4.11-samba-changes.patch deleted file mode 100644 index 5748efb..0000000 --- a/freeipa-4.11-samba-changes.patch +++ /dev/null @@ -1,80 +0,0 @@ -From d50624dce932d02ea03a00d3ac2ec1be69e8d3b6 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Thu, 19 Oct 2023 12:47:03 +0200 -Subject: [PATCH 1/2] group-add-member fails with an external member - -The command ipa group-add-member --external aduser@addomain.test -fails with an internal error when used with samba 4.19. - -The command internally calls samba.security.dom_sid(sid) which -used to raise a TypeError but now raises a ValueError -(commit 9abdd67 on https://github.com/samba-team/samba). - -IPA source code needs to handle properly both exception types. - -Fixes: https://pagure.io/freeipa/issue/9466 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Rob Crittenden ---- - ipaserver/dcerpc.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py -index 741f0608f..7e585c876 100644 ---- a/ipaserver/dcerpc.py -+++ b/ipaserver/dcerpc.py -@@ -303,7 +303,7 @@ class DomainValidator: - # Parse sid string to see if it is really in a SID format - try: - test_sid = security.dom_sid(sid) -- except TypeError: -+ except (TypeError, ValueError): - raise errors.ValidationError(name='sid', - error=_('SID is not valid')) - --- -2.41.0 - - -From ed6fa6029d863aed1522b449d3360e6c4028e066 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Fri, 20 Oct 2023 10:20:57 +0200 -Subject: [PATCH 2/2] Handle samba changes in samba.security.dom_sid() - -samba.security.dom_sid() in 4.19 now raises ValueError instead of -TypeError. Fix the expected exception. - -Related: https://pagure.io/freeipa/issue/9466 - -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Alexander Bokovoy ---- - ipaserver/dcerpc.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py -index 7e585c876..675572c03 100644 ---- a/ipaserver/dcerpc.py -+++ b/ipaserver/dcerpc.py -@@ -97,7 +97,7 @@ logger = logging.getLogger(__name__) - def is_sid_valid(sid): - try: - security.dom_sid(sid) -- except TypeError: -+ except (TypeError, ValueError): - return False - else: - return True -@@ -457,7 +457,7 @@ class DomainValidator: - try: - test_sid = security.dom_sid(sid) - return unicode(test_sid) -- except TypeError: -+ except (TypeError, ValueError): - raise errors.ValidationError(name=_('trusted domain object'), - error=_('Trusted domain did not ' - 'return a valid SID for ' --- -2.41.0 - diff --git a/freeipa-support-389-ds-with-lmdb-backup.patch b/freeipa-support-389-ds-with-lmdb-backup.patch deleted file mode 100644 index 2766d0b..0000000 --- a/freeipa-support-389-ds-with-lmdb-backup.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 677d30806662856595289525ef529a77adbf2272 Mon Sep 17 00:00:00 2001 -From: Florence Blanc-Renaud -Date: Fri, 26 Jan 2024 13:26:48 +0100 -Subject: [PATCH] ipa-backup: adapt for 389ds switch to LMDB - -ipa-backup is relying on the presence of the directory -/var/lib/dirsrv/slapd-/db/ipaca/ -to detect if the CA is installed on the server and backup -the ipaca backend. - -With the switch to LMDB, this directory does not exist and the -backup is missing ipaca information. - -Use lib389.cli_ctl.dblib.run_dbscan utility instead to -check if ipaca backend is present (this method has been -introduced in 389ds 2.1.0 and works with Berkeley DB and LMDB). - -Fixes: https://pagure.io/freeipa/issue/9516 -Signed-off-by: Florence Blanc-Renaud -Reviewed-By: Alexander Bokovoy -Reviewed-By: Thierry Bordaz ---- - freeipa.spec.in | 7 ++++--- - ipaserver/install/ipa_backup.py | 8 ++++++-- - 2 files changed, 10 insertions(+), 5 deletions(-) - -diff --git a/freeipa.spec.in b/freeipa.spec.in -index a091fee68..997a55d8d 100755 ---- a/freeipa.spec.in -+++ b/freeipa.spec.in -@@ -78,8 +78,8 @@ - %global ds_version 1.4.3.16-12 - %global selinux_policy_version 3.14.3-107 - %else --# DNA interval enabled --%global ds_version 2.0.5-1 -+# version supporting LMDB and lib389.cli_ctl.dblib.run_dbscan utility -+%global ds_version 2.1.0 - %global selinux_policy_version 38.1.1-1 - %endif - -@@ -124,10 +124,11 @@ - - # Make sure to use 389-ds-base versions that fix https://github.com/389ds/389-ds-base/issues/4700 - # and has DNA interval enabled -+# version supporting LMDB and lib389.cli_ctl.dblib.run_dbscan utility - %if 0%{?fedora} < 34 - %global ds_version 1.4.4.16-1 - %else --%global ds_version 2.0.7-1 -+%global ds_version 2.1.0 - %endif - - # Fix for TLS 1.3 PHA, RHBZ#1775146 -diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py -index 2904c9e2e..f4fa73ff5 100644 ---- a/ipaserver/install/ipa_backup.py -+++ b/ipaserver/install/ipa_backup.py -@@ -41,6 +41,7 @@ from ipaserver.install import installutils - from ipapython import ipaldap - from ipaplatform.constants import constants - from ipaplatform.tasks import tasks -+from lib389.cli_ctl.dblib import run_dbscan - - # pylint: disable=import-error - if six.PY3: -@@ -337,8 +338,11 @@ class Backup(admintool.AdminTool): - instance = ipaldap.realm_to_serverid(api.env.realm) - if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % - instance): -- if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE % -- (instance, 'ipaca')): -+ # Check existence of ipaca backend -+ dbpath = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE % -+ (instance, "")) -+ output = run_dbscan(['-L', dbpath]) -+ if 'ipaca/' in output: - self.db2ldif(instance, 'ipaca', online=options.online) - self.db2ldif(instance, 'userRoot', online=options.online) - self.db2bak(instance, online=options.online) --- -2.43.0 - diff --git a/freeipa-support-389-ds-with-lmdb-restore.patch b/freeipa-support-389-ds-with-lmdb-restore.patch deleted file mode 100644 index ef2ee4e..0000000 --- a/freeipa-support-389-ds-with-lmdb-restore.patch +++ /dev/null @@ -1,106 +0,0 @@ -From cb16071635e8c60faa5b6062ed1dd61c3f133fa3 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Wed, 7 Feb 2024 13:42:11 -0500 -Subject: ipa-restore: adapt for 389-ds switch to LMDB - -ipa-restore is relying on the presence of specific directories, -e.g. /var/lib/dirsrv/slapd-/db/ipaca, to detect -which backends are in use (userRoot or ipaca). - -With the switch to LMDB, these directories do not exist and the -restore fails finding the ipaca backend. - -Use lib389.cli_ctl.dblib.run_dbscan utility instead to -check which backends are present. - -This method was been introduced in 389ds 2.1.0 and works with -Berkeley DB and LMDB. - -Fixes: https://pagure.io/freeipa/issue/9526 - -Signed-off-by: Rob Crittenden ---- - ipaserver/install/ipa_restore.py | 45 +++++++++++++++++++++++++++----- - 1 file changed, 38 insertions(+), 7 deletions(-) - -diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py -index 5b7ac61d08f..88b34477049 100644 ---- a/ipaserver/install/ipa_restore.py -+++ b/ipaserver/install/ipa_restore.py -@@ -50,6 +50,8 @@ - from ipaplatform import services - from ipaplatform.paths import paths - -+from lib389.cli_ctl.dblib import run_dbscan -+ - try: - from ipaserver.install import adtrustinstance - except ImportError: -@@ -65,6 +67,29 @@ - - logger = logging.getLogger(__name__) - -+backends = [] # global to save running dbscan multiple times -+ -+ -+def get_backends(db_dir): -+ """Retrieve the set of backends directly from the current database""" -+ global backends -+ -+ if backends: -+ return backends -+ -+ output = run_dbscan(['-L', db_dir]) -+ output = output.replace(db_dir + '/', '') -+ output = output.split('\n') -+ for line in output: -+ if '/' not in line: -+ continue -+ backends.append(line.split('/')[0].strip().lower()) -+ backends = set(backends) -+ if 'changelog' in backends: -+ backends.remove('changelog') -+ -+ return backends -+ - - def recursive_chown(path, uid, gid): - ''' -@@ -295,8 +320,9 @@ def run(self): - if options.backend: - for instance in self.instances: - db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE % -- (instance, options.backend)) -- if os.path.exists(db_dir): -+ (instance, "")) -+ backends = get_backends(db_dir) -+ if options.backend.lower() in backends: - break - else: - raise admintool.ScriptError( -@@ -304,15 +330,20 @@ def run(self): - - self.backends = [options.backend] - -+ missing_backends = [] - for instance, backend in itertools.product(self.instances, - self.backends): - db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE % -- (instance, backend)) -- if os.path.exists(db_dir): -- break -- else: -+ (instance, "")) -+ backends = get_backends(db_dir) -+ if backend.lower() not in backends: -+ missing_backends.append(backend) -+ -+ if missing_backends: - raise admintool.ScriptError( -- "Cannot restore a data backup into an empty system") -+ "Cannot restore a data backup into an empty system. " -+ "Missing backend(s) %s" % ', '.join(missing_backends) -+ ) - - logger.info("Performing %s restore from %s backup", - restore_type, self.backup_type) diff --git a/freeipa.spec b/freeipa.spec index fe2018f..bf6b96b 100644 --- a/freeipa.spec +++ b/freeipa.spec @@ -70,7 +70,7 @@ %global krb5_kdb_version 9.0 # 0.7.16: https://github.com/drkjam/netaddr/issues/71 %global python_netaddr_version 0.7.19 -%global samba_version 4.17.4-101 +%global samba_version 4.20.0 %global slapi_nis_version 0.56.4 %global python_ldap_version 3.1.0-1 %if 0%{?rhel} < 9 @@ -111,9 +111,14 @@ # fix for segfault in python3-ldap, https://pagure.io/freeipa/issue/7324 %global python_ldap_version 3.1.0-1 -# 389-ds-base version that fixes a number of crashes and performance issues -# https://bodhi.fedoraproject.org/updates/FEDORA-2023-9133b9b669 -%global ds_version 2.4.3-1 +# Make sure to use 389-ds-base versions that fix https://github.com/389ds/389-ds-base/issues/4700 +# and has DNA interval enabled +# version supporting LMDB and lib389.cli_ctl.dblib.run_dbscan utility +%if 0%{?fedora} < 34 +%global ds_version 1.4.4.16-1 +%else +%global ds_version 2.1.0 +%endif # Fix for TLS 1.3 PHA, RHBZ#1775146 %global httpd_version 2.4.41-9 @@ -150,7 +155,7 @@ %endif # RHEL 8.3+, F32+ has 0.79.13 -%global certmonger_version 0.79.7-3 +%global certmonger_version 0.79.17-1 # RHEL 8.2+, F32+ has 3.58 %global nss_version 3.44.0-4 @@ -187,7 +192,7 @@ # Work-around fact that RPM SPEC parser does not accept # "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement -%define IPA_VERSION 4.11.1 +%define IPA_VERSION 4.12.0 # Release candidate version -- uncomment with one percent for RC versions #%%global rc_version %define AT_SIGN @ @@ -200,7 +205,7 @@ Name: %{package_name} Version: %{IPA_VERSION} -Release: 4%{?rc_version:.%rc_version}%{?dist} +Release: 1%{?rc_version:.%rc_version}%{?dist} Summary: The Identity, Policy and Audit system License: GPL-3.0-or-later @@ -219,19 +224,6 @@ Source1: https://releases.pagure.org/freeipa/freeipa-%{version}%{?rc_vers Source2: gpgkey-0E63D716D76AC080A4A33513F40800B6298EB963.asc %endif -Patch0001: freeipa-4.11-samba-changes.patch -Patch0002: freeipa-4.11-pki-revocation-changes.patch -Patch0003: freeipa-4.11-py3.12-timezone-changes.patch -Patch0004: freeipa-4.11-pwpolicy-minlength.patch -Patch0005: 0009-host-keytab-permission.patch -Patch0006: 0008-netbios-defaults.patch -Patch0009: 0005-pyca-42.0.0-support.patch -Patch0010: 0004-ipa-cli-krb5-crash.patch -Patch0011: 0003-kdb-memory-leak.patch -Patch0012: 0010-support-samba-4.20.patch -Patch0013: freeipa-support-389-ds-with-lmdb-backup.patch -Patch0014: freeipa-support-389-ds-with-lmdb-restore.patch - # RHEL spec file only: START: Change branding to IPA and Identity Management # Moved branding logos and background to redhat-logos-ipa-80.4: # header-logo.png, login-screen-background.jpg, login-screen-logo.png, @@ -244,7 +236,8 @@ Patch0014: freeipa-support-389-ds-with-lmdb-restore.patch Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch %endif -%if 0%{?rhel} == 9 +%if 0%{?rhel} >= 9 +Patch0001: 0001-Revert-Replace-netifaces-with-ifaddr.patch Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch %endif %endif @@ -279,6 +272,7 @@ BuildRequires: gettext BuildRequires: gettext-devel BuildRequires: python3-devel BuildRequires: python3-setuptools +BuildRequires: python3-argcomplete BuildRequires: systemd >= %{systemd_version} # systemd-tmpfiles which is executed from make install requires apache user BuildRequires: httpd @@ -555,12 +549,8 @@ Requires: python3-pyasn1 >= 0.3.2-2 Requires: python3-sssdconfig >= %{sssd_version} Requires: python3-psutil Requires: rpm-libs -%if 0%{?rhel} -Requires: python3-urllib3 >= 1.24.2-3 -%else # For urllib3.util.ssl_match_hostname Requires: python3-urllib3 >= 1.25.8 -%endif %description -n python3-ipaserver IPA is an integrated solution to provide centrally managed Identity (users, @@ -704,7 +694,7 @@ Requires: oddjob-mkhomedir Requires: libsss_autofs Requires: autofs Requires: libnfsidmap -Requires: nfs-utils +Requires: (nfs-utils or nfsv4-client-utils) Requires: sssd-tools >= %{sssd_version} Requires(post): policycoreutils @@ -863,6 +853,7 @@ Requires: %{name}-common = %{version}-%{release} Requires(pre): python3-ldap >= %{python_ldap_version} Requires: gnupg2 Requires: keyutils +Requires: python3-argcomplete Requires: python3-cffi Requires: python3-cryptography >= 1.6 Requires: python3-dateutil @@ -886,12 +877,9 @@ Requires: platform-python-setuptools %else Requires: python3-setuptools %endif -%if 0%{?rhel} -Requires: python3-urllib3 >= 1.24.2-3 -%else # For urllib3.util.ssl_match_hostname Requires: python3-urllib3 >= 1.25.8 -%endif +Requires: python3-systemd %description -n python3-ipalib IPA is an integrated solution to provide centrally managed Identity (users, @@ -983,6 +971,26 @@ Requires(post): selinux-policy-%{selinuxtype} %description selinux Custom SELinux policy module for FreeIPA + +%package selinux-nfast +Summary: FreeIPA SELinux policy for nCipher nfast HSMs +BuildArch: noarch +Requires: selinux-policy-%{selinuxtype} +Requires(post): selinux-policy-%{selinuxtype} +%{?selinux_requires} + +%description selinux-nfast +Custom SELinux policy module for nCipher nfast HSMs + +%package selinux-luna +Summary: FreeIPA SELinux policy for Thales Luna HSMs +BuildArch: noarch +Requires: selinux-policy-%{selinuxtype} +Requires(post): selinux-policy-%{selinuxtype} +%{?selinux_requires} + +%description selinux-luna +Custom SELinux policy module for Thales Luna HSMs # with selinux %endif @@ -1069,6 +1077,17 @@ rm -f %{buildroot}%{_usr}/share/ipa/ui/images/product-name.png %endif # RHEL spec file only: END +%if ! %{ONLY_CLIENT} +%if 0%{?fedora} >= 38 +# Register CLI tools for bash completion (fedora only) +for clitool in ipa-migrate +do + register-python-argcomplete "${clitool}" > "${clitool}" + install -p -m 0644 -D -t '%{buildroot}%{bash_completions_dir}' "${clitool}" +done +%endif +%endif + %find_lang %{gettext_domain} %if ! %{ONLY_CLIENT} @@ -1132,6 +1151,10 @@ fi /bin/systemctl reload-or-try-restart oddjobd %tmpfiles_create ipa.conf +%journal_catalog_update + +%postun server +%journal_catalog_update %posttrans server # don't execute upgrade and restart of IPA when server is not installed @@ -1268,13 +1291,21 @@ if [ $1 -gt 1 ] ; then cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/kdc-ca-bundle.pem cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/ca-bundle.pem fi - %{__python3} -c 'from ipaclient.install.client import configure_krb5_snippet; configure_krb5_snippet()' >>/var/log/ipaupgrade.log 2>&1 %{__python3} -c 'from ipaclient.install.client import update_ipa_nssdb; update_ipa_nssdb()' >>/var/log/ipaupgrade.log 2>&1 chmod 0600 /var/log/ipaupgrade.log SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config" if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then sed -E --in-place=.orig 's/^(HostKeyAlgorithms ssh-rsa,ssh-dss)$/# disabled by ipa-client update\n# \1/' "$SSH_CLIENT_SYSTEM_CONF" + # https://pagure.io/freeipa/issue/9536 + # replace sss_ssh_knownhostsproxy with sss_ssh_knownhosts + if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then + if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then + SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf" + fi + sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF + sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF + fi fi fi fi @@ -1290,17 +1321,75 @@ fi semodule -d ipa_custodia &> /dev/null || true; %selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2 +%post selinux-nfast +%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-nfast.pp.bz2 + +%post selinux-luna +%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-luna.pp.bz2 + %postun selinux if [ $1 -eq 0 ]; then %selinux_modules_uninstall -s %{selinuxtype} %{modulename} semodule -e ipa_custodia &> /dev/null || true; fi +%postun selinux-nfast +if [ $1 -eq 0 ]; then + %selinux_modules_uninstall -s %{selinuxtype} %{modulename}-nfast +fi + +%postun selinux-luna +if [ $1 -eq 0 ]; then + %selinux_modules_uninstall -s %{selinuxtype} %{modulename}-luna + %posttrans selinux %selinux_relabel_post -s %{selinuxtype} # with_selinux %endif +%triggerin client -- sssd-common < 2.10 +# Has the client been configured? +restore=0 +test -f '/var/lib/ipa-client/sysrestore/sysrestore.index' && restore=$(wc -l '/var/lib/ipa-client/sysrestore/sysrestore.index' | awk '{print $1}') + +if [ -f '/etc/ssh/sshd_config' -a $restore -ge 2 ]; then + SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config" + if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then + # https://pagure.io/freeipa/issue/9536 + # downgrade sss_ssh_knownhosts with sss_ssh_knownhostsproxy + if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then + if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then + SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf" + fi + GLOBALKNOWNHOSTFILE="GlobalKnownHostsFile /var/lib/sss/pubconf/known_hosts/" + grep -qF '$GLOBALKNOWNHOSTFILE' $SSH_CLIENT_SYSTEM_CONF + if [ $? -ne 0 ]; then + sed -E --in-place=.orig '/(# IPA-related configuration changes to ssh_config)/a # added by ipa-client update\n'"$GLOBALKNOWNHOSTFILE"'' $SSH_CLIENT_SYSTEM_CONF + fi + sed -E --in-place=.orig 's/(KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H)/ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h/' $SSH_CLIENT_SYSTEM_CONF + fi + fi +fi + +%triggerin client -- sssd-common >= 2.10 +# Has the client been configured? +restore=0 +test -f '/var/lib/ipa-client/sysrestore/sysrestore.index' && restore=$(wc -l '/var/lib/ipa-client/sysrestore/sysrestore.index' | awk '{print $1}') + +if [ -f '/etc/ssh/sshd_config' -a $restore -ge 2 ]; then + SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config" + if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then + # https://pagure.io/freeipa/issue/9536 + # upgrade sss_ssh_knownhostsproxy with sss_ssh_knownhosts + if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then + if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then + SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf" + fi + sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF + sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF + fi + fi +fi %triggerin client -- openssh-server < 8.2 # Has the client been configured? @@ -1399,6 +1488,10 @@ fi %{_sbindir}/ipa-crlgen-manage %{_sbindir}/ipa-cert-fix %{_sbindir}/ipa-acme-manage +%{_sbindir}/ipa-migrate +%if 0%{?fedora} >= 38 +%{bash_completions_dir}/ipa-migrate +%endif %{_libexecdir}/certmonger/dogtag-ipa-ca-renew-agent-submit %{_libexecdir}/certmonger/ipa-server-guard %dir %{_libexecdir}/ipa @@ -1431,6 +1524,7 @@ fi %attr(644,root,root) %{_unitdir}/ipa-otpd@.service %attr(644,root,root) %{_unitdir}/ipa-ccache-sweep.service %attr(644,root,root) %{_unitdir}/ipa-ccache-sweep.timer +%attr(644,root,root) %{_journalcatalogdir}/ipa.catalog # END %attr(755,root,root) %{plugin_dir}/libipa_pwd_extop.so %attr(755,root,root) %{plugin_dir}/libipa_enrollment_extop.so @@ -1473,6 +1567,7 @@ fi %{_mandir}/man1/ipa-crlgen-manage.1* %{_mandir}/man1/ipa-cert-fix.1* %{_mandir}/man1/ipa-acme-manage.1* +%{_mandir}/man1/ipa-migrate.1* %files -n python3-ipaserver @@ -1747,10 +1842,22 @@ fi %files selinux %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.* %ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename} + +%files selinux-nfast +%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-nfast.pp.* +%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}-nfast + +%files selinux-luna +%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-luna.pp.* +%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}-luna # with selinux %endif %changelog +* Tue Jun 04 2024 Florence Blanc-Renaud - 4.12.0-1 +- Resolves: RHEL-39144 Rebase ipa to the latest 4.12 version for RHEL 10 +- Resolves: RHEL-30537 ipa: freeipa: argument injection into the username field of the /ipa/session/login_password requests + * Thu Feb 22 2024 Troy Dawson - 4.11.1-4 - Bump release to rebuild on correct samba diff --git a/sources b/sources index 9071b2d..1d416e7 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (freeipa-4.11.1.tar.gz) = 65c3ccc8a6da71b2bad3efdf9e798b0d65e6d1e2c3a6ed6617ab86d7e8a5fa01ba2787714a3004b01e35fe087f464e0ae22d0fe4b254956262e7d96d61b1e84d -SHA512 (freeipa-4.11.1.tar.gz.asc) = 31157e852653681d3914aebc4b98babf16c4131f647ed6b4c2b49d07f50ac393f54fb1a9d9fcbcf6772eccf5bae7331912ad3e3508bf8cac7d7e74c676bdbc60 +SHA512 (freeipa-4.12.0.tar.gz) = 1e95250a6892e85b4782a1f2451a99d21c90ce82db2be369d9e0e1706575229d4539b20f8dd2b97da0d6f73f4fb59168ab6e05eb2fe185b4bb854f42c1e7fd29 +SHA512 (freeipa-4.12.0.tar.gz.asc) = 896170fee005acc3cf46b22053d9f0f0e75f0af31af5c9fbd993674dc26549e479ea3468412ff35f947f7cf42bb7b9bf96f1ead21d754eec92a27b30d731dbe1