diff --git a/.gitignore b/.gitignore
index 34c1a4e..d9c893f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/freeipa-4.9.6.tar.gz
+SOURCES/freeipa-4.9.8.tar.gz
diff --git a/.ipa.metadata b/.ipa.metadata
index ab790ce..15ef586 100644
--- a/.ipa.metadata
+++ b/.ipa.metadata
@@ -1 +1 @@
-b7b91082908db35e4acbcd0221b8df4044913dc1 SOURCES/freeipa-4.9.6.tar.gz
+38641a7f95779ba35089fcc10e25ec82a9b0248e SOURCES/freeipa-4.9.8.tar.gz
diff --git a/README.debrand b/README.debrand
deleted file mode 100644
index 01c46d2..0000000
--- a/README.debrand
+++ /dev/null
@@ -1,2 +0,0 @@
-Warning: This package was configured for automatic debranding, but the changes
-failed to apply.
diff --git a/SOURCES/0001-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch b/SOURCES/0001-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
new file mode 100644
index 0000000..943e986
--- /dev/null
+++ b/SOURCES/0001-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
@@ -0,0 +1,70 @@
+From 0d44e959e5bbe822b51137a8e7cf48fa25533805 Mon Sep 17 00:00:00 2001
+From: Rafael Guterres Jeffman <rjeffman@redhat.com>
+Date: Fri, 10 Dec 2021 12:15:36 -0300
+Subject: [PATCH] Revert "freeipa.spec: depend on bind-dnssec-utils"
+
+This reverts commit f89d59b6e18b54967682f6a37ce92ae67ab3fcda.
+---
+ freeipa.spec.in             | 4 +---
+ ipaplatform/base/paths.py   | 2 +-
+ ipaplatform/fedora/paths.py | 1 +
+ ipaserver/dnssec/bindmgr.py | 1 -
+ 4 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index 8f5c370e5..e20edb7bc 100755
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -576,11 +576,9 @@ Requires: %{name}-server = %{version}-%{release}
+ Requires: bind-dyndb-ldap >= 11.2-2
+ Requires: bind >= %{bind_version}
+ Requires: bind-utils >= %{bind_version}
+-# bind-dnssec-utils is required by the OpenDNSSec integration
+-# https://pagure.io/freeipa/issue/9026
+-Requires: bind-dnssec-utils >= %{bind_version}
+ %if %{with bind_pkcs11}
+ Requires: bind-pkcs11 >= %{bind_version}
++Requires: bind-pkcs11-utils >= %{bind_version}
+ %else
+ Requires: softhsm >= %{softhsm_version}
+ Requires: openssl-pkcs11 >= %{openssl_pkcs11_version}
+diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
+index 7d21367ec..42a47f1df 100644
+--- a/ipaplatform/base/paths.py
++++ b/ipaplatform/base/paths.py
+@@ -259,7 +259,7 @@ class BasePathNamespace:
+     IPA_PKI_RETRIEVE_KEY = "/usr/libexec/ipa/ipa-pki-retrieve-key"
+     IPA_HTTPD_PASSWD_READER = "/usr/libexec/ipa/ipa-httpd-pwdreader"
+     IPA_PKI_WAIT_RUNNING = "/usr/libexec/ipa/ipa-pki-wait-running"
+-    DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel"
++    DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel-pkcs11"
+     GETSEBOOL = "/usr/sbin/getsebool"
+     GROUPADD = "/usr/sbin/groupadd"
+     USERMOD = "/usr/sbin/usermod"
+diff --git a/ipaplatform/fedora/paths.py b/ipaplatform/fedora/paths.py
+index 4e993c063..92a948966 100644
+--- a/ipaplatform/fedora/paths.py
++++ b/ipaplatform/fedora/paths.py
+@@ -36,6 +36,7 @@ class FedoraPathNamespace(RedHatPathNamespace):
+     NAMED_CRYPTO_POLICY_FILE = "/etc/crypto-policies/back-ends/bind.config"
+     if HAS_NFS_CONF:
+         SYSCONFIG_NFS = '/etc/nfs.conf'
++    DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel"
+ 
+ 
+ paths = FedoraPathNamespace()
+diff --git a/ipaserver/dnssec/bindmgr.py b/ipaserver/dnssec/bindmgr.py
+index 0c79cc03d..a15c0e601 100644
+--- a/ipaserver/dnssec/bindmgr.py
++++ b/ipaserver/dnssec/bindmgr.py
+@@ -127,7 +127,6 @@ class BINDMgr:
+         )
+         cmd = [
+             paths.DNSSEC_KEYFROMLABEL,
+-            '-E', 'pkcs11',
+             '-K', workdir,
+             '-a', attrs['idnsSecAlgorithm'][0],
+             '-l', uri
+-- 
+2.31.1
+
diff --git a/SOURCES/0001-rpcserver.py-perf_counter_ns-is-Python-3.7_rhbz#1974822.patch b/SOURCES/0001-rpcserver.py-perf_counter_ns-is-Python-3.7_rhbz#1974822.patch
deleted file mode 100644
index 22f37ad..0000000
--- a/SOURCES/0001-rpcserver.py-perf_counter_ns-is-Python-3.7_rhbz#1974822.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From e713c227bb420a841ce3ae146bca55a84a1b0dbf Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fran=C3=A7ois=20Cami?= <fcami@redhat.com>
-Date: Tue, 22 Jun 2021 14:36:51 +0200
-Subject: [PATCH] paths: add IPA_SERVER_CONF
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Related: https://pagure.io/freeipa/issue/8891
-Signed-off-by: François Cami <fcami@redhat.com>
-Reviewed-By: Stanislav Levin <slev@altlinux.org>
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
----
- ipaplatform/base/paths.py | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index 91423b332..de217d9ef 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -71,6 +71,7 @@ class BasePathNamespace:
-     IPA_DEFAULT_CONF = "/etc/ipa/default.conf"
-     IPA_DNSKEYSYNCD_KEYTAB = "/etc/ipa/dnssec/ipa-dnskeysyncd.keytab"
-     IPA_ODS_EXPORTER_KEYTAB = "/etc/ipa/dnssec/ipa-ods-exporter.keytab"
-+    IPA_SERVER_CONF = "/etc/ipa/server.conf"
-     DNSSEC_OPENSSL_CONF = "/etc/ipa/dnssec/openssl.cnf"
-     DNSSEC_SOFTHSM2_CONF = "/etc/ipa/dnssec/softhsm2.conf"
-     DNSSEC_SOFTHSM_PIN_SO = "/etc/ipa/dnssec/softhsm_pin_so"
--- 
-2.31.1
-
-From ee4be290e1583834a573c3896ee1d97b3fbb6c24 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fran=C3=A7ois=20Cami?= <fcami@redhat.com>
-Date: Tue, 22 Jun 2021 14:45:49 +0200
-Subject: [PATCH] ipatests: smoke test for server debug mode.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add a smoke test to make sure the server can be set in debug mode
-without issue.
-
-Related: https://pagure.io/freeipa/issue/8891
-Signed-off-by: François Cami <fcami@redhat.com>
-Reviewed-By: Stanislav Levin <slev@altlinux.org>
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
----
- .../test_integration/test_installation.py     | 27 +++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
-diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
-index 301767b8d..0c96536f0 100644
---- a/ipatests/test_integration/test_installation.py
-+++ b/ipatests/test_integration/test_installation.py
-@@ -703,6 +703,33 @@ class TestInstallMaster(IntegrationTest):
-     def test_install_master(self):
-         tasks.install_master(self.master, setup_dns=False)
- 
-+    @pytest.mark.skip_if_platform(
-+        "debian", reason="This test hardcodes the httpd service name"
-+    )
-+    def test_smoke_test_for_debug_mode(self):
-+        """Test if an IPA server works in debug mode.
-+        Related: https://pagure.io/freeipa/issue/8891
-+
-+        Note: this test hardcodes the "httpd" service name.
-+        """
-+
-+        target_fname = paths.IPA_SERVER_CONF
-+        assert not self.master.transport.file_exists(target_fname)
-+
-+        # set the IPA server in debug mode
-+        server_conf = "[global]\ndebug=True"
-+        self.master.put_file_contents(target_fname, server_conf)
-+        self.master.run_command(["systemctl", "restart", "httpd"])
-+
-+        # smoke test in debug mode
-+        tasks.kdestroy_all(self.master)
-+        tasks.kinit_admin(self.master)
-+        self.master.run_command(["ipa", "user-show", "admin"])
-+
-+        # rollback
-+        self.master.run_command(["rm", target_fname])
-+        self.master.run_command(["systemctl", "restart", "httpd"])
-+
-     def test_schema_compat_attribute_and_tree_disable(self):
-         """Test if schema-compat-entry-attribute is set
- 
--- 
-2.31.1
-
-From 1539c7383116647ad9c5b125b343f972e9c9653b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fran=C3=A7ois=20Cami?= <fcami@redhat.com>
-Date: Wed, 23 Jun 2021 06:35:19 +0200
-Subject: [PATCH] rpcserver.py: perf_counter_ns is Python 3.7+
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-perf_counter_ns is only available in Python 3.7 and later.
-Define a lambda for 3.6 and lower.
-
-Fixes: https://pagure.io/freeipa/issue/8891
-Signed-off-by: François Cami <fcami@redhat.com>
-Reviewed-By: Stanislav Levin <slev@altlinux.org>
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
----
- ipaserver/rpcserver.py | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
-index b121316bf..e612528e0 100644
---- a/ipaserver/rpcserver.py
-+++ b/ipaserver/rpcserver.py
-@@ -31,6 +31,7 @@ import os
- import time
- import traceback
- from io import BytesIO
-+from sys import version_info
- from urllib.parse import parse_qs
- from xmlrpc.client import Fault
- 
-@@ -72,6 +73,10 @@ from requests.auth import AuthBase
- if six.PY3:
-     unicode = str
- 
-+# time.perf_counter_ns appeared in Python 3.7.
-+if version_info < (3, 7):
-+    time.perf_counter_ns = lambda: int(time.perf_counter() * 10**9)
-+
- logger = logging.getLogger(__name__)
- 
- HTTP_STATUS_SUCCESS = '200 Success'
--- 
-2.31.1
-
diff --git a/SOURCES/0002-Add-checks-to-prevent-adding-auth-indicators-to-inte_rhbz#1979625.patch b/SOURCES/0002-Add-checks-to-prevent-adding-auth-indicators-to-inte_rhbz#1979625.patch
deleted file mode 100644
index 81b6c45..0000000
--- a/SOURCES/0002-Add-checks-to-prevent-adding-auth-indicators-to-inte_rhbz#1979625.patch
+++ /dev/null
@@ -1,272 +0,0 @@
-From a5d2857297cfcf87ed8973df96e89ebcef22850d Mon Sep 17 00:00:00 2001
-From: Antonio Torres <antorres@redhat.com>
-Date: Mon, 8 Mar 2021 18:15:50 +0100
-Subject: [PATCH] Add checks to prevent adding auth indicators to internal IPA
- services
-
-Authentication indicators should not be enforced against internal
-IPA services, since not all users of those services are able to produce
-Kerberos tickets with all the auth indicator options. This includes
-host, ldap, HTTP and cifs in IPA server and cifs in IPA clients.
-If a client that is being promoted to replica has an auth indicator
-in its host principal then the promotion is aborted.
-
-Fixes: https://pagure.io/freeipa/issue/8206
-Signed-off-by: Antonio Torres <antorres@redhat.com>
----
- ipaserver/install/server/replicainstall.py | 13 ++++++++++++
- ipaserver/plugins/host.py                  |  5 ++++-
- ipaserver/plugins/service.py               | 24 ++++++++++++++++++++++
- 3 files changed, 41 insertions(+), 1 deletion(-)
-
-diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
-index 73967a224..f1fb91036 100644
---- a/ipaserver/install/server/replicainstall.py
-+++ b/ipaserver/install/server/replicainstall.py
-@@ -770,6 +770,15 @@ def promotion_check_ipa_domain(master_ldap_conn, basedn):
-         ))
- 
- 
-+def promotion_check_host_principal_auth_ind(conn, hostdn):
-+    entry = conn.get_entry(hostdn, ['krbprincipalauthind'])
-+    if 'krbprincipalauthind' in entry:
-+        raise RuntimeError(
-+            "Client cannot be promoted to a replica if the host principal "
-+            "has an authentication indicator set."
-+        )
-+
-+
- @common_cleanup
- @preserve_enrollment_state
- def promote_check(installer):
-@@ -956,6 +965,10 @@ def promote_check(installer):
-                                      config.master_host_name, None)
- 
-         promotion_check_ipa_domain(conn, remote_api.env.basedn)
-+        hostdn = DN(('fqdn', api.env.host),
-+                    api.env.container_host,
-+                    api.env.basedn)
-+        promotion_check_host_principal_auth_ind(conn, hostdn)
- 
-         # Make sure that domain fulfills minimal domain level
-         # requirement
-diff --git a/ipaserver/plugins/host.py b/ipaserver/plugins/host.py
-index eb1f8ef04..41fa933e2 100644
---- a/ipaserver/plugins/host.py
-+++ b/ipaserver/plugins/host.py
-@@ -38,7 +38,7 @@ from .baseldap import (LDAPQuery, LDAPObject, LDAPCreate,
-                                      LDAPAddAttributeViaOption,
-                                      LDAPRemoveAttributeViaOption)
- from .service import (
--    validate_realm, normalize_principal,
-+    validate_realm, validate_auth_indicator, normalize_principal,
-     set_certificate_attrs, ticket_flags_params, update_krbticketflags,
-     set_kerberos_attrs, rename_ipaallowedtoperform_from_ldap,
-     rename_ipaallowedtoperform_to_ldap, revoke_certs)
-@@ -735,6 +735,8 @@ class host_add(LDAPCreate):
-         update_krbticketflags(ldap, entry_attrs, attrs_list, options, False)
-         if 'krbticketflags' in entry_attrs:
-             entry_attrs['objectclass'].append('krbticketpolicyaux')
-+        validate_auth_indicator(entry_attrs)
-+
-         return dn
- 
-     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-@@ -993,6 +995,7 @@ class host_mod(LDAPUpdate):
-             if 'krbprincipalaux' not in (item.lower() for item in
-                                          entry_attrs['objectclass']):
-                 entry_attrs['objectclass'].append('krbprincipalaux')
-+            validate_auth_indicator(entry_attrs)
- 
-         add_sshpubkey_to_attrs_pre(self.context, attrs_list)
- 
-diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
-index 1c9347804..cfbbff3c6 100644
---- a/ipaserver/plugins/service.py
-+++ b/ipaserver/plugins/service.py
-@@ -201,6 +201,28 @@ def validate_realm(ugettext, principal):
-         raise errors.RealmMismatch()
- 
- 
-+def validate_auth_indicator(entry):
-+    new_value = entry.get('krbprincipalauthind', None)
-+    if not new_value:
-+        return
-+    # The following services are considered internal IPA services
-+    # and shouldn't be allowed to have auth indicators.
-+    # https://pagure.io/freeipa/issue/8206
-+    pkey = api.Object['service'].get_primary_key_from_dn(entry.dn)
-+    principal = kerberos.Principal(pkey)
-+    server = api.Command.server_find(principal.hostname)['result']
-+    if server:
-+        prefixes = ("host", "cifs", "ldap", "HTTP")
-+    else:
-+        prefixes = ("cifs",)
-+    if principal.service_name in prefixes:
-+        raise errors.ValidationError(
-+            name='krbprincipalauthind',
-+            error=_('authentication indicators not allowed '
-+                    'in service "%s"' % principal.service_name)
-+        )
-+
-+
- def normalize_principal(value):
-     """
-     Ensure that the name in the principal is lower-case. The realm is
-@@ -652,6 +674,7 @@ class service_add(LDAPCreate):
-                     hostname)
- 
-         self.obj.validate_ipakrbauthzdata(entry_attrs)
-+        validate_auth_indicator(entry_attrs)
- 
-         if not options.get('force', False):
-             # We know the host exists if we've gotten this far but we
-@@ -846,6 +869,7 @@ class service_mod(LDAPUpdate):
-         assert isinstance(dn, DN)
- 
-         self.obj.validate_ipakrbauthzdata(entry_attrs)
-+        validate_auth_indicator(entry_attrs)
- 
-         # verify certificates
-         certs = entry_attrs.get('usercertificate') or []
--- 
-2.31.1
-
-From 28484c3dee225662e41acc691bfe6b1c1cee99c8 Mon Sep 17 00:00:00 2001
-From: Antonio Torres <antorres@redhat.com>
-Date: Mon, 8 Mar 2021 18:20:35 +0100
-Subject: [PATCH] ipatests: ensure auth indicators can't be added to internal
- IPA services
-
-Authentication indicators should not be added to internal IPA services,
-since this can lead to a broken IPA setup. In case a client with
-an auth indicator set in its host principal, promoting it to a replica
-should fail.
-
-Related: https://pagure.io/freeipa/issue/8206
-Signed-off-by: Antonio Torres <antorres@redhat.com>
----
- .../test_replica_promotion.py                 | 38 +++++++++++++++++++
- ipatests/test_xmlrpc/test_host_plugin.py      | 10 +++++
- ipatests/test_xmlrpc/test_service_plugin.py   | 21 ++++++++++
- 3 files changed, 69 insertions(+)
-
-diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
-index 0a137dbdc..b9c56f775 100644
---- a/ipatests/test_integration/test_replica_promotion.py
-+++ b/ipatests/test_integration/test_replica_promotion.py
-@@ -101,6 +101,44 @@ class TestReplicaPromotionLevel1(ReplicaPromotionBase):
-         assert result.returncode == 1
-         assert expected_err in result.stderr_text
- 
-+    @replicas_cleanup
-+    def test_install_with_host_auth_ind_set(self):
-+        """ A client shouldn't be able to be promoted if it has
-+        any auth indicator set in the host principal.
-+        https://pagure.io/freeipa/issue/8206
-+        """
-+
-+        client = self.replicas[0]
-+        # Configure firewall first
-+        Firewall(client).enable_services(["freeipa-ldap",
-+                                          "freeipa-ldaps"])
-+
-+        client.run_command(['ipa-client-install', '-U',
-+                            '--domain', self.master.domain.name,
-+                            '--realm', self.master.domain.realm,
-+                            '-p', 'admin',
-+                            '-w', self.master.config.admin_password,
-+                            '--server', self.master.hostname,
-+                            '--force-join'])
-+
-+        tasks.kinit_admin(client)
-+
-+        client.run_command(['ipa', 'host-mod', '--auth-ind=otp',
-+                            client.hostname])
-+
-+        res = client.run_command(['ipa-replica-install', '-U', '-w',
-+                                  self.master.config.dirman_password],
-+                                 raiseonerr=False)
-+
-+        client.run_command(['ipa', 'host-mod', '--auth-ind=',
-+                            client.hostname])
-+
-+        expected_err = ("Client cannot be promoted to a replica if the host "
-+                        "principal has an authentication indicator set.")
-+        assert res.returncode == 1
-+        assert expected_err in res.stderr_text
-+
-+
-     @replicas_cleanup
-     def test_one_command_installation(self):
-         """
-diff --git a/ipatests/test_xmlrpc/test_host_plugin.py b/ipatests/test_xmlrpc/test_host_plugin.py
-index c66bbc865..9cfde3565 100644
---- a/ipatests/test_xmlrpc/test_host_plugin.py
-+++ b/ipatests/test_xmlrpc/test_host_plugin.py
-@@ -605,6 +605,16 @@ class TestProtectedMaster(XMLRPC_test):
-                 error=u'An IPA master host cannot be deleted or disabled')):
-             command()
- 
-+    def test_try_add_auth_ind_master(self, this_host):
-+        command = this_host.make_update_command({
-+            u'krbprincipalauthind': u'radius'})
-+        with raises_exact(errors.ValidationError(
-+            name='krbprincipalauthind',
-+            error=u'authentication indicators not allowed '
-+                'in service "host"'
-+        )):
-+            command()
-+
- 
- @pytest.mark.tier1
- class TestValidation(XMLRPC_test):
-diff --git a/ipatests/test_xmlrpc/test_service_plugin.py b/ipatests/test_xmlrpc/test_service_plugin.py
-index 4c845938c..ed634a045 100644
---- a/ipatests/test_xmlrpc/test_service_plugin.py
-+++ b/ipatests/test_xmlrpc/test_service_plugin.py
-@@ -25,6 +25,7 @@ from ipalib import api, errors
- from ipatests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_hash
- from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_digits, fuzzy_date, fuzzy_issuer
- from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_hex, XMLRPC_test
-+from ipatests.test_xmlrpc.xmlrpc_test import raises_exact
- from ipatests.test_xmlrpc import objectclasses
- from ipatests.test_xmlrpc.testcert import get_testcert, subject_base
- from ipatests.test_xmlrpc.test_user_plugin import get_user_result, get_group_dn
-@@ -1552,6 +1553,15 @@ def indicators_host(request):
-     return tracker.make_fixture(request)
- 
- 
-+@pytest.fixture(scope='function')
-+def this_host(request):
-+    """Fixture for the current master"""
-+    tracker = HostTracker(name=api.env.host.partition('.')[0],
-+                          fqdn=api.env.host)
-+    tracker.exists = True
-+    return tracker
-+
-+
- @pytest.fixture(scope='function')
- def indicators_service(request):
-     tracker = ServiceTracker(
-@@ -1587,6 +1597,17 @@ class TestAuthenticationIndicators(XMLRPC_test):
-             expected_updates={u'krbprincipalauthind': [u'radius']}
-         )
- 
-+    def test_update_indicator_internal_service(self, this_host):
-+        command = this_host.make_command('service_mod',
-+                                         'ldap/' + this_host.fqdn,
-+                                         **dict(krbprincipalauthind='otp'))
-+        with raises_exact(errors.ValidationError(
-+            name='krbprincipalauthind',
-+            error=u'authentication indicators not allowed '
-+                 'in service "ldap"'
-+        )):
-+            command()
-+
- 
- @pytest.fixture(scope='function')
- def managing_host(request):
--- 
-2.31.1
-
diff --git a/SOURCES/0002-Config-plugin-return-EmptyModlist-when-no-change-is-applied_rhbz#2031825.patch b/SOURCES/0002-Config-plugin-return-EmptyModlist-when-no-change-is-applied_rhbz#2031825.patch
new file mode 100644
index 0000000..f5f3cf3
--- /dev/null
+++ b/SOURCES/0002-Config-plugin-return-EmptyModlist-when-no-change-is-applied_rhbz#2031825.patch
@@ -0,0 +1,75 @@
+From b9c42fed9b6f60801f908c368d0d97a2a69f7bb2 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Wed, 15 Dec 2021 10:47:02 +0100
+Subject: [PATCH] Config plugin: return EmptyModlist when no change is applied
+
+When ipa config-mod is called with the option --enable-sid,
+the code needs to trap EmptyModlist exception (it is expected
+that no LDAP attribute is modified by this operation).
+The code had a flaw and was checking:
+    'enable_sid' in options
+instead of
+    options['enable_sid']
+
+"'enable_sid' in options" always returns true as this option
+is a Flag with a default value, hence always present even if
+not specified on the command line.
+
+Fixes: https://pagure.io/freeipa/issue/9063
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ ipaserver/plugins/config.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
+index eae401fc3..24446beb0 100644
+--- a/ipaserver/plugins/config.py
++++ b/ipaserver/plugins/config.py
+@@ -707,7 +707,7 @@ class config_mod(LDAPUpdate):
+         if (isinstance(exc, errors.EmptyModlist) and
+                 call_func.__name__ == 'update_entry' and
+                 ('ca_renewal_master_server' in options or
+-                 'enable_sid' in options)):
++                 options['enable_sid'])):
+             return
+ 
+         super(config_mod, self).exc_callback(
+-- 
+2.34.1
+
+From cd735099e86304294217147ed578ac902fcf3dd3 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Wed, 15 Dec 2021 10:51:05 +0100
+Subject: [PATCH] config plugin: add a test ensuring EmptyModlist is returned
+
+Add a test to test_config_plugin, that calls ipa config-mod
+with the same value as already present in LDAP.
+The call must return EmptyModlist.
+
+Related: https://pagure.io/freeipa/issue/9063
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ ipatests/test_xmlrpc/test_config_plugin.py | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/ipatests/test_xmlrpc/test_config_plugin.py b/ipatests/test_xmlrpc/test_config_plugin.py
+index e981bb4a0..a8ec9f0e5 100644
+--- a/ipatests/test_xmlrpc/test_config_plugin.py
++++ b/ipatests/test_xmlrpc/test_config_plugin.py
+@@ -312,4 +312,13 @@ class test_config(Declarative):
+                 'value': None,
+             },
+         ),
++        dict(
++            desc='Set the value to the already set value, no modifications',
++            command=(
++                'config_mod', [], {
++                    'ipasearchrecordslimit': u'100',
++                },
++            ),
++            expected=errors.EmptyModlist(),
++        ),
+     ]
+-- 
+2.34.1
+
diff --git a/SOURCES/0003-Custodia-use-a-stronger-encryption-algo-when-exporting-keys_rhbz#2032806.patch b/SOURCES/0003-Custodia-use-a-stronger-encryption-algo-when-exporting-keys_rhbz#2032806.patch
new file mode 100644
index 0000000..f6cf756
--- /dev/null
+++ b/SOURCES/0003-Custodia-use-a-stronger-encryption-algo-when-exporting-keys_rhbz#2032806.patch
@@ -0,0 +1,47 @@
+From 653a7fe02880c168755984133ee143567cc7bb4e Mon Sep 17 00:00:00 2001
+From: Francisco Trivino <ftrivino@redhat.com>
+Date: Wed, 26 Jan 2022 15:43:39 +0100
+Subject: [PATCH] Custodia: use a stronger encryption algo when exporting keys
+
+The Custodia key export handler is using the default's OpenSSL encryption
+scheme for PKCS#12.
+
+This represents an issue when performing a migration from CentOS Stream 8 (C8S)
+to CentOS Steam 9 (C9S) where the Custodia client running in the new C9S
+replica talks to the Custodia server on C8S source server. The later creates an
+encrypted PKCS#12 file that contains the cert and the key using the OpenSSL's
+default encryption scheme, which is no longer supported on C9S.
+
+This commit enforces a stronger encryption algorigthm by adding following
+arguments to the Custodia server handler:
+
+-keypbe AES-256-CBC -certpbe AES-256-CBC -macalg sha384
+
+The new arguments enforce stronger PBEv2 instead of the insecure PBEv1.
+
+Fixes: https://pagure.io/freeipa/issue/9101
+
+Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+---
+ ipaserver/secrets/handlers/pemfile.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/ipaserver/secrets/handlers/pemfile.py b/ipaserver/secrets/handlers/pemfile.py
+index 4e8eff0e3..ad36bd020 100644
+--- a/ipaserver/secrets/handlers/pemfile.py
++++ b/ipaserver/secrets/handlers/pemfile.py
+@@ -31,6 +31,9 @@ def export_key(args, tmpdir):
+         '-out', pk12file,
+         '-inkey', args.keyfile,
+         '-password', 'file:{pk12pwfile}'.format(pk12pwfile=pk12pwfile),
++        '-keypbe', 'AES-256-CBC',
++        '-certpbe', 'AES-256-CBC',
++        '-macalg', 'sha384',
+     ])
+ 
+     with open(pk12file, 'rb') as f:
+-- 
+2.34.1
+
diff --git a/SOURCES/0003-stageuser-add-ipauserauthtypeclass-when-required_rhbz#1979605.patch b/SOURCES/0003-stageuser-add-ipauserauthtypeclass-when-required_rhbz#1979605.patch
deleted file mode 100644
index 7934afd..0000000
--- a/SOURCES/0003-stageuser-add-ipauserauthtypeclass-when-required_rhbz#1979605.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From 06468b2f604c56b02231904072cb57412966a701 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Mon, 5 Jul 2021 09:51:41 +0200
-Subject: [PATCH] stageuser: add ipauserauthtypeclass when required
-
-The command
-ipa stageuser-add --user-auth-type=xxx
-is currently failing because the objectclass ipauserauthtypeclass
-is missing from the created entry.
-
-There is code adding the missing objectclass in the
-pre_common_callback method of user_add, and this code should
-be common to user_add and stageuser_add. In order to avoid code
-duplication, it makes more sense to move the existing code to
-pre_common_callback of baseuser_add, that is called by both
-classes.
-
-Fixes: https://pagure.io/freeipa/issue/8909
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipaserver/plugins/baseuser.py | 3 +++
- ipaserver/plugins/user.py     | 4 ----
- 2 files changed, 3 insertions(+), 4 deletions(-)
-
-diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
-index ae16a978a..6035228f1 100644
---- a/ipaserver/plugins/baseuser.py
-+++ b/ipaserver/plugins/baseuser.py
-@@ -539,6 +539,9 @@ class baseuser_add(LDAPCreate):
-         if entry_attrs.get('ipatokenradiususername', None):
-             add_missing_object_class(ldap, u'ipatokenradiusproxyuser', dn,
-                                      entry_attrs, update=False)
-+        if entry_attrs.get('ipauserauthtype', None):
-+            add_missing_object_class(ldap, u'ipauserauthtypeclass', dn,
-+                                     entry_attrs, update=False)
- 
-     def post_common_callback(self, ldap, dn, entry_attrs, *keys, **options):
-         assert isinstance(dn, DN)
-diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
-index 6f7facb53..e4ee572b2 100644
---- a/ipaserver/plugins/user.py
-+++ b/ipaserver/plugins/user.py
-@@ -617,10 +617,6 @@ class user_add(baseuser_add):
-            'ipauser' not in entry_attrs['objectclass']:
-             entry_attrs['objectclass'].append('ipauser')
- 
--        if 'ipauserauthtype' in entry_attrs and \
--           'ipauserauthtypeclass' not in entry_attrs['objectclass']:
--            entry_attrs['objectclass'].append('ipauserauthtypeclass')
--
-         rcl = entry_attrs.get('ipatokenradiusconfiglink', None)
-         if rcl:
-             if 'ipatokenradiusproxyuser' not in entry_attrs['objectclass']:
--- 
-2.31.1
-
-From 4a5a0fe7d25209a41a2eadd159f7f4c771e5d7fc Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Mon, 5 Jul 2021 10:22:31 +0200
-Subject: [PATCH] XMLRPC test: add a test for stageuser-add --user-auth-type
-
-Related: https://pagure.io/freeipa/issue/8909
-Reviewed-By: Rob Crittenden <rcritten@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
----
- ipatests/test_xmlrpc/test_stageuser_plugin.py | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/ipatests/test_xmlrpc/test_stageuser_plugin.py b/ipatests/test_xmlrpc/test_stageuser_plugin.py
-index 5586fc607..bc606b093 100644
---- a/ipatests/test_xmlrpc/test_stageuser_plugin.py
-+++ b/ipatests/test_xmlrpc/test_stageuser_plugin.py
-@@ -343,6 +343,12 @@ class TestStagedUser(XMLRPC_test):
-         result = command()
-         assert result['count'] == 1
- 
-+    def test_create_withuserauthtype(self, stageduser):
-+        stageduser.ensure_missing()
-+        command = stageduser.make_create_command(
-+            options={u'ipauserauthtype': u'password'})
-+        command()
-+
- 
- @pytest.mark.tier1
- class TestCreateInvalidAttributes(XMLRPC_test):
--- 
-2.31.1
-
diff --git a/SOURCES/0004-ipa-kdb-do-not-remove-keys-for-hardened-auth-enabled-users_rhbz#2033342.patch b/SOURCES/0004-ipa-kdb-do-not-remove-keys-for-hardened-auth-enabled-users_rhbz#2033342.patch
new file mode 100644
index 0000000..1e342e5
--- /dev/null
+++ b/SOURCES/0004-ipa-kdb-do-not-remove-keys-for-hardened-auth-enabled-users_rhbz#2033342.patch
@@ -0,0 +1,122 @@
+From 6d70421f57d0eca066a922e09416ef7195ee96d4 Mon Sep 17 00:00:00 2001
+From: Julien Rische <jrische@redhat.com>
+Date: Tue, 1 Feb 2022 16:43:09 +0100
+Subject: [PATCH] ipa-kdb: do not remove keys for hardened auth-enabled users
+
+Since 5d51ae5, principal keys were dropped in case user auth indicator
+was not including password. Thereafter, the key removal behavior was
+removed by 15ff9c8 in the context of the kdcpolicy plugin introduction.
+Support for hardened pre-auth methods (FAST and SPAKE) was added in
+d057040, and the removal of principal keys was restored afterwards by
+f0d12b7, but not taking the new hardened auth indicator into account.
+
+Fixes: https://pagure.io/freeipa/issue/9065
+Related to: https://pagure.io/freeipa/issue/8001
+
+Signed-off-by: Julien Rische <jrische@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ daemons/ipa-kdb/ipa_kdb_principals.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
+index 15f3df4fe..0d0d3748c 100644
+--- a/daemons/ipa-kdb/ipa_kdb_principals.c
++++ b/daemons/ipa-kdb/ipa_kdb_principals.c
+@@ -788,17 +788,18 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
+                                       &res_key_data, &result, &mkvno);
+     switch (ret) {
+     case 0:
+-        /* Only set a principal's key if password auth can be used. Otherwise
+-         * the KDC would add pre-authentication methods to the NEEDED_PREAUTH
+-         * reply for AS-REQs which indicate the password authentication is
+-         * available. This might confuse applications like e.g. SSSD which try
+-         * to determine suitable authentication methods and corresponding
+-         * prompts with the help of MIT Kerberos' responder interface which
+-         * acts on the returned pre-authentication methods. A typical example
+-         * is enforced OTP authentication where of course keys are available
+-         * for the first factor but password authentication should not be
+-         * advertised by the KDC. */
+-        if (!(ua & IPADB_USER_AUTH_PASSWORD) && (ua != IPADB_USER_AUTH_NONE)) {
++        /* Only set a principal's key if password or hardened auth can be used.
++         * Otherwise the KDC would add pre-authentication methods to the
++         * NEEDED_PREAUTH reply for AS-REQs which indicate the password
++         * authentication is available. This might confuse applications like
++         * e.g. SSSD which try to determine suitable authentication methods and
++         * corresponding prompts with the help of MIT Kerberos' responder
++         * interface which acts on the returned pre-authentication methods. A
++         * typical example is enforced OTP authentication where of course keys
++         * are available for the first factor but password authentication
++         * should not be advertised by the KDC. */
++        if (!(ua & (IPADB_USER_AUTH_PASSWORD | IPADB_USER_AUTH_HARDENED)) &&
++            (ua != IPADB_USER_AUTH_NONE)) {
+             /* This is the same behavior as ENOENT below. */
+             ipa_krb5_free_key_data(res_key_data, result);
+             break;
+-- 
+2.34.1
+
+From 294ae35a61e6ca8816b261c57508e4be21221864 Mon Sep 17 00:00:00 2001
+From: Julien Rische <jrische@redhat.com>
+Date: Tue, 1 Feb 2022 19:38:29 +0100
+Subject: [PATCH] ipatests: add case for hardened-only ticket policy
+
+Signed-off-by: Julien Rische <jrische@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ ipatests/test_integration/test_krbtpolicy.py | 30 ++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+diff --git a/ipatests/test_integration/test_krbtpolicy.py b/ipatests/test_integration/test_krbtpolicy.py
+index 63e75ae67..9489fbc97 100644
+--- a/ipatests/test_integration/test_krbtpolicy.py
++++ b/ipatests/test_integration/test_krbtpolicy.py
+@@ -103,8 +103,8 @@ class TestPWPolicy(IntegrationTest):
+         result = master.run_command('klist | grep krbtgt')
+         assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
+ 
+-    def test_krbtpolicy_hardended(self):
+-        """Test a hardened kerberos ticket policy with 10 min tickets"""
++    def test_krbtpolicy_password_and_hardended(self):
++        """Test a pwd and hardened kerberos ticket policy with 10min tickets"""
+         master = self.master
+         master.run_command(['ipa', 'user-mod', USER1,
+                             '--user-auth-type', 'password',
+@@ -131,6 +131,32 @@ class TestPWPolicy(IntegrationTest):
+         result = master.run_command('klist | grep krbtgt')
+         assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
+ 
++    def test_krbtpolicy_hardended(self):
++        """Test a hardened kerberos ticket policy with 30min tickets"""
++        master = self.master
++        master.run_command(['ipa', 'user-mod', USER1,
++                            '--user-auth-type', 'hardened'])
++        master.run_command(['ipa', 'config-mod',
++                            '--user-auth-type', 'hardened'])
++        master.run_command(['ipa', 'krbtpolicy-mod', USER1,
++                            '--hardened-maxlife', '1800'])
++
++        tasks.kdestroy_all(master)
++
++        master.run_command(['kinit', USER1],
++                           stdin_text=PASSWORD + '\n')
++        result = master.run_command('klist | grep krbtgt')
++        assert maxlife_within_policy(result.stdout_text, 1800,
++                                     slush=1800) is True
++
++        tasks.kdestroy_all(master)
++
++        # Verify that the short policy only applies to USER1
++        master.run_command(['kinit', USER2],
++                           stdin_text=PASSWORD + '\n')
++        result = master.run_command('klist | grep krbtgt')
++        assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
++
+     def test_krbtpolicy_password(self):
+         """Test the kerberos ticket policy which issues 20 min tickets"""
+         master = self.master
+-- 
+2.34.1
+
diff --git a/SOURCES/0004-man-page-update-ipa-server-upgrade.1_rhbz#1973273.patch b/SOURCES/0004-man-page-update-ipa-server-upgrade.1_rhbz#1973273.patch
deleted file mode 100644
index 83182ce..0000000
--- a/SOURCES/0004-man-page-update-ipa-server-upgrade.1_rhbz#1973273.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 195035cef51a132b2b80df57ed50f2fe620244e6 Mon Sep 17 00:00:00 2001
-From: Florence Blanc-Renaud <flo@redhat.com>
-Date: Wed, 7 Jul 2021 14:11:40 +0200
-Subject: [PATCH] man page: update ipa-server-upgrade.1
-
-The man page needs to clarify in which case the command needs
-to be run.
-
-Fixes: https://pagure.io/freeipa/issue/8913
-Reviewed-By: Francois Cami <fcami@redhat.com>
----
- install/tools/man/ipa-server-upgrade.1 | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/install/tools/man/ipa-server-upgrade.1 b/install/tools/man/ipa-server-upgrade.1
-index 3db19b0f1..f01e21c6b 100644
---- a/install/tools/man/ipa-server-upgrade.1
-+++ b/install/tools/man/ipa-server-upgrade.1
-@@ -8,7 +8,12 @@ ipa\-server\-upgrade \- upgrade IPA server
- .SH "SYNOPSIS"
- ipa\-server\-upgrade [options]
- .SH "DESCRIPTION"
--ipa\-server\-upgrade is used to upgrade IPA server when the IPA packages are being updated. It is not intended to be executed by end\-users.
-+ipa\-server\-upgrade is executed automatically to upgrade IPA server when
-+the IPA packages are being updated. It is not intended to be executed by
-+end\-users, unless the automatic execution reports an error. In this case,
-+the administrator needs to identify and fix the issue that is causing the
-+upgrade failure (with the help of /var/log/ipaupgrade.log)
-+and manually re\-run ipa\-server\-upgrade.
- 
- ipa\-server\-upgrade will:
- 
--- 
-2.31.1
-
diff --git a/SOURCES/0005-Fall-back-to-krbprincipalname-when-validating-host-a_rhbz#1979625.patch b/SOURCES/0005-Fall-back-to-krbprincipalname-when-validating-host-a_rhbz#1979625.patch
deleted file mode 100644
index 069d106..0000000
--- a/SOURCES/0005-Fall-back-to-krbprincipalname-when-validating-host-a_rhbz#1979625.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 8ad535b618d60fa016061212ff85d0ad28ccae59 Mon Sep 17 00:00:00 2001
-From: Rob Crittenden <rcritten@redhat.com>
-Date: Mon, 12 Jul 2021 11:02:10 -0400
-Subject: [PATCH] Fall back to krbprincipalname when validating host auth
- indicators
-
-When adding a new host the principal cannot be determined because it
-relies on either:
-
-a) an entry to already exist
-b) krbprincipalname be a component of the dn
-
-As a result the full dn is being passed into ipapython.Kerberos
-which can't parse it.
-
-Look into the entry in validate_validate_auth_indicator() for
-krbprincipalname in this case.
-
-https://pagure.io/freeipa/issue/8206
-
-Signed-off-by: Rob Crittenden <rcritten@redhat.com>
-Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
----
- ipaserver/plugins/service.py             |  5 +++++
- ipatests/test_xmlrpc/test_host_plugin.py | 11 +++++++++++
- 2 files changed, 16 insertions(+)
-
-diff --git a/ipaserver/plugins/service.py b/ipaserver/plugins/service.py
-index cfbbff3c6..498f5e444 100644
---- a/ipaserver/plugins/service.py
-+++ b/ipaserver/plugins/service.py
-@@ -209,6 +209,11 @@ def validate_auth_indicator(entry):
-     # and shouldn't be allowed to have auth indicators.
-     # https://pagure.io/freeipa/issue/8206
-     pkey = api.Object['service'].get_primary_key_from_dn(entry.dn)
-+    if pkey == str(entry.dn):
-+        # krbcanonicalname may not be set yet if this is a host entry,
-+        # try krbprincipalname
-+        if 'krbprincipalname' in entry:
-+            pkey = entry['krbprincipalname']
-     principal = kerberos.Principal(pkey)
-     server = api.Command.server_find(principal.hostname)['result']
-     if server:
-diff --git a/ipatests/test_xmlrpc/test_host_plugin.py b/ipatests/test_xmlrpc/test_host_plugin.py
-index 9cfde3565..ff50e796c 100644
---- a/ipatests/test_xmlrpc/test_host_plugin.py
-+++ b/ipatests/test_xmlrpc/test_host_plugin.py
-@@ -615,6 +615,17 @@ class TestProtectedMaster(XMLRPC_test):
-         )):
-             command()
- 
-+    def test_add_non_master_with_auth_ind(self, host5):
-+        host5.ensure_missing()
-+        command = host5.make_command(
-+            'host_add', host5.fqdn, krbprincipalauthind=['radius'],
-+            force=True
-+        )
-+        result = command()
-+        # The fact that the command succeeds exercises the change but
-+        # let's check the indicator as well.
-+        assert result['result']['krbprincipalauthind'] == ('radius',)
-+
- 
- @pytest.mark.tier1
- class TestValidation(XMLRPC_test):
--- 
-2.31.1
-
diff --git a/SOURCES/0005-ipa-pki-proxy.conf-provide-access-to-kra-admin-kra-getStatus_rhbz#2049167.patch b/SOURCES/0005-ipa-pki-proxy.conf-provide-access-to-kra-admin-kra-getStatus_rhbz#2049167.patch
new file mode 100644
index 0000000..3ac05fa
--- /dev/null
+++ b/SOURCES/0005-ipa-pki-proxy.conf-provide-access-to-kra-admin-kra-getStatus_rhbz#2049167.patch
@@ -0,0 +1,44 @@
+From 9bae5492270d8b695999cd82831cbee62b04626b Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Fri, 28 Jan 2022 16:58:42 +0100
+Subject: [PATCH] ipa-pki-proxy.conf: provide access to
+ /kra/admin/kra/getStatus
+
+The access to /kra/admin/kra/getStatus will be needed
+in order to fix pki-healthcheck.
+Note that this commit is a pre-requisite for the fix
+to be done on PKI side. No test added since the full
+integration test already exists in test_replica_promotion.py,
+in TestHiddenReplicaPromotion::test_ipahealthcheck_hidden_replica
+
+Fixes: https://pagure.io/freeipa/issue/9099
+Related: https://pagure.io/freeipa/issue/8582
+
+Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ install/share/ipa-pki-proxy.conf.template | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/install/share/ipa-pki-proxy.conf.template b/install/share/ipa-pki-proxy.conf.template
+index 96708482c..7a46f20b9 100644
+--- a/install/share/ipa-pki-proxy.conf.template
++++ b/install/share/ipa-pki-proxy.conf.template
+@@ -1,4 +1,4 @@
+-# VERSION 16 - DO NOT REMOVE THIS LINE
++# VERSION 17 - DO NOT REMOVE THIS LINE
+ 
+ ProxyRequests Off
+ 
+@@ -11,7 +11,7 @@ ProxyRequests Off
+ </LocationMatch>
+ 
+ # matches for admin port and installer
+-<LocationMatch "^/ca/admin/ca/getCertChain|^/ca/admin/ca/getConfigEntries|^/ca/admin/ca/getCookie|^/ca/admin/ca/getStatus|^/ca/admin/ca/securityDomainLogin|^/ca/admin/ca/getDomainXML|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/tokenAuthenticate|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/updateDomainXML|^/ca/admin/ca/updateConnector|^/ca/admin/ca/getSubsystemCert|^/kra/admin/kra/updateNumberRange|^/kra/admin/kra/getConfigEntries">
++<LocationMatch "^/ca/admin/ca/getCertChain|^/ca/admin/ca/getConfigEntries|^/ca/admin/ca/getCookie|^/ca/admin/ca/getStatus|^/ca/admin/ca/securityDomainLogin|^/ca/admin/ca/getDomainXML|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/tokenAuthenticate|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/updateDomainXML|^/ca/admin/ca/updateConnector|^/ca/admin/ca/getSubsystemCert|^/kra/admin/kra/updateNumberRange|^/kra/admin/kra/getConfigEntries|^/kra/admin/kra/getStatus">
+     SSLOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
+     SSLVerifyClient none
+     ProxyPassMatch ajp://localhost:$DOGTAG_PORT $DOGTAG_AJP_SECRET
+-- 
+2.34.1
+
diff --git a/SOURCES/0006-Backport-latest-test-fxes-in-python3-ipatests_rhbz#2048509.patch b/SOURCES/0006-Backport-latest-test-fxes-in-python3-ipatests_rhbz#2048509.patch
new file mode 100644
index 0000000..14d1f0c
--- /dev/null
+++ b/SOURCES/0006-Backport-latest-test-fxes-in-python3-ipatests_rhbz#2048509.patch
@@ -0,0 +1,755 @@
+From 0edf915efbb39fac45c784171dd715ec6b28861a Mon Sep 17 00:00:00 2001
+From: Sumedh Sidhaye <ssidhaye@redhat.com>
+Date: Fri, 14 Jan 2022 19:55:13 +0530
+Subject: [PATCH] Added test automation for SHA384withRSA CSR support
+
+Scenario 1:
+Setup master with --ca-signing-algorithm=SHA384withRSA
+Run certutil and check Signing Algorithm
+
+Scenario 2:
+Setup a master
+Stop services
+Modify default.params.signingAlg in CS.cfg
+Restart services
+Resubmit cert (Resubmitted cert should have new Algorithm)
+
+Pagure Link: https://pagure.io/freeipa/issue/8906
+
+Signed-off-by: Sumedh Sidhaye <ssidhaye@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+Reviewed-By: Antonio Torres <antorres@redhat.com>
+---
+ .../test_integration/test_installation.py     | 63 +++++++++++++++++++
+ 1 file changed, 63 insertions(+)
+
+diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
+index 0947241ae..f2d372c0c 100644
+--- a/ipatests/test_integration/test_installation.py
++++ b/ipatests/test_integration/test_installation.py
+@@ -34,6 +34,7 @@ from ipatests.pytest_ipa.integration import tasks
+ from ipatests.pytest_ipa.integration.env_config import get_global_config
+ from ipatests.test_integration.base import IntegrationTest
+ from ipatests.test_integration.test_caless import CALessBase, ipa_certs_cleanup
++from ipatests.test_integration.test_cert import get_certmonger_fs_id
+ from ipaplatform import services
+ 
+ 
+@@ -1916,3 +1917,65 @@ class TestInstallWithoutNamed(IntegrationTest):
+         tasks.install_replica(
+             self.master, self.replicas[0], setup_ca=False, setup_dns=False
+         )
++
++
++class TestInstallwithSHA384withRSA(IntegrationTest):
++    num_replicas = 0
++
++    def test_install_master_withalgo_sha384withrsa(self, server_cleanup):
++        tasks.install_master(
++            self.master,
++            extra_args=['--ca-signing-algorithm=SHA384withRSA'],
++        )
++
++        # check Signing Algorithm post installation
++        dashed_domain = self.master.domain.realm.replace(".", '-')
++        cmd_args = ['certutil', '-L', '-d',
++                    '/etc/dirsrv/slapd-{}/'.format(dashed_domain),
++                    '-n', 'Server-Cert']
++        result = self.master.run_command(cmd_args)
++        assert 'SHA-384 With RSA Encryption' in result.stdout_text
++
++    def test_install_master_modify_existing(self, server_cleanup):
++        """
++        Setup a master
++        Stop services
++        Modify default.params.signingAlg in CS.cfg
++        Restart services
++        Resubmit cert (Resubmitted cert should have new Algorithm)
++        """
++        tasks.install_master(self.master)
++        self.master.run_command(['ipactl', 'stop'])
++        cs_cfg_content = self.master.get_file_contents(paths.CA_CS_CFG_PATH,
++                                                       encoding='utf-8')
++        new_lines = []
++        replace_str = "ca.signing.defaultSigningAlgorithm=SHA384withRSA"
++        ocsp_rep_str = "ca.ocsp_signing.defaultSigningAlgorithm=SHA384withRSA"
++        for line in cs_cfg_content.split('\n'):
++            if line.startswith('ca.signing.defaultSigningAlgorithm'):
++                new_lines.append(replace_str)
++            elif line.startswith('ca.ocsp_signing.defaultSigningAlgorithm'):
++                new_lines.append(ocsp_rep_str)
++            else:
++                new_lines.append(line)
++        self.master.put_file_contents(paths.CA_CS_CFG_PATH,
++                                      '\n'.join(new_lines))
++        self.master.run_command(['ipactl', 'start'])
++
++        cmd = ['getcert', 'list', '-f', paths.RA_AGENT_PEM]
++        result = self.master.run_command(cmd)
++        request_id = get_certmonger_fs_id(result.stdout_text)
++
++        # resubmit RA Agent cert
++        cmd = ['getcert', 'resubmit', '-f', paths.RA_AGENT_PEM]
++        self.master.run_command(cmd)
++
++        tasks.wait_for_certmonger_status(self.master,
++                                         ('CA_WORKING', 'MONITORING'),
++                                         request_id)
++
++        cmd_args = ['openssl', 'x509', '-in',
++                    paths.RA_AGENT_PEM, '-noout', '-text']
++        result = self.master.run_command(cmd_args)
++        assert_str = 'Signature Algorithm: sha384WithRSAEncryption'
++        assert assert_str in result.stdout_text
+-- 
+2.34.1
+
+From 8b22ee018c3bb7f58a1b6694a7fd611688f8e74f Mon Sep 17 00:00:00 2001
+From: Sumedh Sidhaye <ssidhaye@redhat.com>
+Date: Thu, 25 Nov 2021 17:48:20 +0530
+Subject: [PATCH] Extend test to see if replica is not shown when running
+ `ipa-replica-manage list -v <FQDN>`
+
+Related: https://pagure.io/freeipa/issue/8605
+
+Signed-off-by: Sumedh Sidhaye <ssidhaye@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+---
+ ipatests/test_integration/test_simple_replication.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ipatests/test_integration/test_simple_replication.py b/ipatests/test_integration/test_simple_replication.py
+index 8de385144..17092a499 100644
+--- a/ipatests/test_integration/test_simple_replication.py
++++ b/ipatests/test_integration/test_simple_replication.py
+@@ -111,5 +111,6 @@ class TestSimpleReplication(IntegrationTest):
+         # has to be run with --force, there is no --unattended
+         self.master.run_command(['ipa-replica-manage', 'del',
+                                  self.replicas[0].hostname, '--force'])
+-        result = self.master.run_command(['ipa-replica-manage', 'list'])
++        result = self.master.run_command(
++            ['ipa-replica-manage', 'list', '-v', self.master.hostname])
+         assert self.replicas[0].hostname not in result.stdout_text
+-- 
+2.34.1
+
+From ba7ec71ba96280da3841ebe47df2a6dc1cd6341e Mon Sep 17 00:00:00 2001
+From: Mohammad Rizwan <myusuf@redhat.com>
+Date: Fri, 26 Nov 2021 12:11:21 +0530
+Subject: [PATCH] ipatests: Fix test_ipa_cert_fix.py::TestCertFixReplica
+ teardown
+
+Fixture `expire_certs` moves date back after renewing the certs.
+This is causing the ipa-replica to fail. This fix first uninstalls
+the server then moves back the date.
+
+Fixes: https://pagure.io/freeipa/issue/9052
+
+Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+---
+ ipatests/test_integration/test_ipa_cert_fix.py | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py
+index 39904d5de..5b56054b4 100644
+--- a/ipatests/test_integration/test_ipa_cert_fix.py
++++ b/ipatests/test_integration/test_ipa_cert_fix.py
+@@ -389,6 +389,12 @@ class TestCertFixReplica(IntegrationTest):
+             setup_dns=False, extra_args=['--no-ntp']
+         )
+ 
++    @classmethod
++    def uninstall(cls, mh):
++        # Uninstall method is empty as the uninstallation is done in
++        # the fixture
++        pass
++
+     @pytest.fixture
+     def expire_certs(self):
+         # move system date to expire certs
+@@ -398,7 +404,8 @@ class TestCertFixReplica(IntegrationTest):
+         yield
+ 
+         # move date back on replica and master
+-        for host in self.master, self.replicas[0]:
++        for host in self.replicas[0], self.master:
++            tasks.uninstall_master(host)
+             tasks.move_date(host, 'start', '-3years-1days')
+ 
+     def test_renew_expired_cert_replica(self, expire_certs):
+-- 
+2.34.1
+
+From 465f1669a6c5abc72da1ecaf9aefa8488f80806c Mon Sep 17 00:00:00 2001
+From: Anuja More <amore@redhat.com>
+Date: Mon, 13 Dec 2021 17:37:05 +0530
+Subject: [PATCH] ipatests: Test default value of nsslapd-sizelimit.
+
+related : https://pagure.io/freeipa/issue/8962
+
+Signed-off-by: Anuja More <amore@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+---
+ ipatests/test_integration/test_installation.py | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
+index 95cfaad54..0947241ae 100644
+--- a/ipatests/test_integration/test_installation.py
++++ b/ipatests/test_integration/test_installation.py
+@@ -1067,6 +1067,19 @@ class TestInstallMaster(IntegrationTest):
+         )
+         assert "nsslapd-db-locks" not in result.stdout_text
+ 
++    def test_nsslapd_sizelimit(self):
++        """ Test for default value of nsslapd-sizelimit.
++
++        Related : https://pagure.io/freeipa/issue/8962
++        """
++        result = tasks.ldapsearch_dm(
++            self.master,
++            "cn=config",
++            ["nsslapd-sizelimit"],
++            scope="base"
++        )
++        assert "nsslapd-sizelimit: 100000" in result.stdout_text
++
+     def test_admin_root_alias_CVE_2020_10747(self):
+         # Test for CVE-2020-10747 fix
+         # https://bugzilla.redhat.com/show_bug.cgi?id=1810160
+-- 
+2.34.1
+
+From cbd9ac6ab07dfb60f67da762fdd70856ad35c230 Mon Sep 17 00:00:00 2001
+From: Mohammad Rizwan <myusuf@redhat.com>
+Date: Thu, 25 Nov 2021 13:10:05 +0530
+Subject: [PATCH] ipatests: Test empty cert request doesn't force certmonger to
+ segfault
+
+When empty cert request is submitted to certmonger, it goes to
+segfault. This fix test that if something like this happens,
+certmonger should gracefuly handle it
+
+and some PEP8 fixes
+
+related: https://pagure.io/certmonger/issue/191
+
+Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
+---
+ ipatests/test_integration/test_cert.py | 79 +++++++++++++++++++++++++-
+ 1 file changed, 78 insertions(+), 1 deletion(-)
+
+diff --git a/ipatests/test_integration/test_cert.py b/ipatests/test_integration/test_cert.py
+index 5ffb8c608..0518d7954 100644
+--- a/ipatests/test_integration/test_cert.py
++++ b/ipatests/test_integration/test_cert.py
+@@ -14,6 +14,7 @@ import random
+ import re
+ import string
+ import time
++import textwrap
+ 
+ from ipaplatform.paths import paths
+ from ipapython.dn import DN
+@@ -193,7 +194,7 @@ class TestInstallMasterClient(IntegrationTest):
+         tasks.kinit_admin(self.master)
+         tasks.user_add(self.master, user)
+ 
+-        for id in (0,1):
++        for id in (0, 1):
+             csr_file = f'{id}.csr'
+             key_file = f'{id}.key'
+             cert_file = f'{id}.crt'
+@@ -584,3 +585,79 @@ class TestCAShowErrorHandling(IntegrationTest):
+         error_msg = 'ipa: ERROR: The certificate for ' \
+                     '{} is not available on this server.'.format(lwca)
+         assert error_msg in result.stderr_text
++
++    def test_certmonger_empty_cert_not_segfault(self):
++        """Test empty cert request doesn't force certmonger to segfault
++
++        Test scenario:
++        create a cert request file in /var/lib/certmonger/requests which is
++        missing most of the required information, and ask request a new
++        certificate to certmonger. The wrong request file should not make
++        certmonger crash.
++
++        related: https://pagure.io/certmonger/issue/191
++        """
++        empty_cert_req_content = textwrap.dedent("""
++        id=dogtag-ipa-renew-agent
++        key_type=UNSPECIFIED
++        key_gen_type=UNSPECIFIED
++        key_size=0
++        key_gen_size=0
++        key_next_type=UNSPECIFIED
++        key_next_gen_type=UNSPECIFIED
++        key_next_size=0
++        key_next_gen_size=0
++        key_preserve=0
++        key_storage_type=NONE
++        key_perms=0
++        key_requested_count=0
++        key_issued_count=0
++        cert_storage_type=FILE
++        cert_perms=0
++        cert_is_ca=0
++        cert_ca_path_length=0
++        cert_no_ocsp_check=0
++        last_need_notify_check=19700101000000
++        last_need_enroll_check=19700101000000
++        template_is_ca=0
++        template_ca_path_length=-1
++        template_no_ocsp_check=0
++        state=NEED_KEY_PAIR
++        autorenew=0
++        monitor=0
++        submitted=19700101000000
++        """)
++        # stop certmonger service
++        self.master.run_command(['systemctl', 'stop', 'certmonger'])
++
++        # place an empty cert request file to certmonger request dir
++        self.master.put_file_contents(
++            os.path.join(paths.CERTMONGER_REQUESTS_DIR, '20211125062617'),
++            empty_cert_req_content
++        )
++
++        # start certmonger, it should not fail
++        self.master.run_command(['systemctl', 'start', 'certmonger'])
++
++        # request a new cert, should succeed and certmonger doesn't goes
++        # to segfault
++        result = self.master.run_command([
++            "ipa-getcert", "request",
++            "-f", os.path.join(paths.OPENSSL_CERTS_DIR, "test.pem"),
++            "-k", os.path.join(paths.OPENSSL_PRIVATE_DIR, "test.key"),
++        ])
++        request_id = re.findall(r'\d+', result.stdout_text)
++
++        # check if certificate is in MONITORING state
++        status = tasks.wait_for_request(self.master, request_id[0], 50)
++        assert status == "MONITORING"
++
++        self.master.run_command(
++            ['ipa-getcert', 'stop-tracking', '-i', request_id[0]]
++        )
++        self.master.run_command([
++            'rm', '-rf',
++            os.path.join(paths.CERTMONGER_REQUESTS_DIR, '20211125062617'),
++            os.path.join(paths.OPENSSL_CERTS_DIR, 'test.pem'),
++            os.path.join(paths.OPENSSL_PRIVATE_DIR, 'test.key')
++        ])
+-- 
+2.34.1
+
+From edbd8f692a28fc999b92e9032614d366511db323 Mon Sep 17 00:00:00 2001
+From: Anuja More <amore@redhat.com>
+Date: Mon, 6 Dec 2021 20:50:01 +0530
+Subject: [PATCH] ipatests: webui: Tests for subordinate ids.
+
+Added web-ui tests to verify where operations
+using subordinate ids are working as expected.
+
+Related : https://pagure.io/freeipa/issue/8361
+
+Signed-off-by: Anuja More <amore@redhat.com>
+Reviewed-By: Michal Polovka <mpolovka@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+---
+ ipatests/test_webui/test_subid.py | 141 ++++++++++++++++++++++++++++++
+ ipatests/test_webui/ui_driver.py  |  28 ++++++
+ 2 files changed, 169 insertions(+)
+ create mode 100644 ipatests/test_webui/test_subid.py
+
+diff --git a/ipatests/test_webui/test_subid.py b/ipatests/test_webui/test_subid.py
+new file mode 100644
+index 000000000..26decdba0
+--- /dev/null
++++ b/ipatests/test_webui/test_subid.py
+@@ -0,0 +1,141 @@
++
++"""
++Tests for subordinateid.
++"""
++
++from ipatests.test_webui.ui_driver import UI_driver
++import ipatests.test_webui.data_config as config_data
++import ipatests.test_webui.data_user as user_data
++from ipatests.test_webui.ui_driver import screenshot
++import re
++
++
++class test_subid(UI_driver):
++
++    def add_user(self, pkey, name, surname):
++        self.add_record('user', {
++            'pkey': pkey,
++            'add': [
++                ('textbox', 'uid', pkey),
++                ('textbox', 'givenname', name),
++                ('textbox', 'sn', surname),
++            ]
++        })
++
++    def set_default_subid(self):
++        self.navigate_to_entity(config_data.ENTITY)
++        self.check_option('ipauserdefaultsubordinateid', 'checked')
++        self.facet_button_click('save')
++
++    def get_user_count(self, user_pkey):
++        self.navigate_to_entity('subid', facet='search')
++        self.apply_search_filter(user_pkey)
++        self.wait_for_request()
++        return self.get_rows()
++
++    @screenshot
++    def test_set_defaultsubid(self):
++        """
++        Test to verify that enable/disable is working for
++        adding subids to new users.
++        """
++        self.init_app()
++        self.add_record(user_data.ENTITY, user_data.DATA2)
++        self.navigate_to_entity(config_data.ENTITY)
++        # test subid can be enabled/disabled.
++        self.set_default_subid()
++        assert self.get_field_checked('ipauserdefaultsubordinateid')
++        self.set_default_subid()
++        assert not self.get_field_checked('ipauserdefaultsubordinateid')
++
++    @screenshot
++    def test_user_defaultsubid(self):
++        """
++        Test to verify that subid is generated for new user.
++        """
++        self.init_app()
++        user_pkey = "some-user"
++
++        self.set_default_subid()
++        assert self.get_field_checked('ipauserdefaultsubordinateid')
++
++        before_count = self.get_user_count(user_pkey)
++        assert len(before_count) == 0
++
++        self.add_user(user_pkey, 'Some', 'User')
++        after_count = self.get_user_count(user_pkey)
++        assert len(after_count) == 1
++
++    @screenshot
++    def test_user_subid_mod_desc(self):
++        """
++        Test to verify that auto-assigned subid description is modified.
++        """
++        self.init_app()
++        self.navigate_to_record("some-user")
++        self.switch_to_facet('memberof_subid')
++        rows = self.get_rows()
++        self.navigate_to_row_record(rows[-1])
++        self.fill_textbox("description", "some-user-subid-desc")
++        self.facet_button_click('save')
++
++    @screenshot
++    def test_admin_subid(self):
++        """
++        Test to verify that subid range is created with owner admin.
++        """
++        self.init_app()
++        self.navigate_to_entity('subid', facet='search')
++        self.facet_button_click('add')
++        self.select_combobox('ipaowner', 'admin')
++        self.dialog_button_click('add')
++        self.wait(0.3)
++        self.assert_no_error_dialog()
++
++    @screenshot
++    def test_admin_subid_negative(self):
++        """
++        Test to verify that readding the subid fails with error.
++        """
++        self.init_app()
++        self.navigate_to_entity('subid', facet='search')
++        self.facet_button_click('add')
++        self.select_combobox('ipaowner', 'admin')
++        self.dialog_button_click('add')
++        self.wait(0.3)
++        err_dialog = self.get_last_error_dialog(dialog_name='error_dialog')
++        text = self.get_text('.modal-body div p', err_dialog)
++        text = text.strip()
++        pattern = r'Subordinate id with with name .* already exists.'
++        assert re.search(pattern, text) is not None
++        self.close_all_dialogs()
++
++    @screenshot
++    def test_user_subid_add(self):
++        """
++        Test to verify that subid range is created for given user.
++        """
++        self.init_app()
++        self.navigate_to_entity('subid', facet='search')
++        before_count = self.get_rows()
++        self.facet_button_click('add')
++        self.select_combobox('ipaowner', user_data.PKEY2)
++        self.dialog_button_click('add')
++        self.wait(0.3)
++        self.assert_no_error_dialog()
++        after_count = self.get_rows()
++        assert len(before_count) < len(after_count)
++
++    @screenshot
++    def test_subid_del(self):
++        """
++        Test to remove subordinate id for given user.
++        """
++        self.init_app()
++        self.navigate_to_entity('subid', facet='search')
++        user_uid = self.get_record_pkey("some-user", "ipaowner",
++                                        table_name="ipauniqueid")
++        before_count = self.get_rows()
++        self.delete_record(user_uid, table_name="ipauniqueid")
++        after_count = self.get_rows()
++        assert len(before_count) > len(after_count)
+diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py
+index 46fd512ae..77fd74e49 100644
+--- a/ipatests/test_webui/ui_driver.py
++++ b/ipatests/test_webui/ui_driver.py
+@@ -1151,6 +1151,34 @@ class UI_driver:
+                 return row
+         return None
+ 
++    def get_row_by_column_value(self, key, column_name, parent=None,
++                                table_name=None):
++        """
++        Get the first matched row element of a search table with given key
++        matched against selected column. None if not found
++        """
++        rows = self.get_rows(parent, table_name)
++        s = "td div[name='%s']" % column_name
++        for row in rows:
++            has = self.find(s, By.CSS_SELECTOR, row)
++            if has.text == key:
++                return row
++        return None
++
++    def get_record_pkey(self, key, column, parent=None, table_name=None):
++        """
++        Get record pkey if value of column is known
++        """
++        row = self.get_row_by_column_value(key,
++                                           column_name=column,
++                                           parent=parent,
++                                           table_name=table_name)
++        val = None
++        if row:
++            el = self.find("td input", By.CSS_SELECTOR, row)
++            val = el.get_attribute("value")
++        return val
++
+     def navigate_to_row_record(self, row, pkey_column=None):
+         """
+         Navigate to record by clicking on a link.
+-- 
+2.34.1
+
+From 419d7fd6e5a9ed2d356ad05eef1043309f5646ef Mon Sep 17 00:00:00 2001
+From: Michal Polovka <mpolovka@redhat.com>
+Date: Fri, 7 Jan 2022 12:12:26 +0100
+Subject: [PATCH] ipatests: webui: Use safe-loader for loading YAML
+ configuration file
+
+FullLoader class for YAML loader was introduced in version 5.1 which
+also deprecated default loader. SafeLoader, however, stays consistent
+across the versions and brings added security.
+
+This fix is necessary as PyYAML > 5.1 is not available in downstream.
+
+Related: https://pagure.io/freeipa/issue/9009
+
+Signed-off-by: Michal Polovka <mpolovka@redhat.com>
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ ipatests/test_webui/ui_driver.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py
+index 77fd74e49..519efee9b 100644
+--- a/ipatests/test_webui/ui_driver.py
++++ b/ipatests/test_webui/ui_driver.py
+@@ -192,7 +192,7 @@ class UI_driver:
+         if not NO_YAML and os.path.isfile(path):
+             try:
+                 with open(path, 'r') as conf:
+-                    cls.config = yaml.load(stream=conf, Loader=yaml.FullLoader)
++                    cls.config = yaml.safe_load(stream=conf)
+             except yaml.YAMLError as e:
+                 pytest.skip("Invalid Web UI config.\n%s" % e)
+             except IOError as e:
+-- 
+2.34.1
+
+From 5444da016edc416c0c9481c660c013053dbb93b5 Mon Sep 17 00:00:00 2001
+From: Mohammad Rizwan <myusuf@redhat.com>
+Date: Thu, 18 Nov 2021 18:43:22 +0530
+Subject: [PATCH] PEP8 Fixes
+
+Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
+---
+ .../test_integration/test_replica_promotion.py     | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
+index 1a4e9bc12..c328b1a08 100644
+--- a/ipatests/test_integration/test_replica_promotion.py
++++ b/ipatests/test_integration/test_replica_promotion.py
+@@ -138,7 +138,6 @@ class TestReplicaPromotionLevel1(ReplicaPromotionBase):
+         assert res.returncode == 1
+         assert expected_err in res.stderr_text
+ 
+-
+     @replicas_cleanup
+     def test_one_command_installation(self):
+         """
+@@ -150,11 +149,11 @@ class TestReplicaPromotionLevel1(ReplicaPromotionBase):
+         Firewall(self.replicas[0]).enable_services(["freeipa-ldap",
+                                                     "freeipa-ldaps"])
+         self.replicas[0].run_command(['ipa-replica-install', '-w',
+-                                     self.master.config.admin_password,
+-                                     '-n', self.master.domain.name,
+-                                     '-r', self.master.domain.realm,
+-                                     '--server', self.master.hostname,
+-                                     '-U'])
++                                      self.master.config.admin_password,
++                                      '-n', self.master.domain.name,
++                                      '-r', self.master.domain.realm,
++                                      '--server', self.master.hostname,
++                                      '-U'])
+         # Ensure that pkinit is properly configured, test for 7566
+         result = self.replicas[0].run_command(['ipa-pkinit-manage', 'status'])
+         assert "PKINIT is enabled" in result.stdout_text
+@@ -321,7 +320,7 @@ class TestWrongClientDomain(IntegrationTest):
+         result1 = client.run_command(['ipa-replica-install', '-U', '-w',
+                                       self.master.config.dirman_password],
+                                      raiseonerr=False)
+-        assert(result1.returncode == 0), (
++        assert (result1.returncode == 0), (
+             'Failed to promote the client installed with the upcase domain name')
+ 
+     def test_client_rollback(self):
+@@ -355,6 +354,7 @@ class TestWrongClientDomain(IntegrationTest):
+         assert("An error occurred while removing SSSD" not in
+                result.stdout_text)
+ 
++
+ class TestRenewalMaster(IntegrationTest):
+ 
+     topology = 'star'
+-- 
+2.34.1
+
+From 1d19b860d4cd3bd65a4b143b588425d9a64237fd Mon Sep 17 00:00:00 2001
+From: Mohammad Rizwan <myusuf@redhat.com>
+Date: Thu, 18 Nov 2021 18:36:58 +0530
+Subject: [PATCH] Test cases for ipa-replica-conncheck command
+
+Following test cases would be checked:
+- when called with --principal (it should then prompt for a password)
+- when called with --principal / --password
+- when called without principal and password but with a kerberos TGT,
+  kinit admin done before calling ipa-replica-conncheck
+- when called without principal and password, and without any kerberos
+  TGT (it should default to principal=admin and prompt for a password)
+
+related: https://pagure.io/freeipa/issue/9047
+
+Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
+---
+ .../test_replica_promotion.py                 | 70 +++++++++++++++++++
+ 1 file changed, 70 insertions(+)
+
+diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
+index b9c56f775..1a4e9bc12 100644
+--- a/ipatests/test_integration/test_replica_promotion.py
++++ b/ipatests/test_integration/test_replica_promotion.py
+@@ -437,6 +437,76 @@ class TestRenewalMaster(IntegrationTest):
+         self.assertCARenewalMaster(master, replica.hostname)
+         self.assertCARenewalMaster(replica, replica.hostname)
+ 
++    def test_replica_concheck(self):
++        """Test cases for ipa-replica-conncheck command
++
++        Following test cases would be checked:
++        - when called with --principal (it should then prompt for a password)
++        - when called with --principal / --password
++        - when called without principal and password but with a kerberos TGT,
++          kinit admin done before calling ipa-replica-conncheck
++        - when called without principal and password, and without any kerberos
++          TGT (it should default to principal=admin and prompt for a password)
++
++          related: https://pagure.io/freeipa/issue/9047
++        """
++        exp_str1 = "Connection from replica to master is OK."
++        exp_str2 = "Connection from master to replica is OK"
++        tasks.kdestroy_all(self.replicas[0])
++        # when called with --principal (it should then prompt for a password)
++        result = self.replicas[0].run_command(
++            ['ipa-replica-conncheck', '--auto-master-check',
++             '--master', self.master.hostname,
++             '-r', self.replicas[0].domain.realm,
++             '-p', self.replicas[0].config.admin_name],
++            stdin_text=self.master.config.admin_password
++        )
++        assert result.returncode == 0
++        assert (
++            exp_str1 in result.stderr_text and exp_str2 in result.stderr_text
++        )
++
++        # when called with --principal / --password
++        result = self.replicas[0].run_command([
++            'ipa-replica-conncheck', '--auto-master-check',
++            '--master', self.master.hostname,
++            '-r', self.replicas[0].domain.realm,
++            '-p', self.replicas[0].config.admin_name,
++            '-w', self.master.config.admin_password
++        ])
++        assert result.returncode == 0
++        assert (
++            exp_str1 in result.stderr_text and exp_str2 in result.stderr_text
++        )
++
++        # when called without principal and password, and without
++        # any kerberos TGT, it should default to principal=admin
++        # and prompt for a password
++        result = self.replicas[0].run_command(
++            ['ipa-replica-conncheck', '--auto-master-check',
++             '--master', self.master.hostname,
++             '-r', self.replicas[0].domain.realm],
++            stdin_text=self.master.config.admin_password
++        )
++        assert result.returncode == 0
++        assert (
++            exp_str1 in result.stderr_text and exp_str2 in result.stderr_text
++        )
++
++        # when called without principal and password but with a kerberos TGT,
++        # kinit admin done before calling ipa-replica-conncheck
++        tasks.kinit_admin(self.replicas[0])
++        result = self.replicas[0].run_command(
++            ['ipa-replica-conncheck', '--auto-master-check',
++             '--master', self.master.hostname,
++             '-r', self.replicas[0].domain.realm]
++        )
++        assert result.returncode == 0
++        assert (
++            exp_str1 in result.stderr_text and exp_str2 in result.stderr_text
++        )
++        tasks.kdestroy_all(self.replicas[0])
++
+     def test_automatic_renewal_master_transfer_ondelete(self):
+         # Test that after replica uninstallation, master overtakes the cert
+         # renewal master role from replica (which was previously set there)
+-- 
+2.34.1
+
diff --git a/SOURCES/0006-rhel-platform-add-a-named-crypto-policy-support_rhbz#1982956.patch b/SOURCES/0006-rhel-platform-add-a-named-crypto-policy-support_rhbz#1982956.patch
deleted file mode 100644
index 3f83c40..0000000
--- a/SOURCES/0006-rhel-platform-add-a-named-crypto-policy-support_rhbz#1982956.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 1a5159b216455070eb51b6a11ceaf0033fc8ce4c Mon Sep 17 00:00:00 2001
-From: Alexander Bokovoy <abokovoy@redhat.com>
-Date: Fri, 16 Jul 2021 09:20:33 +0300
-Subject: [PATCH] rhel platform: add a named crypto-policy support
-
-RHEL 8+ provides bind system-wide crypto policy support, enable it.
-
-Fixes: https://pagure.io/freeipa/issue/8925
-Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
-Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
-Reviewed-By: Anuja More <amore@redhat.com>
----
- ipaplatform/rhel/paths.py | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/ipaplatform/rhel/paths.py b/ipaplatform/rhel/paths.py
-index c081ada32..3631550eb 100644
---- a/ipaplatform/rhel/paths.py
-+++ b/ipaplatform/rhel/paths.py
-@@ -30,6 +30,7 @@ from ipaplatform.rhel.constants import HAS_NFS_CONF
- 
- 
- class RHELPathNamespace(RedHatPathNamespace):
-+    NAMED_CRYPTO_POLICY_FILE = "/etc/crypto-policies/back-ends/bind.config"
-     if HAS_NFS_CONF:
-         SYSCONFIG_NFS = '/etc/nfs.conf'
- 
--- 
-2.31.1
-
diff --git a/SOURCES/0007-Don-t-always-override-the-port-in-import_included_profiles_rhbz#2022483.patch b/SOURCES/0007-Don-t-always-override-the-port-in-import_included_profiles_rhbz#2022483.patch
new file mode 100644
index 0000000..f8b3b9f
--- /dev/null
+++ b/SOURCES/0007-Don-t-always-override-the-port-in-import_included_profiles_rhbz#2022483.patch
@@ -0,0 +1,104 @@
+From edb216849e4f47d6cae95981edf0c3fe2653fd7a Mon Sep 17 00:00:00 2001
+From: Rob Crittenden <rcritten@redhat.com>
+Date: Fri, 28 Jan 2022 16:46:35 -0500
+Subject: [PATCH] Don't always override the port in import_included_profiles
+
+I can only guess to the original purpose of this override. I
+believe it was because this is called in the installer prior
+to Apache being set up. The expectation was that this would
+only be called locally. It predates the RestClient class.
+
+RestClient will attempt to find an available service. In this
+case, during a CA installation, the local server is not
+considered available because it lacks an entry in
+cn=masters. So it will never be returned as an option.
+
+So by overriding the port to 8443 the remote connection will
+likely fail because we don't require that the port be open.
+
+So instead, instantiate a RestClient and see what happens.
+
+There are several use-cases:
+
+1. Installing an initial server. The RestClient connection
+   should fail, so we will fall back to the override port and
+   use the local server. If Apache happens to be running with
+   a globally-issued certificate then the RestClient will
+   succeed. In this case if the connected host and the local
+   hostname are the same, override in that case as well.
+
+2. Installing as a replica. In this case the local server should
+   be ignored in all cases and a remote CA will be picked with
+   no override done.
+
+3. Switching from CA-less to CA-ful. The web server will be
+   trusted but the RestClient login will fail with a 404. Fall
+   back to the override port in this case.
+
+The motivation for this is trying to install an EL 8.x replica
+against an EL 7.9 server. 8.5+ includes the ACME service and
+a new profile is needed which doesn't exist in 7. This was
+failing because the RestClient determined that the local server
+wasn't running a CA so tried the remote one (7.9) on the override
+port 8443. Since this port isn't open: failure.
+
+Chances are that adding the profile is still going to fail
+because again, 7.9 lacks ACME capabilities, but it will fail in
+a way that allows the installation to continue.
+
+I suspect that all of the overrides can similarly handled, or
+handled directly within the RestClient class, but for the sake
+of "do no harm" I'm only changing this instance for now.
+
+https://pagure.io/freeipa/issue/9100
+
+Signed-off-by: Rob Crittenden <rcritten@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+---
+ ipaserver/install/cainstance.py | 30 +++++++++++++++++++++++++++++-
+ 1 file changed, 29 insertions(+), 1 deletion(-)
+
+diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
+index 8c8bf1b3a..ad206aad4 100644
+--- a/ipaserver/install/cainstance.py
++++ b/ipaserver/install/cainstance.py
+@@ -1953,7 +1953,35 @@ def import_included_profiles():
+         cn=['certprofiles'],
+     )
+ 
+-    api.Backend.ra_certprofile.override_port = 8443
++    # At this point Apache may or may not be running with a valid
++    # certificate. The local server is not yet recognized as a full
++    # CA yet so it isn't discoverable. So try to do some detection
++    # on what port to use, 443 (remote) or 8443 (local) for importing
++    # the profiles.
++    #
++    # api.Backend.ra_certprofile invokes the RestClient class
++    # which will discover and login to the CA REST API. We can
++    # use this information to detect where to import the profiles.
++    #
++    # If the login is successful (e.g. doesn't raise an exception)
++    # and it returns our hostname (it prefers the local host) then
++    # we override and talk locally.
++    #
++    # Otherwise a NetworkError means we can't connect on 443 (perhaps
++    # a firewall) or we get an HTTP error (valid TLS certificate on
++    # Apache but no CA, login fails with 404) so we override to the
++    # local server.
++    #
++    # When override port was always set to 8443 the RestClient could
++    # pick a remote server and since 8443 isn't in our firewall profile
++    # setting up a new server would fail.
++    try:
++        with api.Backend.ra_certprofile as profile_api:
++            if profile_api.ca_host == api.env.host:
++                api.Backend.ra_certprofile.override_port = 8443
++    except (errors.NetworkError, errors.RemoteRetrieveError) as e:
++        logger.debug('Overriding CA port: %s', e)
++        api.Backend.ra_certprofile.override_port = 8443
+ 
+     for (profile_id, desc, store_issued) in dogtag.INCLUDED_PROFILES:
+         dn = DN(('cn', profile_id),
+-- 
+2.34.1
+
diff --git a/SOURCES/0008-Remove-ipa-join-errors-from-behind-the-debug-option_rhbz#2048558.patch b/SOURCES/0008-Remove-ipa-join-errors-from-behind-the-debug-option_rhbz#2048558.patch
new file mode 100644
index 0000000..e083b06
--- /dev/null
+++ b/SOURCES/0008-Remove-ipa-join-errors-from-behind-the-debug-option_rhbz#2048558.patch
@@ -0,0 +1,115 @@
+From 7c5540bb47799b4db95673d22f61995ad5c56440 Mon Sep 17 00:00:00 2001
+From: Rob Crittenden <rcritten@redhat.com>
+Date: Mon, 31 Jan 2022 17:31:50 -0500
+Subject: [PATCH] Remove ipa-join errors from behind the debug option
+
+This brings it inline with the previous XML-RPC output which
+only hid the request and response from the output and not
+any errors returned.
+
+https://pagure.io/freeipa/issue/9103
+
+Signed-off-by: Rob Crittenden <rcritten@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
+Reviewed-By: Peter Keresztes Schmidt <carbenium@outlook.com>
+---
+ client/ipa-join.c | 27 +++++++++------------------
+ 1 file changed, 9 insertions(+), 18 deletions(-)
+
+diff --git a/client/ipa-join.c b/client/ipa-join.c
+index d98739a9a..5888a33bf 100644
+--- a/client/ipa-join.c
++++ b/client/ipa-join.c
+@@ -743,8 +743,7 @@ jsonrpc_request(const char *ipaserver, const json_t *json, curl_buffer *response
+ 
+     json_str = json_dumps(json, 0);
+     if (!json_str) {
+-        if (debug)
+-            fprintf(stderr, _("json_dumps() failed\n"));
++        fprintf(stderr, _("json_dumps() failed\n"));
+ 
+         rval = 17;
+         goto cleanup;
+@@ -758,8 +757,7 @@ jsonrpc_request(const char *ipaserver, const json_t *json, curl_buffer *response
+     CURLcode res = curl_easy_perform(curl);
+     if (res != CURLE_OK)
+     {
+-        if (debug)
+-            fprintf(stderr, _("JSON-RPC call failed: %s\n"), curl_easy_strerror(res));
++        fprintf(stderr, _("JSON-RPC call failed: %s\n"), curl_easy_strerror(res));
+ 
+         rval = 17;
+         goto cleanup;
+@@ -769,8 +767,7 @@ jsonrpc_request(const char *ipaserver, const json_t *json, curl_buffer *response
+     curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp_code);
+ 
+     if (resp_code != 200) {
+-        if (debug)
+-            fprintf(stderr, _("JSON-RPC call failed with status code: %li\n"), resp_code);
++        fprintf(stderr, _("JSON-RPC call failed with status code: %li\n"), resp_code);
+ 
+         if (!quiet && resp_code == 401)
+             fprintf(stderr, _("JSON-RPC call was unauthorized. Check your credentials.\n"));
+@@ -848,8 +845,7 @@ jsonrpc_parse_response(const char *payload, json_t** j_result_obj, bool quiet) {
+ 
+     j_root = json_loads(payload, 0, &j_error);
+     if (!j_root) {
+-        if (debug)
+-            fprintf(stderr, _("Parsing JSON-RPC response failed: %s\n"), j_error.text);
++        fprintf(stderr, _("Parsing JSON-RPC response failed: %s\n"), j_error.text);
+ 
+         rval = 17;
+         goto cleanup;
+@@ -864,8 +860,7 @@ jsonrpc_parse_response(const char *payload, json_t** j_result_obj, bool quiet) {
+ 
+     *j_result_obj = json_object_get(j_root, "result");
+     if (!*j_result_obj) {
+-        if (debug)
+-            fprintf(stderr, _("Parsing JSON-RPC response failed: no 'result' value found.\n"));
++        fprintf(stderr, _("Parsing JSON-RPC response failed: no 'result' value found.\n"));
+ 
+         rval = 17;
+         goto cleanup;
+@@ -897,8 +892,7 @@ jsonrpc_parse_join_response(const char *payload, join_info *join_i, bool quiet)
+                        &tmp_hostdn,
+                        "krbprincipalname", &tmp_princ,
+                        "krblastpwdchange", &tmp_pwdch) != 0) {
+-        if (debug)
+-            fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
++        fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
+ 
+         rval = 17;
+         goto cleanup;
+@@ -941,8 +935,7 @@ join_krb5_jsonrpc(const char *ipaserver, const char *hostname, char **hostdn, co
+                              "nshardwareplatform", uinfo.machine);
+ 
+     if (!json_req) {
+-        if (debug)
+-            fprintf(stderr, _("json_pack_ex() failed: %s\n"), j_error.text);
++        fprintf(stderr, _("json_pack_ex() failed: %s\n"), j_error.text);
+ 
+         rval = 17;
+         goto cleanup;
+@@ -990,8 +983,7 @@ jsonrpc_parse_unenroll_response(const char *payload, bool* result, bool quiet) {
+ 
+     if (json_unpack_ex(j_result_obj, &j_error, 0, "{s:b}",
+                        "result", result) != 0) {
+-        if (debug)
+-            fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
++        fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
+ 
+         rval = 20;
+         goto cleanup;
+@@ -1021,8 +1013,7 @@ jsonrpc_unenroll_host(const char *ipaserver, const char *host, bool quiet) {
+                             host);
+ 
+     if (!json_req) {
+-        if (debug)
+-            fprintf(stderr, _("json_pack_ex() failed: %s\n"), j_error.text);
++        fprintf(stderr, _("json_pack_ex() failed: %s\n"), j_error.text);
+ 
+         rval = 17;
+         goto cleanup;
+-- 
+2.34.1
+
diff --git a/SOURCES/0009-Enable-the-ccache-sweep-timer-during-installation_rhbz#2051575.patch b/SOURCES/0009-Enable-the-ccache-sweep-timer-during-installation_rhbz#2051575.patch
new file mode 100644
index 0000000..ef581d8
--- /dev/null
+++ b/SOURCES/0009-Enable-the-ccache-sweep-timer-during-installation_rhbz#2051575.patch
@@ -0,0 +1,118 @@
+From 9b6d0bb1245c4891ccc270f360d0f72a4b1444c1 Mon Sep 17 00:00:00 2001
+From: Rob Crittenden <rcritten@redhat.com>
+Date: Mon, 7 Feb 2022 10:39:55 -0500
+Subject: [PATCH] Enable the ccache sweep timer during installation
+
+The timer was only being enabled during package installation
+if IPA was configured. So effectively only on upgrade.
+
+Add as a separate installation step after the ccache directory
+is configured.
+
+Fixes: https://pagure.io/freeipa/issue/9107
+
+Signed-off-by: Rob Crittenden <rcritten@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/install/httpinstance.py | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
+index 732bb58d4..50ccf5e50 100644
+--- a/ipaserver/install/httpinstance.py
++++ b/ipaserver/install/httpinstance.py
+@@ -140,6 +140,8 @@ class HTTPInstance(service.Service):
+         self.step("publish CA cert", self.__publish_ca_cert)
+         self.step("clean up any existing httpd ccaches",
+                   self.remove_httpd_ccaches)
++        self.step("enable ccache sweep",
++                  self.enable_ccache_sweep)
+         self.step("configuring SELinux for httpd", self.configure_selinux_for_httpd)
+         if not self.is_kdcproxy_configured():
+             self.step("create KDC proxy config", self.create_kdcproxy_conf)
+@@ -177,6 +179,11 @@ class HTTPInstance(service.Service):
+             [paths.SYSTEMD_TMPFILES, '--create', '--prefix', paths.IPA_CCACHES]
+         )
+ 
++    def enable_ccache_sweep(self):
++        ipautil.run(
++            [paths.SYSTEMCTL, 'enable', 'ipa-ccache-sweep.timer']
++        )
++
+     def __configure_http(self):
+         self.update_httpd_service_ipa_conf()
+         self.update_httpd_wsgi_conf()
+-- 
+2.34.1
+
+From 0d9eb3d515385412abefe9c33e0099ea14f33cbc Mon Sep 17 00:00:00 2001
+From: Mohammad Rizwan <myusuf@redhat.com>
+Date: Wed, 9 Feb 2022 18:56:21 +0530
+Subject: [PATCH] Test ipa-ccache-sweep.timer enabled by default during
+ installation
+
+This test checks that ipa-ccache-sweep.timer is enabled by default
+during the ipa installation.
+
+related: https://pagure.io/freeipa/issue/9107
+
+Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ .../test_integration/test_installation.py     | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
+index f2d372c0c..63edbaa2b 100644
+--- a/ipatests/test_integration/test_installation.py
++++ b/ipatests/test_integration/test_installation.py
+@@ -475,7 +475,7 @@ class TestInstallCA(IntegrationTest):
+ 
+         # Tweak sysrestore.state to drop installation section
+         self.master.run_command(
+-            ['sed','-i', r's/\[installation\]/\[badinstallation\]/',
++            ['sed', '-i', r's/\[installation\]/\[badinstallation\]/',
+              os.path.join(paths.SYSRESTORE, SYSRESTORE_STATEFILE)])
+ 
+         # Re-run installation check and it should fall back to old method
+@@ -485,7 +485,7 @@ class TestInstallCA(IntegrationTest):
+ 
+         # Restore installation section.
+         self.master.run_command(
+-            ['sed','-i', r's/\[badinstallation\]/\[installation\]/',
++            ['sed', '-i', r's/\[badinstallation\]/\[installation\]/',
+              os.path.join(paths.SYSRESTORE, SYSRESTORE_STATEFILE)])
+ 
+         # Uninstall and confirm that the old method reports correctly
+@@ -690,6 +690,7 @@ def get_pki_tomcatd_pid(host):
+             break
+     return(pid)
+ 
++
+ def get_ipa_services_pids(host):
+     ipa_services_name = [
+         "krb5kdc", "kadmin", "named", "httpd", "ipa-custodia",
+@@ -1309,6 +1310,20 @@ class TestInstallMasterKRA(IntegrationTest):
+     def test_install_master(self):
+         tasks.install_master(self.master, setup_dns=False, setup_kra=True)
+ 
++    def test_ipa_ccache_sweep_timer_enabled(self):
++        """Test ipa-ccache-sweep.timer enabled by default during installation
++
++        This test checks that ipa-ccache-sweep.timer is enabled by default
++        during the ipa installation.
++
++        related: https://pagure.io/freeipa/issue/9107
++        """
++        result = self.master.run_command(
++            ['systemctl', 'is-enabled', 'ipa-ccache-sweep.timer'],
++            raiseonerr=False
++        )
++        assert 'enabled' in result.stdout_text
++
+     def test_install_dns(self):
+         tasks.install_dns(self.master)
+ 
+-- 
+2.34.1
+
diff --git a/SOURCES/0010-ipatests-remove-additional-check-for-failed-units_rhbz#2053024.patch b/SOURCES/0010-ipatests-remove-additional-check-for-failed-units_rhbz#2053024.patch
new file mode 100644
index 0000000..c384f15
--- /dev/null
+++ b/SOURCES/0010-ipatests-remove-additional-check-for-failed-units_rhbz#2053024.patch
@@ -0,0 +1,31 @@
+From b36bcf4ea5ed93baa4dc63f8e2be542d678211fb Mon Sep 17 00:00:00 2001
+From: Anuja More <amore@redhat.com>
+Date: Thu, 10 Feb 2022 18:49:06 +0530
+Subject: [PATCH] ipatests: remove additional check for failed units.
+
+On RHEL tests are randomly failing because of this check
+and the test doesn't need to check this.
+
+Related : https://pagure.io/freeipa/issue/9108
+
+Signed-off-by: Anuja More <amore@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+---
+ ipatests/test_integration/test_otp.py | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
+index d8ce527ca..6e70ddcb3 100644
+--- a/ipatests/test_integration/test_otp.py
++++ b/ipatests/test_integration/test_otp.py
+@@ -316,7 +316,6 @@ class TestOTPToken(IntegrationTest):
+         check_services = self.master.run_command(
+             ['systemctl', 'list-units', '--state=failed']
+         )
+-        assert "0 loaded units listed" in check_services.stdout_text
+         assert "ipa-otpd" not in check_services.stdout_text
+         # Be sure no services are running and failed units
+         self.master.run_command(['killall', 'ipa-otpd'], raiseonerr=False)
+-- 
+2.34.1
+
diff --git a/SOURCES/0011-ipa_cldap-fix-memory-leak_rhbz#2032738.patch b/SOURCES/0011-ipa_cldap-fix-memory-leak_rhbz#2032738.patch
new file mode 100644
index 0000000..3c8109e
--- /dev/null
+++ b/SOURCES/0011-ipa_cldap-fix-memory-leak_rhbz#2032738.patch
@@ -0,0 +1,38 @@
+From 186ebe311bc9545d7a9860cd5e8c748131bbe41e Mon Sep 17 00:00:00 2001
+From: Francisco Trivino <ftrivino@redhat.com>
+Date: Thu, 10 Feb 2022 14:23:12 +0100
+Subject: [PATCH] ipa_cldap: fix memory leak
+
+ipa_cldap_encode_netlogon() allocates memory to store binary data as part of
+berval (bv_val) when processing a CLDAP packet request from a worker. The
+data is used by ipa_cldap_respond() but bv_val is not freed later on.
+
+This commit is adding the corresponding free() after ipa_cldap_respond()
+is completed.
+
+Discovered by LeakSanitizer
+
+Fixes: https://pagure.io/freeipa/issue/9110
+Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
+---
+ daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c
+index db4a3d061..252bcf647 100644
+--- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c
++++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c
+@@ -287,6 +287,7 @@ done:
+     ipa_cldap_respond(ctx, req, &reply);
+ 
+     ipa_cldap_free_kvps(&req->kvps);
++    free(reply.bv_val);
+     free(req);
+     return;
+ }
+-- 
+2.34.1
+
diff --git a/SOURCES/0012-ipatests-fix-TestOTPToken-test_check_otpd_after_idle_timeout_rhbz#2053024.patch b/SOURCES/0012-ipatests-fix-TestOTPToken-test_check_otpd_after_idle_timeout_rhbz#2053024.patch
new file mode 100644
index 0000000..e7081cd
--- /dev/null
+++ b/SOURCES/0012-ipatests-fix-TestOTPToken-test_check_otpd_after_idle_timeout_rhbz#2053024.patch
@@ -0,0 +1,40 @@
+From 4c54e9d6ddb72eab6f654bf3dc2d29f27498ac96 Mon Sep 17 00:00:00 2001
+From: Florence Blanc-Renaud <flo@redhat.com>
+Date: Sun, 5 Dec 2021 17:38:58 +0100
+Subject: [PATCH] ipatests: fix
+ TestOTPToken::test_check_otpd_after_idle_timeout
+
+The test sets 389-ds nsslapd-idletimeout to 60s, then does a
+kinit with an otp token (which makes ipa-otpd create a LDAP
+connection), then sleeps for 60s. The expectation is that
+ns-slapd will detect that the LDAP conn from ipa-otpd is idle
+and close the connection.
+According to 389ds doc, the idle timeout is enforced when the
+connection table is walked. By doing a ldapsearch, the test
+"wakes up" ns-slapd and forces the detection of ipa-otpd
+idle connection.
+
+Fixes: https://pagure.io/freeipa/issue/9044
+Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
+Reviewed-By: Anuja More <amore@redhat.com>
+---
+ ipatests/test_integration/test_otp.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
+index 353470897..d8ce527ca 100644
+--- a/ipatests/test_integration/test_otp.py
++++ b/ipatests/test_integration/test_otp.py
+@@ -354,6 +354,9 @@ class TestOTPToken(IntegrationTest):
+             otpvalue = totp.generate(int(time.time())).decode("ascii")
+             kinit_otp(self.master, USER, password=PASSWORD, otp=otpvalue)
+             time.sleep(60)
++            # ldapsearch will wake up slapd and force walking through
++            # the connection list, in order to spot the idle connections
++            tasks.ldapsearch_dm(self.master, "", ldap_args=[], scope="base")
+ 
+             def test_cb(cmd_jornalctl):
+                 # check if LDAP connection is timed out
+-- 
+2.34.1
+
diff --git a/SOURCES/1101-Harden-FreeIPA-KDC-processing-of-PAC-buffers-20211130.patch b/SOURCES/1101-Harden-FreeIPA-KDC-processing-of-PAC-buffers-20211130.patch
new file mode 100644
index 0000000..48bb8e0
--- /dev/null
+++ b/SOURCES/1101-Harden-FreeIPA-KDC-processing-of-PAC-buffers-20211130.patch
@@ -0,0 +1,122 @@
+From 7d93bda31ce0b4e0e22c6e464c9138800dcf8b1c Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Fri, 26 Nov 2021 11:13:51 +0200
+Subject: [PATCH] ipa-kdb: fix requester SID check according to MS-KILE and
+ MS-SFU updates
+
+New versions of MS-KILE and MS-SFU after Windows Server November 2021
+security updates add PAC_REQUESTER_SID buffer check behavior:
+
+ - PAC_REQUESTER_SID should only be added for TGT requests
+
+ - if PAC_REQUESTER_SID is present, KDC must verify that the cname on
+   the ticket resolves to the account with the same SID as the
+   PAC_REQUESTER_SID. If it doesn't KDC must respond with
+   KDC_ERR_TKT_REVOKED
+
+Change requester SID check to skip exact check for non-local
+PAC_REQUESTER_SID but harden to ensure it comes from the trusted domains
+we know about.
+
+If requester SID is the same as in PAC, we already do cname vs PAC SID
+verification.
+
+With these changes FreeIPA works against Windows Server 2019 with
+November 2021 security fixes in cross-realm S4U2Self operations.
+
+Fixes: https://pagure.io/freeipa/issue/9031
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Rob Crittenden <rcritten@redhat.com>
+---
+ daemons/ipa-kdb/ipa_kdb_mspac.c | 47 ++++++++++++++++++++++++---------
+ 1 file changed, 34 insertions(+), 13 deletions(-)
+
+diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
+index 538cfbba9..1b972c167 100644
+--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
++++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
+@@ -1697,7 +1697,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
+                                       "local [%s], PAC [%s]",
+                                       dom ? dom : "<failed to display>",
+                                       sid ? sid : "<failed to display>");
+-            return KRB5KDC_ERR_POLICY;
++            return KRB5KDC_ERR_TGT_REVOKED;
+         }
+     }
+ 
+@@ -1709,7 +1709,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
+     kerr = ipadb_get_principal(context, client_princ, flags, &client_actual);
+     if (kerr != 0) {
+         krb5_klog_syslog(LOG_ERR, "PAC issue: ipadb_get_principal failed.");
+-        return KRB5KDC_ERR_POLICY;
++        return KRB5KDC_ERR_TGT_REVOKED;
+     }
+ 
+     ied = (struct ipadb_e_data *)client_actual->e_data;
+@@ -1743,7 +1743,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
+                                   "local [%s] vs PAC [%s]",
+                                   local_sid ? local_sid : "<failed to display>",
+                                   pac_sid ? pac_sid : "<failed to display>");
+-        kerr = KRB5KDC_ERR_POLICY;
++        kerr = KRB5KDC_ERR_TGT_REVOKED;
+         goto done;
+     }
+ 
+@@ -2005,22 +2005,43 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context,
+     /* Check that requester SID is the same as in the PAC entry */
+     if (requester_sid != NULL) {
+         struct dom_sid client_sid;
++        bool is_from_trusted_domain = false;
+         kerr = ipadb_get_sid_from_pac(tmpctx, info.info, &client_sid);
+         if (kerr) {
+             goto done;
+         }
+         result = dom_sid_check(&client_sid, requester_sid, true);
+         if (!result) {
+-            /* memctx is freed by the caller */
+-            char *pac_sid = dom_sid_string(tmpctx, &client_sid);
+-            char *req_sid = dom_sid_string(tmpctx, requester_sid);
+-            krb5_klog_syslog(LOG_ERR, "PAC issue: PAC has a SID "
+-                                      "different from what PAC requester claims. "
+-                                      "PAC [%s] vs PAC requester [%s]",
+-                                      pac_sid ? pac_sid : "<failed to display>",
+-                                      req_sid ? req_sid : "<failed to display>");
+-            kerr = KRB5KDC_ERR_POLICY;
+-            goto done;
++            struct ipadb_context *ipactx = ipadb_get_context(context);
++            if (!ipactx || !ipactx->mspac) {
++                return KRB5_KDB_DBNOTINITED;
++            }
++            /* In S4U case we might be dealing with the PAC issued by the trusted domain */
++            if (is_s4u && (ipactx->mspac->trusts != NULL)) {
++                /* Iterate through list of trusts and check if this SID belongs to
++                * one of the domains we trust */
++                for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
++                    result = dom_sid_check(&ipactx->mspac->trusts[i].domsid,
++                                           requester_sid, false);
++                    if (result) {
++                        is_from_trusted_domain = true;
++                        break;
++                    }
++                }
++            }
++
++            if (!is_from_trusted_domain) {
++                /* memctx is freed by the caller */
++                char *pac_sid = dom_sid_string(tmpctx, &client_sid);
++                char *req_sid = dom_sid_string(tmpctx, requester_sid);
++                krb5_klog_syslog(LOG_ERR, "PAC issue: PAC has a SID "
++                                        "different from what PAC requester claims. "
++                                        "PAC [%s] vs PAC requester [%s]",
++                                        pac_sid ? pac_sid : "<failed to display>",
++                                        req_sid ? req_sid : "<failed to display>");
++                kerr = KRB5KDC_ERR_TGT_REVOKED;
++                goto done;
++            }
+         }
+     }
+ 
+-- 
+2.31.1
+
diff --git a/SOURCES/freeipa-4.9.6.tar.gz.asc b/SOURCES/freeipa-4.9.6.tar.gz.asc
deleted file mode 100644
index f71d351..0000000
--- a/SOURCES/freeipa-4.9.6.tar.gz.asc
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN PGP SIGNATURE-----
-
-iQIzBAABCgAdFiEEhAodHH8+xLL+UwQ1RxniuKu/YhoFAmDbPRQACgkQRxniuKu/
-Yhr7uBAAnpF70nH8Cn/HhKKpfafPoN3B9fDNIfAa+jsJ52OyeNMKVNi4MEob32iN
-1aMGGFCJUMle/M7v1+w8WH59eiHs1jKHcFZnl2R4Ap5SxVtypYT+ewXbNnSHII2w
-qWS5PvLkJwjh6Bw/HlyBwDRSrw9Yah4oZZbJt3zE06+Imr8BpB3IWqyhuAi7FjYO
-J9hHCwCvtJvWK4yplZSXCt8OS1JA68/Djgjecm5lUSamuqKaBVhDb+ZAPLDJpBf5
-Pz2JpUF/W/rplt+Q9wAFdhDB9iC0vd3MBkgs4KPsjuyS9+GGNu8LyXs0C1Wm/VgX
-liX2pjZmpnTrhH3QQ2nufwH784ZpinXxS2fcbvCfX1Utgr77wNHjwqDt2NBffJl1
-BM7JJr1ZwGOGSki6yjRDXbeSAsiEX9l7f2mv2t/8ZjHMRJ7mJmBbmh5Qhk5qsMou
-BptNDE20cG77xcjBtTCDpii/UatETuNAyMd/l2smfe76z8y61fQrvScxRwOCHckw
-u/ERChpBZOUlQt59Efj3ja313oXZMxXRw01n/72Hh5rnk+XZf75zQ1zUDBYnwzAr
-4cdqyrfpFkQu1sRQvgjT8ZLkP8istjRdVEI/Oj61zb5+6+scQ/Zh/R/mYGCV4/h+
-RzojBwUAXuwUMrj1jTbb5Lkz58+vY3Lk4xNOY2hSAc8rCcDVRZY=
-=TQFs
------END PGP SIGNATURE-----
diff --git a/SOURCES/freeipa-4.9.8.tar.gz.asc b/SOURCES/freeipa-4.9.8.tar.gz.asc
new file mode 100644
index 0000000..c14420c
--- /dev/null
+++ b/SOURCES/freeipa-4.9.8.tar.gz.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCAAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmGf1XcACgkQaYdvcqbi
+00/kMQ//Vano94V0/L3YsLaqKiFcGo/py5pTq1Os3wB9zzCYSuU0P/eajuHLBYNe
+MfxecZihFFlmUdNooNWbewT4CE0ey1qFLwPfGXuLrse6fXVLLaYnAv2mkPUmDSpM
+XfXO0PFU0BtdkMAUsdUATngPCpQzYjVUKsAMwPovi3UcLzFZ8tWJKMA55urhwC4q
+E042wPLqzcX6Ee5JBSBkfNe35vG2LY7o3Ynh8SVCee2lBJvdWiuFT5XRhybXUsOp
+q3eTsVPz68p7CvOrjlLSsWPP0nbGF1O1UQsN+oaDZAav1Nx8lTOlxUCUQXWbs2X6
+BTUAOmZ6VjYu61sNgNSj+BSHlHIT3uRJ55JO5nLH/hLm0Oxn6SGRTVMueqV376QA
+CsIk7UrdcX9QUtu70eRxuu1aAWJ5eaF4GDWnFP+62wzd/d6LjWEE+9kXgvrcTF0C
+UzjWrmbI8x23bB4kqcROHz8lryMsBpZ94QKPHVppMiPgapDKRkculYkSeRLboADi
+q4mh2prkDSq9diWV4HvZTGwPU77oiLrQsvbGuvwD62PAlyQ4rZpfW3FllTL2Lcxy
+urA8a9UnQWQtDOsZIyxmMJ7R04gjI5fZfDhq6S09L9MfjFEKjsqO4FzXamj+SbAo
+w25sIp1qT0sV1vOt+/R/HYSIyggQyTZpQJu5UB34QLqpfDdUwFg=
+=t9up
+-----END PGP SIGNATURE-----
diff --git a/SPECS/ipa.spec b/SPECS/ipa.spec
index 694581c..c2fd678 100644
--- a/SPECS/ipa.spec
+++ b/SPECS/ipa.spec
@@ -68,8 +68,8 @@
 %global krb5_kdb_version 8.0
 # 0.7.16: https://github.com/drkjam/netaddr/issues/71
 %global python_netaddr_version 0.7.19
-# Require 4.7.0 which brings Python 3 bindings
-%global samba_version 4.12.3-12
+# Require 4.14.5-13 which brings CVE-2020-25717 fixes
+%global samba_version 4.14.5-13
 %global selinux_policy_version 3.14.3-52
 %global slapi_nis_version 0.56.4
 %global python_ldap_version 3.1.0-1
@@ -92,9 +92,9 @@
 %global krb5_version 1.18.2-29
 # 0.7.16: https://github.com/drkjam/netaddr/issues/71
 %global python_netaddr_version 0.7.16
-# Require 4.7.0 which brings Python 3 bindings
-# Require 4.12 which has DsRGetForestTrustInformation access rights fixes
-%global samba_version 2:4.12.10
+
+# Require 4.14.6 which brings CVE-2020-25717 fixes
+%global samba_version 2:4.14.6
 
 # 3.14.5-45 or later includes a number of interfaces fixes for IPA interface
 %global selinux_policy_version 3.14.5-45
@@ -178,7 +178,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.9.6
+%define IPA_VERSION 4.9.8
 # Release candidate version -- uncomment with one percent for RC versions
 #%%global rc_version %%nil
 %define AT_SIGN @
@@ -191,7 +191,7 @@
 
 Name:           %{package_name}
 Version:        %{IPA_VERSION}
-Release:        4%{?rc_version:.%rc_version}%{?dist}
+Release:        6%{?rc_version:.%rc_version}%{?dist}
 Summary:        The Identity, Policy and Audit system
 
 License:        GPLv3+
@@ -211,16 +211,23 @@ Source1:        https://releases.pagure.org/freeipa/freeipa-%{version}%{?rc_vers
 # RHEL spec file only: START
 %if %{NON_DEVELOPER_BUILD}
 %if 0%{?rhel} >= 8
-Patch0001:      0001-rpcserver.py-perf_counter_ns-is-Python-3.7_rhbz#1974822.patch
-Patch0002:      0002-Add-checks-to-prevent-adding-auth-indicators-to-inte_rhbz#1979625.patch
-Patch0003:      0003-stageuser-add-ipauserauthtypeclass-when-required_rhbz#1979605.patch
-Patch0004:      0004-man-page-update-ipa-server-upgrade.1_rhbz#1973273.patch
-Patch0005:      0005-Fall-back-to-krbprincipalname-when-validating-host-a_rhbz#1979625.patch
-Patch0006:      0006-rhel-platform-add-a-named-crypto-policy-support_rhbz#1982956.patch
+Patch0001:      0001-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
+Patch0002:      0002-Config-plugin-return-EmptyModlist-when-no-change-is-applied_rhbz#2031825.patch
+Patch0003:      0003-Custodia-use-a-stronger-encryption-algo-when-exporting-keys_rhbz#2032806.patch
+Patch0004:      0004-ipa-kdb-do-not-remove-keys-for-hardened-auth-enabled-users_rhbz#2033342.patch
+Patch0005:      0005-ipa-pki-proxy.conf-provide-access-to-kra-admin-kra-getStatus_rhbz#2049167.patch
+Patch0006:      0006-Backport-latest-test-fxes-in-python3-ipatests_rhbz#2048509.patch
+Patch0007:      0007-Don-t-always-override-the-port-in-import_included_profiles_rhbz#2022483.patch
+Patch0008:      0008-Remove-ipa-join-errors-from-behind-the-debug-option_rhbz#2048558.patch
+Patch0009:      0009-Enable-the-ccache-sweep-timer-during-installation_rhbz#2051575.patch
+Patch0010:      0010-ipatests-remove-additional-check-for-failed-units_rhbz#2053024.patch
+Patch0011:      0011-ipa_cldap-fix-memory-leak_rhbz#2032738.patch
+Patch0012:      0012-ipatests-fix-TestOTPToken-test_check_otpd_after_idle_timeout_rhbz#2053024.patch
 Patch1001:      1001-Change-branding-to-IPA-and-Identity-Management.patch
 %endif
 %endif
 # RHEL spec file only: END
+Patch1101:      1101-Harden-FreeIPA-KDC-processing-of-PAC-buffers-20211130.patch
 
 # For the timestamp trick in patch application
 BuildRequires:  diffstat
@@ -464,6 +471,8 @@ Requires: gssproxy >= 0.7.0-2
 Requires: sssd-dbus >= %{sssd_version}
 Requires: libpwquality
 Requires: cracklib-dicts
+# NDR libraries are internal in Samba and change with version without changing SONAME
+Requires: samba-client-libs >= %{samba_version}
 
 Provides: %{alt_name}-server = %{version}
 Conflicts: %{alt_name}-server
@@ -1363,6 +1372,7 @@ fi
 %{_libexecdir}/ipa/ipa-pki-wait-running
 %{_libexecdir}/ipa/ipa-otpd
 %{_libexecdir}/ipa/ipa-print-pac
+%{_libexecdir}/ipa/ipa-subids
 %dir %{_libexecdir}/ipa/custodia
 %attr(755,root,root) %{_libexecdir}/ipa/custodia/ipa-custodia-dmldap
 %attr(755,root,root) %{_libexecdir}/ipa/custodia/ipa-custodia-pki-tomcat
@@ -1370,6 +1380,7 @@ fi
 %attr(755,root,root) %{_libexecdir}/ipa/custodia/ipa-custodia-ra-agent
 %dir %{_libexecdir}/ipa/oddjob
 %attr(0755,root,root) %{_libexecdir}/ipa/oddjob/org.freeipa.server.conncheck
+%attr(0755,root,root) %{_libexecdir}/ipa/oddjob/org.freeipa.server.config-enable-sid
 %attr(0755,root,root) %{_libexecdir}/ipa/oddjob/org.freeipa.server.trust-enable-agent
 %config(noreplace) %{_sysconfdir}/dbus-1/system.d/org.freeipa.server.conf
 %config(noreplace) %{_sysconfdir}/oddjobd.conf.d/ipa-server.conf
@@ -1702,6 +1713,72 @@ fi
 
 
 %changelog
+* Mon Feb 14 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.8-6
+- ipatests: fix TestOTPToken::test_check_otpd_after_idle_timeout
+  Related: RHBZ#2053024
+
+* Mon Feb 14 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.8-5
+- ipatests: remove additional check for failed units.
+  Resolves: RHBZ#2053024
+- ipa-cldap: fix memory leak.
+  Resolves: RHBZ#2032738
+
+* Thu Feb 10 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.8-4
+- Don't always override the port in import_included_profiles
+  Fixes: RHBZ#2022483
+- Remove ipa-join errors from behind the debug option
+  Fixes: RHBZ#2048558
+- Enable the ccache sweep timer during installation
+  Fixes: RHBZ#2051575
+
+* Thu Feb 3 2022 Rafael Jeffman <rjeffman@redhat.com> - 4.9.8-3
+- Config plugin: return EmptyModlist when no change is applied.
+  Resolves: RHBZ#2031825
+- Custodia: use a stronger encryption algo when exporting keys.
+  Resolves: RHBZ#2032806
+- ipa-kdb: do not remove keys for hardened auth-enabled users.
+  Resolves: RHBZ#2033342
+- ipa-pki-proxy.conf: provide access to /kra/admin/kra/getStatus
+  Resolves: RHBZ#2049167
+- Backport latest test fxes in python3 ipatests.
+  Resolves: RHBZ#2048509
+- Removed unused patch files that were part of 4.9.8 rebase.
+
+* Fri Dec 10 2021 Rafael Jeffman <rjeffman@redhat.com> - 4.9.8-2
+- Revert bind-pkcs11-utils configuration in freeipa.spec.
+  Resolves: RHBZ#2026732
+
+* Tue Nov 30 2021 Rafael Jeffman <rjeffman@redhat.com> - 4.9.8-1
+- Upstream release FreeIPA 4.9.8
+  Related: RHBZ#2015607
+- Hardening for CVE-2020-25717
+
+* Fri Nov 12 2021 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.6-9.1
+- Fix S4U2Self regression for cross-realm requester SID buffer
+- Related: RHBZ#2021443
+
+* Fri Nov 12 2021 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.6-9
+- Require samba 4.14.5-13 with IPA DC server role fixes
+- Related: RHBZ#2021443
+
+* Fri Nov 12 2021 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.6-8
+- Add versioned dependency of samba-client-libs to ipa-server
+- Related: RHBZ#2021443
+
+* Thu Nov 11 2021 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.6-7
+- Hardening for CVE-2020-25717
+- Harden processing of trusted domains' users in S4U operations
+- Resolves: RHBZ#2021443
+
+* Wed Nov 10 2021 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.6-6
+- Hardening for CVE-2020-25717
+- Rebuild against samba-4.14.5-11.el8
+- Resolves: RHBZ#2021443
+
+* Sun Nov 07 2021 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.6-5
+- Hardening for CVE-2020-25717
+- Related: RHBZ#2019668
+
 * Thu Jul 22 2021 Thomas Woerner <twoerner@redhat.com> - 4.9.6-4
 - ipatests: NAMED_CRYPTO_POLICY_FILE not defined for RHEL
   Resolves: RHBZ#1982956
@@ -2227,7 +2304,7 @@ fi
   - Checks if replica-s4u2proxy.ldif should be applied
 - Resolves: #1493150 [RFE] set nsslapd-ignore-time-skew: on by default
   - ds: ignore time skew during initial replication step
-  - ipa-replica-manage: implicitly ignore initial time skew in force-sync 
+  - ipa-replica-manage: implicitly ignore initial time skew in force-sync
 - Resolves: #1500218 Replica installation at domain-level 0 fails against
   upgraded ipa-server
   - Fix ipa-replica-conncheck when called with --principal
@@ -2271,29 +2348,29 @@ fi
 - Use OpenJDK 8 to bootstrap on AArch64 until RH1482244 is resolved in
   buildroot
 - Resolves: #1470177 - Rebase IPA to latest 4.5.x version
-- Resolves: #1398594 ipa topologysuffix-verify should only warn about 
-  maximum number of replication agreements. 
-- Resolves: #1404236 Web UI: Change "Host Based" and "Role Based" 
-  to "Host-Based" and "Role-Based" 
+- Resolves: #1398594 ipa topologysuffix-verify should only warn about
+  maximum number of replication agreements.
+- Resolves: #1404236 Web UI: Change "Host Based" and "Role Based"
+  to "Host-Based" and "Role-Based"
 - Resolves: #1409786 Second phase of --external-ca ipa-server-install
   setup fails when dirsrv is not running
-- Resolves: #1451576 ipa cert-request failed to generate certificate from csr 
-- Resolves: #1452086 Pagination Size under Customization in IPA WebUI 
+- Resolves: #1451576 ipa cert-request failed to generate certificate from csr
+- Resolves: #1452086 Pagination Size under Customization in IPA WebUI
   accepts negative values
-- Resolves: #1458169 --force-join option is not mentioned in 
-  ipa-replica-install man page 
-- Resolves: #1463186 IPA shouldn't allow objectclass if not all in lower case 
-- Resolves: #1478322 user-show command fails when sizelimit is configured 
-  to number <= number of entity which is user member of 
+- Resolves: #1458169 --force-join option is not mentioned in
+  ipa-replica-install man page
+- Resolves: #1463186 IPA shouldn't allow objectclass if not all in lower case
+- Resolves: #1478322 user-show command fails when sizelimit is configured
+  to number <= number of entity which is user member of
 - Resolves: #1496775 Enterprise principals should be able to trigger
   a refresh of the trusted domain data in the KDC
-- Resolves: #1502533 Changing cert-find to go through the proxy 
+- Resolves: #1502533 Changing cert-find to go through the proxy
   instead of using the port 8080
 - Resolves: #1502663 pkinit-status command fails after an upgrade from
   a pre-4.5 IPA
 - Resolves: #1498168 Error when trying to modify a PTR record
 - Resolves: #1457876 ipa-backup fails silently
-- Resolves: #1493531 In case full PKINIT configuration is failing during 
+- Resolves: #1493531 In case full PKINIT configuration is failing during
   server/replica install the error message should be more meaningful.
 - Resolves: #1449985 Suggest CA installation command in KRA installation
   warning
@@ -2344,7 +2421,7 @@ fi
   - Restore old version of caIPAserviceCert for upgrade only
 
 * Fri Jul 28 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-21.el7.1
-- Resolves: #1455946 Provide a tooling automating the configuration 
+- Resolves: #1455946 Provide a tooling automating the configuration
   of Smart Card authentication on a FreeIPA master
   - smart-card advises: configure systemwide NSS DB also on master
   - smart-card advises: add steps to store smart card signing CA cert
@@ -2358,7 +2435,7 @@ fi
   - smart card advises: use a wrapper around Bash `for` loops
   - smart card advise: use password when changing trust flags on HTTP cert
   - smart-card-advises: ensure that krb5-pkinit is installed on client
-- Resolves: #1475238 Use CommonNameToSANDefault in default profile 
+- Resolves: #1475238 Use CommonNameToSANDefault in default profile
   (new installs only)
   - Add CommonNameToSANDefault to default cert profile
 - Resolves: #1464205 NULL LDAP context in call to ldap_search_ext_s
@@ -2381,11 +2458,11 @@ fi
 * Wed Jun 21 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-19.el7
 - Resolves: #1462112 ipaserver installation fails in FIPS mode: OpenSSL
   internal error, assertion failed: Digest MD4 forbidden in FIPS mode!
-  - ipa-sam: replace encode_nt_key() with E_md4hash() 
+  - ipa-sam: replace encode_nt_key() with E_md4hash()
   - ipa_pwd_extop: do not generate NT hashes in FIPS mode
 - Resolves: #1377973 ipa-server-install fails when the provided or resolved
-  IP address is not found on local interfaces 
-  - Fix local IP address validation 
+  IP address is not found on local interfaces
+  - Fix local IP address validation
   - ipa-dns-install: remove check for local ip address
   - refactor CheckedIPAddress class
   - CheckedIPAddress: remove match_local param
@@ -2398,7 +2475,7 @@ fi
   - kra: promote: Get ticket before calling custodia
 
 * Wed Jun 14 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-17.el7
-- Resolve: #1455946 Provide a tooling automating the configuration 
+- Resolve: #1455946 Provide a tooling automating the configuration
   of Smart Card authentication on a FreeIPA master
   - server certinstall: update KDC master entry
   - pkinit manage: introduce ipa-pkinit-manage
@@ -2423,7 +2500,7 @@ fi
   - Revert setting sessionMaxAge for old clients
 
 * Wed Jun 7 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-15.el7
-- Resolves: #1442233 IPA client commands fail when pointing to replica 
+- Resolves: #1442233 IPA client commands fail when pointing to replica
   - httpinstance: wait until the service entry is replicated
 - Resolves: #1456769 ipaAnchorUUID index incorrectly configured and then
   not indexed
@@ -2437,7 +2514,7 @@ fi
 - Resolves: #1452763 ipa certmaprule change not reflected in krb5kdc workers
   - ipa-kdb: reload certificate mapping rules periodically
 - Resolves: #1455541 after upgrade login from web ui breaks
-  - kdc.key should not be visible to all 
+  - kdc.key should not be visible to all
 - Resolves: #1435606 Add pkinit_indicator option to KDC configuration
   - ipa-kdb: add pkinit authentication indicator in case of a successful
     certauth
@@ -2449,7 +2526,7 @@ fi
   - fix incorrect suffix handling in topology checks
 
 * Wed May 24 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-14.el7
-- Resolves: #1438731 Extend ipa-server-certinstall and ipa-certupdate to 
+- Resolves: #1438731 Extend ipa-server-certinstall and ipa-certupdate to
   handle PKINIT certificates/anchors
   - certdb: add named trust flag constants
   - certdb, certs: make trust flags argument mandatory
@@ -2471,7 +2548,7 @@ fi
   - server install: fix KDC certificate validation in CA-less
 - Resolves: #1451228 ipa-kra-install fails when primary KRA server has been
   decommissioned
-  - ipa-kra-install: fix pkispawn setting for pki_security_domain_hostname 
+  - ipa-kra-install: fix pkispawn setting for pki_security_domain_hostname
 - Resolves: #1451712 KRA installation fails on server that was originally
   installed as CA-less
   - ipa-ca-install: append CA cert chain into /etc/ipa/ca.crt
@@ -2497,14 +2574,14 @@ fi
   - krb5: make sure KDC certificate is readable
 - Resolves: #1455862 "ipa: ERROR: an internal error has occurred" on executing
   command "ipa cert-request --add" after upgrade
-  - Change python-cryptography to python2-cryptography 
+  - Change python-cryptography to python2-cryptography
 
 * Thu May 18 2017 Pavel Vomacka <pvomacka@redhat.com> - 4.5.0-13.el7
 - Resolves: #1451804 "AttributeError: 'tuple' object has no attribute 'append'"
-  error observed during ipa upgrade with latest package. 
+  error observed during ipa upgrade with latest package.
   - ipa-server-install: fix uninstall
 - Resolves: #1445390 ipa-[ca|kra]-install with invalid DM password break
-  replica 
+  replica
   - ca install: merge duplicated code for DM password
   - installutils: add DM password validator
   - ca, kra install: validate DM password
@@ -2514,11 +2591,11 @@ fi
   - python2-ipalib: add missing python dependency
   - installer service: fix typo in service entry
   - upgrade: add missing suffix to http instance
-- Resolves: #1444791 Update man page of ipa-kra-install 
+- Resolves: #1444791 Update man page of ipa-kra-install
   - ipa-kra-install manpage: document domain-level 1
 - Resolves: #1441493 ipa cert-show raises stack traces when
-  --certificate-out=/tmp 
-  - cert-show: writable files does not mean dirs 
+  --certificate-out=/tmp
+  - cert-show: writable files does not mean dirs
 - Resolves: #1441192 Add the name of URL parameter which will be check for
   username during cert login
   - Bump version of ipa.conf file
@@ -2533,9 +2610,9 @@ fi
   - renew agent: always export CSR on IPA CA certificate renewal
   - renew agent: get rid of virtual profiles
   - ipa-cacert-manage: add --external-ca-type
-- Resolves: #1441593 error adding authenticator indicators to host 
+- Resolves: #1441593 error adding authenticator indicators to host
   - Fixing adding authenticator indicators to host
-- Resolves: #1449525 Set directory ownership in spec file 
+- Resolves: #1449525 Set directory ownership in spec file
   - Added plugins directory to ipaclient subpackages
   - ipaclient: fix missing RPM ownership
 - Resolves: #1451279 otptoken-add-yubikey KeyError: 'ipatokenotpdigits'