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/0024-ipatests-Tests-for-Autoprivate-group.patch b/SOURCES/0024-ipatests-Tests-for-Autoprivate-group.patch
new file mode 100644
index 0000000..f66b4cc
--- /dev/null
+++ b/SOURCES/0024-ipatests-Tests-for-Autoprivate-group.patch
@@ -0,0 +1,326 @@
+From 6b70e3c49acc55b5553101cf850fc40978861979 Mon Sep 17 00:00:00 2001
+From: Anuja More <amore@redhat.com>
+Date: Mon, 17 Jan 2022 16:57:52 +0530
+Subject: [PATCH] ipatests: Tests for Autoprivate group.
+
+Added tests using posix AD trust and non posix AD trust.
+For option --auto-private-groups=[hybrid/true/false]
+
+Related : https://pagure.io/freeipa/issue/8807
+
+Signed-off-by: Anuja More <amore@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+Reviewed-By: Anuja More <amore@redhat.com>
+---
+ .../nightly_ipa-4-9_latest.yaml               |   2 +-
+ .../nightly_ipa-4-9_latest_selinux.yaml       |   2 +-
+ .../nightly_ipa-4-9_previous.yaml             |   2 +-
+ ipatests/test_integration/test_trust.py       | 242 +++++++++++++++++-
+ 4 files changed, 240 insertions(+), 8 deletions(-)
+
+diff --git a/ipatests/prci_definitions/nightly_ipa-4-9_latest.yaml b/ipatests/prci_definitions/nightly_ipa-4-9_latest.yaml
+index 6817421b278999c52c32b3e28dd06587e30d874f..8b1f58c4d99e744e319e6c758050a62a8d35c9ee 100644
+--- a/ipatests/prci_definitions/nightly_ipa-4-9_latest.yaml
++++ b/ipatests/prci_definitions/nightly_ipa-4-9_latest.yaml
+@@ -1627,7 +1627,7 @@ jobs:
+         build_url: '{fedora-latest-ipa-4-9/build_url}'
+         test_suite: test_integration/test_trust.py
+         template: *ci-ipa-4-9-latest
+-        timeout: 9000
++        timeout: 10000
+         topology: *adroot_adchild_adtree_master_1client
+ 
+   fedora-latest-ipa-4-9/test_backup_and_restore_TestBackupAndRestoreTrust:
+diff --git a/ipatests/prci_definitions/nightly_ipa-4-9_latest_selinux.yaml b/ipatests/prci_definitions/nightly_ipa-4-9_latest_selinux.yaml
+index 817329756dc145fa5e6bc7aa0477e5df2a6ece5b..a11376ab836e7ed2f942c29753707e5b8e88a00f 100644
+--- a/ipatests/prci_definitions/nightly_ipa-4-9_latest_selinux.yaml
++++ b/ipatests/prci_definitions/nightly_ipa-4-9_latest_selinux.yaml
+@@ -1743,7 +1743,7 @@ jobs:
+         selinux_enforcing: True
+         test_suite: test_integration/test_trust.py
+         template: *ci-ipa-4-9-latest
+-        timeout: 9000
++        timeout: 10000
+         topology: *adroot_adchild_adtree_master_1client
+ 
+   fedora-latest-ipa-4-9/test_backup_and_restore_TestBackupAndRestoreTrust:
+diff --git a/ipatests/prci_definitions/nightly_ipa-4-9_previous.yaml b/ipatests/prci_definitions/nightly_ipa-4-9_previous.yaml
+index 4196265c772ec393ebb8f8bbdc4af845cd6d2d24..3f8ce8b7641fdfdc27278651cbf83c2b152e1a16 100644
+--- a/ipatests/prci_definitions/nightly_ipa-4-9_previous.yaml
++++ b/ipatests/prci_definitions/nightly_ipa-4-9_previous.yaml
+@@ -1627,7 +1627,7 @@ jobs:
+         build_url: '{fedora-previous-ipa-4-9/build_url}'
+         test_suite: test_integration/test_trust.py
+         template: *ci-ipa-4-9-previous
+-        timeout: 9000
++        timeout: 10000
+         topology: *adroot_adchild_adtree_master_1client
+ 
+   fedora-previous-ipa-4-9/test_backup_and_restore_TestBackupAndRestoreTrust:
+diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
+index 0634badbb6a9aa148db2e3062e866215e61e89e7..ff2dd9cc819e1c5620ce449384957a633ae6d1f0 100644
+--- a/ipatests/test_integration/test_trust.py
++++ b/ipatests/test_integration/test_trust.py
+@@ -62,11 +62,12 @@ class BaseTestTrust(IntegrationTest):
+         cls.check_sid_generation()
+         tasks.sync_time(cls.master, cls.ad)
+ 
+-        cls.child_ad = cls.ad_subdomains[0]
+-        cls.ad_subdomain = cls.child_ad.domain.name
+-        cls.tree_ad = cls.ad_treedomains[0]
+-        cls.ad_treedomain = cls.tree_ad.domain.name
+-
++        if cls.num_ad_subdomains > 0:
++            cls.child_ad = cls.ad_subdomains[0]
++            cls.ad_subdomain = cls.child_ad.domain.name
++        if cls.num_ad_treedomains > 0:
++            cls.tree_ad = cls.ad_treedomains[0]
++            cls.ad_treedomain = cls.tree_ad.domain.name
+         # values used in workaround for
+         # https://bugzilla.redhat.com/show_bug.cgi?id=1711958
+         cls.srv_gc_record_name = \
+@@ -106,6 +107,63 @@ class BaseTestTrust(IntegrationTest):
+         expected_text = 'iparangetype: %s\n' % expected_type
+         assert expected_text in result.stdout_text
+ 
++    def mod_idrange_auto_private_group(
++        self, option='false'
++    ):
++        """
++        Set the auto-private-group option of the default trusted
++        AD domain range.
++        """
++        tasks.kinit_admin(self.master)
++        rangename = self.ad_domain.upper() + '_id_range'
++        error_msg = "ipa: ERROR: no modifications to be performed"
++        cmd = ["ipa", "idrange-mod", rangename,
++               "--auto-private-groups", option]
++        result = self.master.run_command(cmd, raiseonerr=False)
++        if result.returncode != 0:
++            tasks.assert_error(result, error_msg)
++        tasks.clear_sssd_cache(self.master)
++        tasks.clear_sssd_cache(self.clients[0])
++        test = self.master.run_command(["ipa", "idrange-show", rangename])
++        assert "Auto private groups: {0}".format(option) in test.stdout_text
++
++    def get_user_id(self, host, username):
++        """
++        User uid gid is parsed from the output of id user command.
++        """
++        tasks.clear_sssd_cache(self.master)
++        tasks.clear_sssd_cache(self.clients[0])
++        self.master.run_command(["id", username])
++        test_id = host.run_command(["id", username])
++        regex = r"^uid=(?P<uid>\d+).*gid=(?P<gid>\d+).*groups=(?P<groups>\d+)"
++        match = re.match(regex, test_id.stdout_text)
++        uid = match.group('uid')
++        gid = match.group('gid')
++        return uid, gid
++
++    @contextmanager
++    def set_idoverrideuser(self, user, uid, gid):
++        """
++        Fixture to add/remove idoverrideuser for default idview,
++        also creates idm group with the provided gid because
++        gid overrides requires an existing group.
++        """
++        tasks.clear_sssd_cache(self.master)
++        tasks.clear_sssd_cache(self.clients[0])
++        tasks.kinit_admin(self.master)
++        try:
++            args = ["ipa", "idoverrideuser-add", "Default Trust View",
++                    "--gid", gid, "--uid", uid, user]
++            self.master.run_command(args)
++            tasks.group_add(self.master, "idgroup",
++                            extra_args=["--gid", gid])
++            yield
++        finally:
++            self.master.run_command([
++                "ipa", "idoverrideuser-del", "Default Trust View", user]
++            )
++            self.master.run_command(["ipa", "group-del", "idgroup"])
++
+     def remove_trust(self, ad):
+         tasks.remove_trust_with_ad(self.master,
+                                    ad.domain.name, ad.hostname)
+@@ -993,3 +1051,177 @@ class TestTrust(BaseTestTrust):
+             self.master.run_command(['rm', '-f', ad_zone_file])
+             tasks.configure_dns_for_trust(self.master, self.ad)
+             self.remove_trust(self.ad)
++
++
++class TestNonPosixAutoPrivateGroup(BaseTestTrust):
++    """
++    Tests for auto-private-groups option with non posix AD trust
++    Related : https://pagure.io/freeipa/issue/8807
++    """
++    topology = 'line'
++    num_ad_domains = 1
++    num_clients = 1
++    num_ad_subdomains = 0
++    num_ad_treedomains = 0
++    uid_override = "99999999"
++    gid_override = "78878787"
++
++    def test_add_nonposix_trust(self):
++        tasks.configure_dns_for_trust(self.master, self.ad)
++        tasks.establish_trust_with_ad(
++            self.master, self.ad_domain,
++            extra_args=['--range-type', 'ipa-ad-trust'])
++
++    @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
++    def test_auto_private_groups_default_trusted_range(self, type):
++        """
++        Modify existing range for default trusted AD domain range
++        with auto-private-groups set as true/hybrid/false and test
++        user with no posix attributes.
++        """
++        self.mod_idrange_auto_private_group(type)
++        nonposixuser = "nonposixuser@%s" % self.ad_domain
++        (uid, gid) = self.get_user_id(self.clients[0], nonposixuser)
++        if type == "true":
++            assert uid == gid
++        else:
++            test_group = self.clients[0].run_command(["id", nonposixuser])
++            gid_str = "gid={0}(domain users@{1})".format(gid, self.ad_domain)
++            grp_str = "groups={0}(domain users@{1})".format(gid,
++                                                            self.ad_domain)
++            assert gid_str in test_group.stdout_text
++            assert grp_str in test_group.stdout_text
++            assert uid != gid
++
++    @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
++    def test_idoverride_with_auto_private_group(self, type):
++        """
++        Override ad trusted user in default trust view
++        and set auto-private-groups=[hybrid,true,false]
++        and ensure that overridden values takes effect.
++        """
++        nonposixuser = "nonposixuser@%s" % self.ad_domain
++        with self.set_idoverrideuser(nonposixuser,
++                                     self.uid_override,
++                                     self.gid_override
++                                     ):
++            self.mod_idrange_auto_private_group(type)
++            (uid, gid) = self.get_user_id(self.clients[0], nonposixuser)
++            assert (uid == self.uid_override and gid == self.gid_override)
++            test_group = self.clients[0].run_command(
++                ["id", nonposixuser]).stdout_text
++            assert "domain users@{0}".format(self.ad_domain) in test_group
++
++    @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
++    def test_nonposixuser_nondefault_primary_group(self, type):
++        """
++        Test for non default primary group.
++        For hybrid/false gid corresponds to the group testgroup1.
++        """
++        nonposixuser1 = "nonposixuser1@%s" % self.ad_domain
++        self.mod_idrange_auto_private_group(type)
++        (uid, gid) = self.get_user_id(self.clients[0], nonposixuser1)
++        if type == "true":
++            assert uid == gid
++        else:
++            test_group = self.clients[0].run_command(["id", nonposixuser1])
++            gid_str = "gid={0}(testgroup1@{1})".format(gid, self.ad_domain)
++            group = "groups={0}(testgroup1@{1})".format(gid, self.ad_domain)
++            assert (gid_str in test_group.stdout_text
++                    and group in test_group.stdout_text)
++
++
++class TestPosixAutoPrivateGroup(BaseTestTrust):
++    """
++    Tests for auto-private-groups option with posix AD trust
++    Related : https://pagure.io/freeipa/issue/8807
++    """
++    topology = 'line'
++    num_ad_domains = 1
++    num_clients = 1
++    num_ad_subdomains = 0
++    num_ad_treedomains = 0
++    uid_override = "99999999"
++    gid_override = "78878787"
++
++    def test_add_posix_trust(self):
++        tasks.configure_dns_for_trust(self.master, self.ad)
++        tasks.establish_trust_with_ad(
++            self.master, self.ad_domain,
++            extra_args=['--range-type', 'ipa-ad-trust-posix'])
++
++    @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
++    def test_gidnumber_not_corresponding_existing_group(self, type):
++        """
++        Test checks that sssd can resolve AD users which
++        contain posix attributes (uidNumber and gidNumber)
++        but there is no group with the corresponding gidNumber.
++        """
++        posixuser = "testuser2@%s" % self.ad_domain
++        self.mod_idrange_auto_private_group(type)
++        if type != "true":
++            result = self.clients[0].run_command(['id', posixuser],
++                                                 raiseonerr=False)
++            tasks.assert_error(result, "no such user")
++        else:
++            (uid, gid) = self.get_user_id(self.clients[0], posixuser)
++            assert uid == gid
++            assert uid == '10060'
++
++    @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
++    def test_only_uid_number_auto_private_group_default(self, type):
++        """
++        Test checks that posix user with only uidNumber defined
++        and gidNumber not set, auto-private-group
++        is set to false/true/hybrid
++        """
++        posixuser = "testuser1@%s" % self.ad_domain
++        self.mod_idrange_auto_private_group(type)
++        if type == "true":
++            (uid, gid) = self.get_user_id(self.clients[0], posixuser)
++            assert uid == gid
++        else:
++            for host in [self.master, self.clients[0]]:
++                result = host.run_command(['id', posixuser], raiseonerr=False)
++                tasks.assert_error(result, "no such user")
++
++    @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
++    def test_auto_private_group_primary_group(self, type):
++        """
++        Test checks that AD users which contain posix attributes
++        (uidNumber and gidNumber) and there is primary group
++        with gid number defined.
++        """
++        posixuser = "testuser@%s" % self.ad_domain
++        self.mod_idrange_auto_private_group(type)
++        (uid, gid) = self.get_user_id(self.clients[0], posixuser)
++        test_grp = self.clients[0].run_command(["id", posixuser])
++        assert uid == '10042'
++        if type == "true":
++            assert uid == gid
++            groups = "groups=10042(testuser@{0}),10047(testgroup@{1})".format(
++                self.ad_domain, self.ad_domain)
++            assert groups in test_grp.stdout_text
++        else:
++            assert gid == '10047'
++            groups = "10047(testgroup@{0})".format(self.ad_domain)
++            assert groups in test_grp.stdout_text
++
++    @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
++    def test_idoverride_with_auto_private_group(self, type):
++        """
++        Override ad trusted user in default trust view
++        and set auto-private-groups=[hybrid,true,false]
++        and ensure that overridden values takes effect.
++        """
++        posixuser = "testuser@%s" % self.ad_domain
++        with self.set_idoverrideuser(posixuser,
++                                     self.uid_override,
++                                     self.gid_override):
++            self.mod_idrange_auto_private_group(type)
++            (uid, gid) = self.get_user_id(self.clients[0], posixuser)
++            assert(uid == self.uid_override
++                   and gid == self.gid_override)
++            result = self.clients[0].run_command(['id', posixuser])
++            assert "10047(testgroup@{0})".format(
++                self.ad_domain) in result.stdout_text
+-- 
+2.34.1
+
diff --git a/SOURCES/0025-mark-xfail-for-test_idoverride_with_auto_private_gro.patch b/SOURCES/0025-mark-xfail-for-test_idoverride_with_auto_private_gro.patch
new file mode 100644
index 0000000..2b84d99
--- /dev/null
+++ b/SOURCES/0025-mark-xfail-for-test_idoverride_with_auto_private_gro.patch
@@ -0,0 +1,43 @@
+From 84381001d2e114b1f29fe89e16155c040b56b80f Mon Sep 17 00:00:00 2001
+From: Anuja More <amore@redhat.com>
+Date: Thu, 10 Feb 2022 17:07:45 +0530
+Subject: [PATCH] mark xfail for
+ test_idoverride_with_auto_private_group[hybrid]
+
+Related : https://github.com/SSSD/sssd/issues/5989
+
+Signed-off-by: Anuja More <amore@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+Reviewed-By: Anuja More <amore@redhat.com>
+---
+ ipatests/test_integration/test_trust.py | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
+index ff2dd9cc819e1c5620ce449384957a633ae6d1f0..54bd154628cb8fb063d9839d7928acd37647e2a4 100644
+--- a/ipatests/test_integration/test_trust.py
++++ b/ipatests/test_integration/test_trust.py
+@@ -15,6 +15,7 @@ from ipaplatform.paths import paths
+ from ipatests.test_integration.base import IntegrationTest
+ from ipatests.pytest_ipa.integration import tasks
+ from ipatests.pytest_ipa.integration import fips
++from ipatests.util import xfail_context
+ from ipapython.dn import DN
+ from collections import namedtuple
+ from contextlib import contextmanager
+@@ -1110,7 +1111,11 @@ class TestNonPosixAutoPrivateGroup(BaseTestTrust):
+             assert (uid == self.uid_override and gid == self.gid_override)
+             test_group = self.clients[0].run_command(
+                 ["id", nonposixuser]).stdout_text
+-            assert "domain users@{0}".format(self.ad_domain) in test_group
++            version = tasks.get_sssd_version(self.clients[0])
++            with xfail_context(version <= tasks.parse_version('2.6.3')
++                               and type == "hybrid",
++                               'https://github.com/SSSD/sssd/issues/5989'):
++                assert "domain users@{0}".format(self.ad_domain) in test_group
+ 
+     @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+     def test_nonposixuser_nondefault_primary_group(self, type):
+-- 
+2.34.1
+
diff --git a/SOURCES/0026-Mark-xfail-test_gidnumber_not_corresponding_existing.patch b/SOURCES/0026-Mark-xfail-test_gidnumber_not_corresponding_existing.patch
new file mode 100644
index 0000000..a45d917
--- /dev/null
+++ b/SOURCES/0026-Mark-xfail-test_gidnumber_not_corresponding_existing.patch
@@ -0,0 +1,38 @@
+From 7ad500e5d3f7d9af81e8a3137158672c6fafb0b4 Mon Sep 17 00:00:00 2001
+From: Anuja More <amore@redhat.com>
+Date: Thu, 10 Feb 2022 17:29:45 +0530
+Subject: [PATCH] Mark xfail
+ test_gidnumber_not_corresponding_existing_group[true,hybrid]
+
+Related : https://github.com/SSSD/sssd/issues/5988
+
+Signed-off-by: Anuja More <amore@redhat.com>
+Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
+Reviewed-By: Anuja More <amore@redhat.com>
+---
+ ipatests/test_integration/test_trust.py | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
+index 54bd154628cb8fb063d9839d7928acd37647e2a4..c128378151ec4c0fb295823d75f2a04df2f7ffa0 100644
+--- a/ipatests/test_integration/test_trust.py
++++ b/ipatests/test_integration/test_trust.py
+@@ -1169,9 +1169,12 @@ class TestPosixAutoPrivateGroup(BaseTestTrust):
+                                                  raiseonerr=False)
+             tasks.assert_error(result, "no such user")
+         else:
+-            (uid, gid) = self.get_user_id(self.clients[0], posixuser)
+-            assert uid == gid
+-            assert uid == '10060'
++            sssd_version = tasks.get_sssd_version(self.clients[0])
++            with xfail_context(sssd_version <= tasks.parse_version('2.6.3'),
++                               'https://github.com/SSSD/sssd/issues/5988'):
++                (uid, gid) = self.get_user_id(self.clients[0], posixuser)
++                assert uid == gid
++                assert uid == '10060'
+ 
+     @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+     def test_only_uid_number_auto_private_group_default(self, type):
+-- 
+2.34.1
+
diff --git a/SOURCES/0027-KRB-instance-make-provision-to-work-with-crypto-poli.patch b/SOURCES/0027-KRB-instance-make-provision-to-work-with-crypto-poli.patch
new file mode 100644
index 0000000..fb75eeb
--- /dev/null
+++ b/SOURCES/0027-KRB-instance-make-provision-to-work-with-crypto-poli.patch
@@ -0,0 +1,108 @@
+From a51900819bd5332bc05ec9d513f062844b3a7763 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Fri, 25 Feb 2022 08:58:24 +0200
+Subject: [PATCH] KRB instance: make provision to work with crypto policy
+ without SHA-1 HMAC types
+
+RHEL 9 system-wide crypto policies aim at eventual removal of SHA-1 use.
+
+Due to bootstrapping process, force explicitly supported encryption
+types in kdc.conf or we may end up with AES128-SHA1 and AES256-SHA2 only
+in FIPS mode at bootstrap time which then fails to initialize kadmin
+principals requiring use of AES256-SHA2 and AES128-SHA2.
+
+Camellia ciphers must be filtered out in FIPS mode, we do that already
+in the kerberos.ldif.
+
+At this point we are not changing the master key encryption type to
+AES256-SHA2 because upgrading existing deployments is complicated and
+at the time when a replica configuration is deployed, we don't know what
+is the encryption type of the master key of the original server as well.
+
+Fixes: https://pagure.io/freeipa/issue/9119
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Julien Rische <jrische@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ install/share/kdc.conf.template  |  3 ++-
+ install/share/kerberos.ldif      |  2 ++
+ ipaserver/install/krbinstance.py | 21 ++++++++++++++++++++-
+ 3 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/install/share/kdc.conf.template b/install/share/kdc.conf.template
+index 232fedc445f660c30a88d8844d9f1b6042db41a7..685d42f3b7fb263e86b7a6db98be8bcc53e7bbe6 100644
+--- a/install/share/kdc.conf.template
++++ b/install/share/kdc.conf.template
+@@ -6,7 +6,8 @@
+ 
+ [realms]
+  $REALM = {
+-  master_key_type = aes256-cts
++  master_key_type = $MASTER_KEY_TYPE
++  supported_enctypes = $SUPPORTED_ENCTYPES
+   max_life = 7d
+   max_renewable_life = 14d
+   acl_file = $KRB5KDC_KADM5_ACL
+diff --git a/install/share/kerberos.ldif b/install/share/kerberos.ldif
+index 3b75b445641fd86e2029ceb51e479c6ccb17856c..51e5cf9bca4b0b2cf2e1fe3ec85777deb61b76b0 100644
+--- a/install/share/kerberos.ldif
++++ b/install/share/kerberos.ldif
+@@ -28,6 +28,8 @@ ${FIPS}krbSupportedEncSaltTypes: camellia256-cts-cmac:normal
+ ${FIPS}krbSupportedEncSaltTypes: camellia256-cts-cmac:special
+ krbMaxTicketLife: 86400
+ krbMaxRenewableAge: 604800
++krbDefaultEncSaltTypes: aes256-sha2:special
++krbDefaultEncSaltTypes: aes128-sha2:special
+ krbDefaultEncSaltTypes: aes256-cts:special
+ krbDefaultEncSaltTypes: aes128-cts:special
+ 
+diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
+index 216c1032d8abd9fc119d98d8f9976ce17d246ea4..852edcd9978f4a47d355e206fbb4a513ea699865 100644
+--- a/ipaserver/install/krbinstance.py
++++ b/ipaserver/install/krbinstance.py
+@@ -51,6 +51,14 @@ logger = logging.getLogger(__name__)
+ 
+ PKINIT_ENABLED = 'pkinitEnabled'
+ 
++MASTER_KEY_TYPE = 'aes256-sha1'
++SUPPORTED_ENCTYPES = ('aes256-sha2:special', 'aes128-sha2:special',
++                      'aes256-sha2:normal', 'aes128-sha2:normal',
++                      'aes256-cts:special', 'aes128-cts:special',
++                      'aes256-cts:normal', 'aes128-cts:normal',
++                      'camellia256-cts:special', 'camellia128-cts:special',
++                      'camellia256-cts:normal', 'camellia128-cts:normal')
++
+ 
+ def get_pkinit_request_ca():
+     """
+@@ -252,6 +260,7 @@ class KrbInstance(service.Service):
+         else:
+             includes = ''
+ 
++        fips_enabled = tasks.is_fips_enabled()
+         self.sub_dict = dict(FQDN=self.fqdn,
+                              IP=self.ip,
+                              PASSWORD=self.kdc_password,
+@@ -269,7 +278,17 @@ class KrbInstance(service.Service):
+                              KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
+                              CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM,
+                              INCLUDES=includes,
+-                             FIPS='#' if tasks.is_fips_enabled() else '')
++                             FIPS='#' if fips_enabled else '')
++
++        if fips_enabled:
++            supported_enctypes = list(
++                filter(lambda e: not e.startswith('camelia'),
++                       SUPPORTED_ENCTYPES))
++        else:
++            supported_enctypes = SUPPORTED_ENCTYPES
++        self.sub_dict['SUPPORTED_ENCTYPES'] = ' '.join(supported_enctypes)
++
++        self.sub_dict['MASTER_KEY_TYPE'] = MASTER_KEY_TYPE
+ 
+         # IPA server/KDC is not a subdomain of default domain
+         # Proper domain-realm mapping needs to be specified
+-- 
+2.34.1
+
diff --git a/SOURCES/0028-tests-ensure-AD-SUPPORT-subpolicy-is-active.patch b/SOURCES/0028-tests-ensure-AD-SUPPORT-subpolicy-is-active.patch
new file mode 100644
index 0000000..562bba7
--- /dev/null
+++ b/SOURCES/0028-tests-ensure-AD-SUPPORT-subpolicy-is-active.patch
@@ -0,0 +1,58 @@
+From b016683552a58f9cc2a05cf628cc467234eaf599 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Mon, 28 Feb 2022 11:10:49 +0200
+Subject: [PATCH] tests: ensure AD-SUPPORT subpolicy is active
+
+Use AD-SUPPORT subpolicy when testing trust to Active Directory in FIPS
+mode. This is required in FIPS mode due to AD not supporting Kerberos
+AES-bases encryption types using FIPS-compliant PBKDF2 and KDF, as
+defined in RFC 8009.
+
+Fixes: https://pagure.io/freeipa/issue/9119
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Julien Rische <jrische@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ ipatests/pytest_ipa/integration/fips.py  | 6 ++++++
+ ipatests/pytest_ipa/integration/tasks.py | 3 +++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/ipatests/pytest_ipa/integration/fips.py b/ipatests/pytest_ipa/integration/fips.py
+index 694ec8a9927da917fe99482094f68540a1032c14..b33aa91b14552d6f47191c913db4f974a5a5948c 100644
+--- a/ipatests/pytest_ipa/integration/fips.py
++++ b/ipatests/pytest_ipa/integration/fips.py
+@@ -68,3 +68,9 @@ def disable_userspace_fips(host):
+     # sanity check
+     assert not is_fips_enabled(host)
+     host.run_command(["openssl", "md5", "/dev/null"])
++
++
++def enable_crypto_subpolicy(host, subpolicy):
++    result = host.run_command(["update-crypto-policies", "--show"])
++    policy = result.stdin_text.strip() + ":" + subpolicy
++    host.run_command(["update-crypto-policies", "--set", policy])
+diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
+index 7e1b7c24dab00986ff6e75430bf55e55dd1a6b8e..13d84e23fa7dc8a5e562e8498c9142e2bcad696a 100755
+--- a/ipatests/pytest_ipa/integration/tasks.py
++++ b/ipatests/pytest_ipa/integration/tasks.py
+@@ -66,6 +66,7 @@ from .env_config import env_to_script
+ from .host import Host
+ from .firewall import Firewall
+ from .resolver import ResolvedResolver
++from .fips import is_fips_enabled, enable_crypto_subpolicy
+ 
+ logger = logging.getLogger(__name__)
+ 
+@@ -362,6 +363,8 @@ def install_master(host, setup_dns=True, setup_kra=False, setup_adtrust=False,
+     if setup_adtrust:
+         args.append('--setup-adtrust')
+         fw_services.append("freeipa-trust")
++        if is_fips_enabled(host):
++            enable_crypto_subpolicy(host, "AD-SUPPORT")
+     if external_ca:
+         args.append('--external-ca')
+ 
+-- 
+2.34.1
+
diff --git a/SOURCES/0029-ipatests-extend-AES-keyset-to-SHA2-based-ones.patch b/SOURCES/0029-ipatests-extend-AES-keyset-to-SHA2-based-ones.patch
new file mode 100644
index 0000000..b20a590
--- /dev/null
+++ b/SOURCES/0029-ipatests-extend-AES-keyset-to-SHA2-based-ones.patch
@@ -0,0 +1,46 @@
+From 49d9147e38c5b50c52a1ebc7283753c779c2f81f Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Thu, 3 Mar 2022 14:38:57 +0200
+Subject: [PATCH] ipatests: extend AES keyset to SHA2-based ones
+
+Fixes: https://pagure.io/freeipa/issue/9119
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Julien Rische <jrische@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ ipaserver/install/plugins/adtrust.py     | 3 ++-
+ ipatests/pytest_ipa/integration/tasks.py | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py
+index 5b87ac47c6919de287b07c9ceef7ae22e1e79398..67e372bdb40a0b1f6815f107fc567f0ae056dad8 100644
+--- a/ipaserver/install/plugins/adtrust.py
++++ b/ipaserver/install/plugins/adtrust.py
+@@ -754,7 +754,8 @@ class update_host_cifs_keytabs(Updater):
+     """
+ 
+     host_princ_template = "host/{master}@{realm}"
+-    valid_etypes = ['aes256-cts-hmac-sha1-96', 'aes128-cts-hmac-sha1-96']
++    valid_etypes = ['aes256-cts-hmac-sha384-192', 'aes128-cts-hmac-sha256-128',
++                    'aes256-cts-hmac-sha1-96', 'aes128-cts-hmac-sha1-96']
+ 
+     def extract_key_refs(self, keytab):
+         host_princ = self.host_princ_template.format(
+diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
+index 13d84e23fa7dc8a5e562e8498c9142e2bcad696a..d06f8eb2cf6c36956ec200a1abb7c488d1dad9aa 100755
+--- a/ipatests/pytest_ipa/integration/tasks.py
++++ b/ipatests/pytest_ipa/integration/tasks.py
+@@ -2261,7 +2261,8 @@ class KerberosKeyCopier:
+        copier.copy_keys('/etc/krb5.keytab', tmpname, replacement=replacement)
+     """
+     host_princ_template = "host/{master}@{realm}"
+-    valid_etypes = ['aes256-cts-hmac-sha1-96', 'aes128-cts-hmac-sha1-96']
++    valid_etypes = ['aes256-cts-hmac-sha384-192', 'aes128-cts-hmac-sha256-128',
++                    'aes256-cts-hmac-sha1-96', 'aes128-cts-hmac-sha1-96']
+ 
+     def __init__(self, host):
+         self.host = host
+-- 
+2.34.1
+
diff --git a/SOURCES/0030-freeipa.spec-bump-crypto-policies-dependency-for-Cen.patch b/SOURCES/0030-freeipa.spec-bump-crypto-policies-dependency-for-Cen.patch
new file mode 100644
index 0000000..4c61492
--- /dev/null
+++ b/SOURCES/0030-freeipa.spec-bump-crypto-policies-dependency-for-Cen.patch
@@ -0,0 +1,35 @@
+From ee39de46a1c1ea96bbe524f159ae435319b2d072 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Thu, 3 Mar 2022 14:43:11 +0200
+Subject: [PATCH] freeipa.spec: bump crypto-policies dependency for CentOS 9
+ Stream
+
+Fixes: https://pagure.io/freeipa/issue/9119
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Julien Rische <jrische@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ freeipa.spec.in | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index 0b24febc0baff6f60fd2b4cb254971bd3e3aa3b8..c1d81605068c6fc3e6c765ad01c4967fa9f03c95 100755
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -695,6 +695,12 @@ Provides: %{name}-admintools = %{version}-%{release}
+ Conflicts: crypto-policies < 20200629-1
+ %endif
+ 
++%if 0%{?rhel} == 9
++# Conflict with crypto-policies < 20220223-1 to get upgraded AD-SUPPORT and
++# AD-SUPPORT-LEGACY policy modules
++Conflicts: crypto-policies < 20220223-1
++%endif
++
+ %description client
+ IPA is an integrated solution to provide centrally managed Identity (users,
+ hosts, services), Authentication (SSO, 2FA), and Authorization
+-- 
+2.34.1
+
diff --git a/SOURCES/0031-Kerberos-instance-default-to-AES256-SHA2-for-master-.patch b/SOURCES/0031-Kerberos-instance-default-to-AES256-SHA2-for-master-.patch
new file mode 100644
index 0000000..4cb65b1
--- /dev/null
+++ b/SOURCES/0031-Kerberos-instance-default-to-AES256-SHA2-for-master-.patch
@@ -0,0 +1,56 @@
+From 3e54c4362490b4da1b6cb3e141bb6e08fecc58c0 Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Mon, 14 Mar 2022 13:23:04 +0200
+Subject: [PATCH] Kerberos instance: default to AES256-SHA2 for master key
+ encryption
+
+KDC configuration in /var/kerberos/krb5kdc/kdc.conf is generated from
+the template in install/share/kdc.conf.template. Master key encryption
+type specified there is used to bootstrap the master key in LDAP
+database. Once it is done, actual deployment does not rely on the
+master_key_type value anymore. The actual master key(s) get loaded from
+LDAP database where they stored in a BER-encoded format, preserving all
+parameters, including encryption type.
+
+This means we can safely migrate to AES256-SHA2 as the default master
+key encryption type for new installations. Replicas will get their
+master key encryption type details from the server they were provisioned
+from.
+
+MIT Kerberos supports AES256-SHA2 since 1.15 (2015), meaning RHEL 7.4 is
+the earliest supported version as it provides krb5 1.15.1. Current
+supported RHEL 7 version is RHEL 7.9. Since RHEL 6 already cannot be
+used as a replica to IPA 4.5+ due to a domain level 1 upgrade, this
+change does not affect old releases.
+
+Migration from the previously deployed master key encryption type is
+described by MIT Kerberos upstream in
+http://web.mit.edu/kerberos/krb5-latest/doc/admin/advanced/retiring-des.html#the-database-master-key
+
+One would need to use '-x ipa-setup-override-restrictions' to allow
+the `kdb5_util` utility to modify the data over IPA KDB driver.
+
+Fixes: https://pagure.io/freeipa/issue/9119
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ ipaserver/install/krbinstance.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
+index 01b3309d50c0e8025e3381eac577225b1ef0be9d..a5eaa7b17133498f08e84d01c90764236e8ebe84 100644
+--- a/ipaserver/install/krbinstance.py
++++ b/ipaserver/install/krbinstance.py
+@@ -51,7 +51,7 @@ logger = logging.getLogger(__name__)
+ 
+ PKINIT_ENABLED = 'pkinitEnabled'
+ 
+-MASTER_KEY_TYPE = 'aes256-sha1'
++MASTER_KEY_TYPE = 'aes256-sha2'
+ SUPPORTED_ENCTYPES = ('aes256-sha2:special', 'aes128-sha2:special',
+                       'aes256-sha2:normal', 'aes128-sha2:normal',
+                       'aes256-cts:special', 'aes128-cts:special',
+-- 
+2.34.1
+
diff --git a/SOURCES/0032-test_otp-do-not-use-paramiko-unless-it-is-really-nee.patch b/SOURCES/0032-test_otp-do-not-use-paramiko-unless-it-is-really-nee.patch
new file mode 100644
index 0000000..368346f
--- /dev/null
+++ b/SOURCES/0032-test_otp-do-not-use-paramiko-unless-it-is-really-nee.patch
@@ -0,0 +1,44 @@
+From 3baae8d1bd0a0c4c707314524289e86e6ecbc0df Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Mon, 14 Mar 2022 21:09:36 +0200
+Subject: [PATCH] test_otp: do not use paramiko unless it is really needed
+
+paramiko cannot be used in FIPS mode. We have few tests that import
+generic methods from test_otp (add_token/del_token) and those tests fail
+in FIPS mode due to unconditional 'import paramiko'.
+
+Instead, move 'import paramiko' to the ssh_2f() helper which is not used
+in FIPS mode (the whole SSH 2FA test is skipped then).
+
+Related: https://pagure.io/freeipa/issue/9119
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ ipatests/test_integration/test_otp.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
+index bec76d205bf37699483b65ebbc5613cbbb466bb4..04bef4626077e727654898b07a76acab4f1d5971 100644
+--- a/ipatests/test_integration/test_otp.py
++++ b/ipatests/test_integration/test_otp.py
+@@ -5,7 +5,6 @@
+ """
+ import base64
+ import logging
+-import paramiko
+ import pytest
+ import re
+ import time
+@@ -102,6 +101,8 @@ def ssh_2f(hostname, username, answers_dict, port=22):
+             logger.info(
+                 "Answer to ssh prompt is: '%s'", answers_dict[prmpt_str])
+         return resp
++
++    import paramiko
+     trans = paramiko.Transport((hostname, port))
+     trans.connect()
+     trans.auth_interactive(username, answer_handler)
+-- 
+2.34.1
+
diff --git a/SOURCES/0033-test_krbtpolicy-skip-SPAKE-related-tests-in-FIPS-mod.patch b/SOURCES/0033-test_krbtpolicy-skip-SPAKE-related-tests-in-FIPS-mod.patch
new file mode 100644
index 0000000..de21062
--- /dev/null
+++ b/SOURCES/0033-test_krbtpolicy-skip-SPAKE-related-tests-in-FIPS-mod.patch
@@ -0,0 +1,44 @@
+From 2e70535f74e7d9dd76e728eca1119ce522fd138a Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Tue, 15 Mar 2022 11:39:46 +0200
+Subject: [PATCH] test_krbtpolicy: skip SPAKE-related tests in FIPS mode
+
+SPAKE is based on the crypto primitives which are not FIPS compliant
+yet. This means that in FIPS mode use of 'hardened' authentication
+indicator is not possible. Skip corresponding tests in FIPS mode.
+
+Related: https://pagure.io/freeipa/issue/9119
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
+---
+ ipatests/test_integration/test_krbtpolicy.py | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/ipatests/test_integration/test_krbtpolicy.py b/ipatests/test_integration/test_krbtpolicy.py
+index 9489fbc97b7836aecf491b57627f254d4849eb56..eae16247bdfb195c1d91209cf2d11eac4c25018f 100644
+--- a/ipatests/test_integration/test_krbtpolicy.py
++++ b/ipatests/test_integration/test_krbtpolicy.py
+@@ -105,6 +105,9 @@ class TestPWPolicy(IntegrationTest):
+ 
+     def test_krbtpolicy_password_and_hardended(self):
+         """Test a pwd and hardened kerberos ticket policy with 10min tickets"""
++        if self.master.is_fips_mode:
++            pytest.skip("SPAKE pre-auth is not compatible with FIPS mode")
++
+         master = self.master
+         master.run_command(['ipa', 'user-mod', USER1,
+                             '--user-auth-type', 'password',
+@@ -133,6 +136,9 @@ class TestPWPolicy(IntegrationTest):
+ 
+     def test_krbtpolicy_hardended(self):
+         """Test a hardened kerberos ticket policy with 30min tickets"""
++        if self.master.is_fips_mode:
++            pytest.skip("SPAKE pre-auth is not compatible with FIPS mode")
++
+         master = self.master
+         master.run_command(['ipa', 'user-mod', USER1,
+                             '--user-auth-type', 'hardened'])
+-- 
+2.34.1
+
diff --git a/SOURCES/0034-Support-AES-for-KRA-archival-wrapping.patch b/SOURCES/0034-Support-AES-for-KRA-archival-wrapping.patch
new file mode 100644
index 0000000..8d4ec8a
--- /dev/null
+++ b/SOURCES/0034-Support-AES-for-KRA-archival-wrapping.patch
@@ -0,0 +1,555 @@
+From 895e99b6843c2fa2274acab824607c33c1a560a4 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <cheimes@redhat.com>
+Date: Mon, 7 Oct 2019 14:13:03 +0200
+Subject: [PATCH] Support AES for KRA archival wrapping
+
+The vault plugin has used TripleDES (des-ede3-cbc) as default wrapping
+algorithm since the plugin was introduced. Allow use of AES-128-CBC as
+alternative wrapping algorithm for transport of secrets.
+
+Fixes: https://pagure.io/freeipa/issue/6524
+
+Signed-off-by: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ API.txt                    |   7 +-
+ VERSION.m4                 |   5 +-
+ ipaclient/plugins/vault.py | 155 +++++++++++++++++++++++++------------
+ ipalib/capabilities.py     |   4 +
+ ipalib/constants.py        |  12 +++
+ ipaserver/plugins/vault.py |  61 ++++++++++++---
+ 6 files changed, 180 insertions(+), 64 deletions(-)
+
+diff --git a/API.txt b/API.txt
+index 576fa7c51e31886b257ccf176aaf232c0f2ea5ee..f95f2c8457e39f2268386a8a2336952d3285e008 100644
+--- a/API.txt
++++ b/API.txt
+@@ -6548,7 +6548,7 @@ output: Output('completed', type=[<type 'int'>])
+ output: Output('failed', type=[<type 'dict'>])
+ output: Entry('result')
+ command: vault_archive_internal/1
+-args: 1,9,3
++args: 1,10,3
+ arg: Str('cn', cli_name='name')
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+ option: Bytes('nonce')
+@@ -6559,6 +6559,7 @@ option: Flag('shared?', autofill=True, default=False)
+ option: Str('username?', cli_name='user')
+ option: Bytes('vault_data')
+ option: Str('version?')
++option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'des-ede3-cbc', u'aes-128-cbc'])
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+ output: PrimaryKey('value')
+@@ -6649,7 +6650,7 @@ output: Output('completed', type=[<type 'int'>])
+ output: Output('failed', type=[<type 'dict'>])
+ output: Entry('result')
+ command: vault_retrieve_internal/1
+-args: 1,7,3
++args: 1,8,3
+ arg: Str('cn', cli_name='name')
+ option: Flag('all', autofill=True, cli_name='all', default=False)
+ option: Flag('raw', autofill=True, cli_name='raw', default=False)
+@@ -6658,6 +6659,7 @@ option: Bytes('session_key')
+ option: Flag('shared?', autofill=True, default=False)
+ option: Str('username?', cli_name='user')
+ option: Str('version?')
++option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'des-ede3-cbc', u'aes-128-cbc'])
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+ output: PrimaryKey('value')
+@@ -7327,6 +7329,7 @@ default: vaultcontainer_del/1
+ default: vaultcontainer_remove_owner/1
+ default: vaultcontainer_show/1
+ default: whoami/1
++capability: vault_aes_keywrap 2.246
+ capability: messages 2.52
+ capability: optional_uid_params 2.54
+ capability: permissions2 2.69
+diff --git a/VERSION.m4 b/VERSION.m4
+index 70aaff4c9b9514a5937eae60074376e1a592464e..997ac35e74fa6f2a96da027ed3ce93cf809b62a7 100644
+--- a/VERSION.m4
++++ b/VERSION.m4
+@@ -86,9 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000)
+ #                                                      #
+ ########################################################
+ define(IPA_API_VERSION_MAJOR, 2)
+-# Last change: add enable_sid to config
+-define(IPA_API_VERSION_MINOR, 245)
+-
++# Last change: Add wrapping algorithm to vault archive/retrieve
++define(IPA_API_VERSION_MINOR, 246)
+ 
+ ########################################################
+ # Following values are auto-generated from values above
+diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
+index d3a1d370efaccc7e5b0088bd3df341d76884d509..115171c7768d44251c17d0bcdac9c37b3a25db99 100644
+--- a/ipaclient/plugins/vault.py
++++ b/ipaclient/plugins/vault.py
+@@ -25,11 +25,12 @@ import io
+ import json
+ import logging
+ import os
++import ssl
+ import tempfile
+ 
+ from cryptography.fernet import Fernet, InvalidToken
+ from cryptography.hazmat.backends import default_backend
+-from cryptography.hazmat.primitives import hashes, serialization
++from cryptography.hazmat.primitives import hashes
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
+ from cryptography.hazmat.primitives.asymmetric import padding
+ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
+@@ -39,7 +40,7 @@ from cryptography.hazmat.primitives.serialization import (
+ 
+ from ipaclient.frontend import MethodOverride
+ from ipalib import x509
+-from ipalib.constants import USER_CACHE_PATH
++from ipalib import constants
+ from ipalib.frontend import Local, Method, Object
+ from ipalib.util import classproperty
+ from ipalib import api, errors
+@@ -546,42 +547,49 @@ class vault_mod(Local):
+         return response
+ 
+ 
+-class _TransportCertCache:
++class _KraConfigCache:
++    """The KRA config cache stores vaultconfig-show result.
++    """
+     def __init__(self):
+         self._dirname = os.path.join(
+-                USER_CACHE_PATH, 'ipa', 'kra-transport-certs'
++            constants.USER_CACHE_PATH, 'ipa', 'kra-config'
+         )
+ 
+     def _get_filename(self, domain):
+-        basename = DNSName(domain).ToASCII() + '.pem'
++        basename = DNSName(domain).ToASCII() + '.json'
+         return os.path.join(self._dirname, basename)
+ 
+-    def load_cert(self, domain):
+-        """Load cert from cache
++    def load(self, domain):
++        """Load config from cache
+ 
+         :param domain: IPA domain
+-        :return: cryptography.x509.Certificate or None
++        :return: dict or None
+         """
+         filename = self._get_filename(domain)
+         try:
+             try:
+-                return x509.load_certificate_from_file(filename)
+-            except EnvironmentError as e:
++                with open(filename) as f:
++                    return json.load(f)
++            except OSError as e:
+                 if e.errno != errno.ENOENT:
+                     raise
+         except Exception:
+             logger.warning("Failed to load %s", filename, exc_info=True)
+         return None
+ 
+-    def store_cert(self, domain, transport_cert):
+-        """Store a new cert or override existing cert
++    def store(self, domain, response):
++        """Store config in cache
+ 
+         :param domain: IPA domain
+-        :param transport_cert: cryptography.x509.Certificate
+-        :return: True if cert was stored successfully
++        :param config: ipa vaultconfig-show response
++        :return: True if config was stored successfully
+         """
++        config = response['result'].copy()
++        # store certificate as PEM-encoded ASCII
++        config['transport_cert'] = ssl.DER_cert_to_PEM_cert(
++            config['transport_cert']
++        )
+         filename = self._get_filename(domain)
+-        pem = transport_cert.public_bytes(serialization.Encoding.PEM)
+         try:
+             try:
+                 os.makedirs(self._dirname)
+@@ -589,9 +597,9 @@ class _TransportCertCache:
+                 if e.errno != errno.EEXIST:
+                     raise
+             with tempfile.NamedTemporaryFile(dir=self._dirname, delete=False,
+-                                             mode='wb') as f:
++                                             mode='w') as f:
+                 try:
+-                    f.write(pem)
++                    json.dump(config, f)
+                     ipautil.flush_sync(f)
+                     f.close()
+                     os.rename(f.name, filename)
+@@ -604,8 +612,8 @@ class _TransportCertCache:
+         else:
+             return True
+ 
+-    def remove_cert(self, domain):
+-        """Remove a cert from cache, ignores errors
++    def remove(self, domain):
++        """Remove a config from cache, ignores errors
+ 
+         :param domain: IPA domain
+         :return: True if cert was found and removed
+@@ -621,7 +629,7 @@ class _TransportCertCache:
+             return True
+ 
+ 
+-_transport_cert_cache = _TransportCertCache()
++_kra_config_cache = _KraConfigCache()
+ 
+ 
+ @register(override=True, no_fail=True)
+@@ -636,13 +644,8 @@ class vaultconfig_show(MethodOverride):
+ 
+         response = super(vaultconfig_show, self).forward(*args, **options)
+ 
+-        # cache transport certificate
+-        transport_cert = x509.load_der_x509_certificate(
+-                response['result']['transport_cert'])
+-
+-        _transport_cert_cache.store_cert(
+-            self.api.env.domain, transport_cert
+-        )
++        # cache config
++        _kra_config_cache.store(self.api.env.domain, response)
+ 
+         if file:
+             with open(file, 'wb') as f:
+@@ -652,10 +655,54 @@ class vaultconfig_show(MethodOverride):
+ 
+ 
+ class ModVaultData(Local):
+-    def _generate_session_key(self):
+-        key_length = max(algorithms.TripleDES.key_sizes)
+-        algo = algorithms.TripleDES(os.urandom(key_length // 8))
+-        return algo
++    def _generate_session_key(self, name):
++        if name not in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
++            msg = _("{algo} is not a supported vault wrapping algorithm")
++            raise errors.ValidationError(msg.format(algo=repr(name)))
++        if name == constants.VAULT_WRAPPING_AES128_CBC:
++            return algorithms.AES(os.urandom(128 // 8))
++        elif name == constants.VAULT_WRAPPING_3DES:
++            return algorithms.TripleDES(os.urandom(196 // 8))
++        else:
++            # unreachable
++            raise ValueError(name)
++
++    def _get_vaultconfig(self, force_refresh=False):
++        config = None
++        if not force_refresh:
++            config = _kra_config_cache.load(self.api.env.domain)
++        if config is None:
++            # vaultconfig_show also caches data
++            response = self.api.Command.vaultconfig_show()
++            config = response['result']
++            transport_cert = x509.load_der_x509_certificate(
++                config['transport_cert']
++            )
++        else:
++            # cached JSON uses PEM-encoded ASCII string
++            transport_cert = x509.load_pem_x509_certificate(
++                config['transport_cert'].encode('ascii')
++            )
++
++        default_algo = config.get('wrapping_default_algorithm')
++        if default_algo is None:
++            # old server
++            wrapping_algo = constants.VAULT_WRAPPING_AES128_CBC
++        elif default_algo in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
++            # try to use server default
++            wrapping_algo = default_algo
++        else:
++            # prefer server's sorting order
++            for algo in config['wrapping_supported_algorithms']:
++                if algo in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
++                    wrapping_algo = algo
++                    break
++            else:
++                raise errors.ValidationError(
++                    "No overlapping wrapping algorithm between server and "
++                    "client."
++                )
++        return transport_cert, wrapping_algo
+ 
+     def _do_internal(self, algo, transport_cert, raise_unexpected,
+                      *args, **options):
+@@ -675,29 +722,23 @@ class ModVaultData(Local):
+         except (errors.InternalError,
+                 errors.ExecutionError,
+                 errors.GenericError):
+-            _transport_cert_cache.remove_cert(self.api.env.domain)
++            _kra_config_cache.remove(self.api.env.domain)
+             if raise_unexpected:
+                 raise
+         return None
+ 
+-    def internal(self, algo, *args, **options):
++    def internal(self, algo, transport_cert, *args, **options):
+         """
+         Calls the internal counterpart of the command.
+         """
+-        domain = self.api.env.domain
+-
+         # try call with cached transport certificate
+-        transport_cert = _transport_cert_cache.load_cert(domain)
+-        if transport_cert is not None:
+-            result = self._do_internal(algo, transport_cert, False,
++        result = self._do_internal(algo, transport_cert, False,
+                                        *args, **options)
+-            if result is not None:
+-                return result
++        if result is not None:
++            return result
+ 
+         # retrieve transport certificate (cached by vaultconfig_show)
+-        response = self.api.Command.vaultconfig_show()
+-        transport_cert = x509.load_der_x509_certificate(
+-            response['result']['transport_cert'])
++        transport_cert = self._get_vaultconfig(force_refresh=True)[0]
+         # call with the retrieved transport certificate
+         return self._do_internal(algo, transport_cert, True,
+                                  *args, **options)
+@@ -777,7 +818,7 @@ class vault_archive(ModVaultData):
+     def _wrap_data(self, algo, json_vault_data):
+         """Encrypt data with wrapped session key and transport cert
+ 
+-        :param bytes algo: wrapping algorithm instance
++        :param algo: wrapping algorithm instance
+         :param bytes json_vault_data: dumped vault data
+         :return:
+         """
+@@ -929,15 +970,24 @@ class vault_archive(ModVaultData):
+ 
+         json_vault_data = json.dumps(vault_data).encode('utf-8')
+ 
++        # get config
++        transport_cert, wrapping_algo = self._get_vaultconfig()
++        # let options override wrapping algo
++        # For backwards compatibility do not send old legacy wrapping algo
++        # to server. Only send the option when non-3DES is used.
++        wrapping_algo = options.pop('wrapping_algo', wrapping_algo)
++        if wrapping_algo != constants.VAULT_WRAPPING_3DES:
++            options['wrapping_algo'] = wrapping_algo
++
+         # generate session key
+-        algo = self._generate_session_key()
++        algo = self._generate_session_key(wrapping_algo)
+         # wrap vault data
+         nonce, wrapped_vault_data = self._wrap_data(algo, json_vault_data)
+         options.update(
+             nonce=nonce,
+             vault_data=wrapped_vault_data
+         )
+-        return self.internal(algo, *args, **options)
++        return self.internal(algo, transport_cert, *args, **options)
+ 
+ 
+ @register(no_fail=True)
+@@ -1061,10 +1111,19 @@ class vault_retrieve(ModVaultData):
+         vault = self.api.Command.vault_show(*args, **options)['result']
+         vault_type = vault['ipavaulttype'][0]
+ 
++        # get config
++        transport_cert, wrapping_algo = self._get_vaultconfig()
++        # let options override wrapping algo
++        # For backwards compatibility do not send old legacy wrapping algo
++        # to server. Only send the option when non-3DES is used.
++        wrapping_algo = options.pop('wrapping_algo', wrapping_algo)
++        if wrapping_algo != constants.VAULT_WRAPPING_3DES:
++            options['wrapping_algo'] = wrapping_algo
++
+         # generate session key
+-        algo = self._generate_session_key()
++        algo = self._generate_session_key(wrapping_algo)
+         # send retrieval request to server
+-        response = self.internal(algo, *args, **options)
++        response = self.internal(algo, transport_cert, *args, **options)
+         # unwrap data with session key
+         vault_data = self._unwrap_response(
+             algo,
+diff --git a/ipalib/capabilities.py b/ipalib/capabilities.py
+index 55b84aa6bc73d583e7bd5d03d2f4f1cc5c8e7c0b..4d8ae408bf67c280d27ce494baa9db9aaff0cd69 100644
+--- a/ipalib/capabilities.py
++++ b/ipalib/capabilities.py
+@@ -54,6 +54,10 @@ capabilities = dict(
+ 
+     # dns_name_values: dnsnames as objects
+     dns_name_values=u'2.88',
++
++    # vault supports aes key wrapping
++    vault_aes_keywrap='2.246'
++
+ )
+ 
+ 
+diff --git a/ipalib/constants.py b/ipalib/constants.py
+index 9f19b0f9941ba5068f1e6c218092e3b76fdc7599..11171b2e8aeb6f7306299b2bd7db3a3f39d29d4a 100644
+--- a/ipalib/constants.py
++++ b/ipalib/constants.py
+@@ -374,3 +374,15 @@ KRA_TRACKING_REQS = {
+ }
+ 
+ ALLOWED_NETBIOS_CHARS = string.ascii_uppercase + string.digits + '-'
++
++# vault data wrapping algorithms
++VAULT_WRAPPING_3DES = 'des-ede3-cbc'
++VAULT_WRAPPING_AES128_CBC = 'aes-128-cbc'
++VAULT_WRAPPING_SUPPORTED_ALGOS = (
++    # old default was 3DES
++    VAULT_WRAPPING_3DES,
++    # supported since pki-kra >= 10.4
++    VAULT_WRAPPING_AES128_CBC,
++)
++# 3DES for backwards compatibility
++VAULT_WRAPPING_DEFAULT_ALGO = VAULT_WRAPPING_3DES
+diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
+index aebac7dff7bb9d183c6012cc685577d476e18c4e..4d40f66c6a793a831e91c5fe25c8b5277cbd1972 100644
+--- a/ipaserver/plugins/vault.py
++++ b/ipaserver/plugins/vault.py
+@@ -23,6 +23,10 @@ from ipalib.frontend import Command, Object
+ from ipalib import api, errors
+ from ipalib import Bytes, Flag, Str, StrEnum
+ from ipalib import output
++from ipalib.constants import (
++    VAULT_WRAPPING_SUPPORTED_ALGOS, VAULT_WRAPPING_DEFAULT_ALGO,
++    VAULT_WRAPPING_3DES, VAULT_WRAPPING_AES128_CBC,
++)
+ from ipalib.crud import PKQuery, Retrieve
+ from ipalib.parameters import Principal
+ from ipalib.plugable import Registry
+@@ -39,14 +43,8 @@ from ipaserver.masters import is_service_enabled
+ if api.env.in_server:
+     import pki.account
+     import pki.key
+-    # pylint: disable=no-member
+-    try:
+-        # pki >= 10.4.0
+-        from pki.crypto import DES_EDE3_CBC_OID
+-    except ImportError:
+-        DES_EDE3_CBC_OID = pki.key.KeyClient.DES_EDE3_CBC_OID
+-    # pylint: enable=no-member
+-
++    from pki.crypto import DES_EDE3_CBC_OID
++    from pki.crypto import AES_128_CBC_OID
+ 
+ if six.PY3:
+     unicode = str
+@@ -652,6 +652,20 @@ class vault(LDAPObject):
+         ),
+     )
+ 
++    def _translate_algorithm(self, name):
++        if name is None:
++            name = VAULT_WRAPPING_DEFAULT_ALGO
++        if name not in VAULT_WRAPPING_SUPPORTED_ALGOS:
++            msg = _("{algo} is not a supported vault wrapping algorithm")
++            raise errors.ValidationError(msg.format(algo=name))
++        if name == VAULT_WRAPPING_3DES:
++            return DES_EDE3_CBC_OID
++        elif name == VAULT_WRAPPING_AES128_CBC:
++            return AES_128_CBC_OID
++        else:
++            # unreachable
++            raise ValueError(name)
++
+     def get_dn(self, *keys, **options):
+         """
+         Generates vault DN from parameters.
+@@ -992,14 +1006,18 @@ class vaultconfig_show(Retrieve):
+     )
+ 
+     def execute(self, *args, **options):
+-
+         if not self.api.Command.kra_is_enabled()['result']:
+             raise errors.InvocationError(
+                 format=_('KRA service is not enabled'))
+ 
++        config = dict(
++            wrapping_supported_algorithms=VAULT_WRAPPING_SUPPORTED_ALGOS,
++            wrapping_default_algorithm=VAULT_WRAPPING_DEFAULT_ALGO,
++        )
++
+         with self.api.Backend.kra.get_client() as kra_client:
+             transport_cert = kra_client.system_certs.get_transport_cert()
+-            config = {'transport_cert': transport_cert.binary}
++            config['transport_cert'] = transport_cert.binary
+ 
+         self.api.Object.config.show_servroles_attributes(
+             config, "KRA server", **options)
+@@ -1029,6 +1047,13 @@ class vault_archive_internal(PKQuery):
+             'nonce',
+             doc=_('Nonce'),
+         ),
++        StrEnum(
++            'wrapping_algo?',
++            doc=_('Key wrapping algorithm'),
++            values=VAULT_WRAPPING_SUPPORTED_ALGOS,
++            default=VAULT_WRAPPING_DEFAULT_ALGO,
++            autofill=True,
++        ),
+     )
+ 
+     has_output = output.standard_entry
+@@ -1045,6 +1070,9 @@ class vault_archive_internal(PKQuery):
+         nonce = options.pop('nonce')
+         wrapped_session_key = options.pop('session_key')
+ 
++        wrapping_algo = options.pop('wrapping_algo', None)
++        algorithm_oid = self.obj._translate_algorithm(wrapping_algo)
++
+         # retrieve vault info
+         vault = self.api.Command.vault_show(*args, **options)['result']
+ 
+@@ -1071,7 +1099,7 @@ class vault_archive_internal(PKQuery):
+                 pki.key.KeyClient.PASS_PHRASE_TYPE,
+                 wrapped_vault_data,
+                 wrapped_session_key,
+-                algorithm_oid=DES_EDE3_CBC_OID,
++                algorithm_oid=algorithm_oid,
+                 nonce_iv=nonce,
+             )
+ 
+@@ -1098,6 +1126,13 @@ class vault_retrieve_internal(PKQuery):
+             'session_key',
+             doc=_('Session key wrapped with transport certificate'),
+         ),
++        StrEnum(
++            'wrapping_algo?',
++            doc=_('Key wrapping algorithm'),
++            values=VAULT_WRAPPING_SUPPORTED_ALGOS,
++            default=VAULT_WRAPPING_DEFAULT_ALGO,
++            autofill=True,
++        ),
+     )
+ 
+     has_output = output.standard_entry
+@@ -1112,6 +1147,9 @@ class vault_retrieve_internal(PKQuery):
+ 
+         wrapped_session_key = options.pop('session_key')
+ 
++        wrapping_algo = options.pop('wrapping_algo', None)
++        algorithm_oid = self.obj._translate_algorithm(wrapping_algo)
++
+         # retrieve vault info
+         vault = self.api.Command.vault_show(*args, **options)['result']
+ 
+@@ -1132,6 +1170,9 @@ class vault_retrieve_internal(PKQuery):
+ 
+             key_info = response.key_infos[0]
+ 
++            # XXX hack
++            kra_client.keys.encrypt_alg_oid = algorithm_oid
++
+             # retrieve encrypted data from KRA
+             key = kra_client.keys.retrieve_key(
+                 key_info.get_key_id(),
+-- 
+2.34.1
+
diff --git a/SOURCES/0035-Set-AES-as-default-for-KRA-archival-wrapping.patch b/SOURCES/0035-Set-AES-as-default-for-KRA-archival-wrapping.patch
new file mode 100644
index 0000000..f762229
--- /dev/null
+++ b/SOURCES/0035-Set-AES-as-default-for-KRA-archival-wrapping.patch
@@ -0,0 +1,86 @@
+From 984190eea01ac42cd1f97567a67dd9446e5b0bf9 Mon Sep 17 00:00:00 2001
+From: Francisco Trivino <ftrivino@redhat.com>
+Date: Fri, 11 Mar 2022 17:47:38 +0100
+Subject: [PATCH] Set AES as default for KRA archival wrapping
+
+This commit sets AES-128-CBC as default wrapping algorithm as
+TripleDES (des-ede3-cbc) is not supported anymore in C9S.
+
+Fixes: https://pagure.io/freeipa/issue/6524
+
+Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
+Reviewed-By: Christian Heimes <cheimes@redhat.com>
+Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ API.txt             |  6 +++---
+ ipalib/constants.py | 14 +++++++++-----
+ 2 files changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/API.txt b/API.txt
+index f95f2c8457e39f2268386a8a2336952d3285e008..1f27dcc616a6395c56ef91f3453e7620625c7645 100644
+--- a/API.txt
++++ b/API.txt
+@@ -6559,7 +6559,7 @@ option: Flag('shared?', autofill=True, default=False)
+ option: Str('username?', cli_name='user')
+ option: Bytes('vault_data')
+ option: Str('version?')
+-option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'des-ede3-cbc', u'aes-128-cbc'])
++option: StrEnum('wrapping_algo?', autofill=True, default=u'aes-128-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+ output: PrimaryKey('value')
+@@ -6659,7 +6659,7 @@ option: Bytes('session_key')
+ option: Flag('shared?', autofill=True, default=False)
+ option: Str('username?', cli_name='user')
+ option: Str('version?')
+-option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'des-ede3-cbc', u'aes-128-cbc'])
++option: StrEnum('wrapping_algo?', autofill=True, default=u'aes-128-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
+ output: Entry('result')
+ output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
+ output: PrimaryKey('value')
+@@ -7329,10 +7329,10 @@ default: vaultcontainer_del/1
+ default: vaultcontainer_remove_owner/1
+ default: vaultcontainer_show/1
+ default: whoami/1
+-capability: vault_aes_keywrap 2.246
+ capability: messages 2.52
+ capability: optional_uid_params 2.54
+ capability: permissions2 2.69
+ capability: primary_key_types 2.83
+ capability: datetime_values 2.84
+ capability: dns_name_values 2.88
++capability: vault_aes_keywrap 2.246
+diff --git a/ipalib/constants.py b/ipalib/constants.py
+index 11171b2e8aeb6f7306299b2bd7db3a3f39d29d4a..68178004181bebcc8c093dac55e18d5afe0251e5 100644
+--- a/ipalib/constants.py
++++ b/ipalib/constants.py
+@@ -29,6 +29,8 @@ from ipaplatform.constants import constants as _constants
+ from ipapython.dn import DN
+ from ipapython.fqdn import gethostfqdn
+ from ipapython.version import VERSION, API_VERSION
++from cryptography.hazmat.primitives.ciphers import algorithms, modes
++from cryptography.hazmat.backends.openssl.backend import backend
+ 
+ 
+ FQDN = gethostfqdn()
+@@ -379,10 +381,12 @@ ALLOWED_NETBIOS_CHARS = string.ascii_uppercase + string.digits + '-'
+ VAULT_WRAPPING_3DES = 'des-ede3-cbc'
+ VAULT_WRAPPING_AES128_CBC = 'aes-128-cbc'
+ VAULT_WRAPPING_SUPPORTED_ALGOS = (
+-    # old default was 3DES
+-    VAULT_WRAPPING_3DES,
+-    # supported since pki-kra >= 10.4
++    # new default and supported since pki-kra >= 10.4
+     VAULT_WRAPPING_AES128_CBC,
+ )
+-# 3DES for backwards compatibility
+-VAULT_WRAPPING_DEFAULT_ALGO = VAULT_WRAPPING_3DES
++VAULT_WRAPPING_DEFAULT_ALGO = VAULT_WRAPPING_AES128_CBC
++
++# Add 3DES for backwards compatibility if supported
++if backend.cipher_supported(algorithms.TripleDES(b"\x00" * 8),
++                            modes.CBC(b"\x00" * 8)):
++    VAULT_WRAPPING_SUPPORTED_ALGOS += (VAULT_WRAPPING_3DES,)
+-- 
+2.34.1
+
diff --git a/SPECS/freeipa.spec b/SPECS/freeipa.spec
index c145291..12c75a3 100644
--- a/SPECS/freeipa.spec
+++ b/SPECS/freeipa.spec
@@ -66,7 +66,7 @@
 %if 0%{?rhel}
 %global package_name ipa
 %global alt_name freeipa
-%global krb5_version 1.18.2-2
+%global krb5_version 1.19.1-15
 %global krb5_kdb_version 8.0
 # 0.7.16: https://github.com/drkjam/netaddr/issues/71
 %global python_netaddr_version 0.7.19
@@ -198,7 +198,7 @@
 
 Name:           %{package_name}
 Version:        %{IPA_VERSION}
-Release:        5%{?rc_version:.%rc_version}%{?dist}
+Release:        7%{?rc_version:.%rc_version}%{?dist}
 Summary:        The Identity, Policy and Audit system
 
 License:        GPLv3+
@@ -241,6 +241,18 @@ Patch0020:      0020-Test-ipa-ccache-sweep.timer-enabled-by-default-durin.patch
 Patch0021:      0021-ipa_cldap-fix-memory-leak.patch
 Patch0022:      0022-ipatests-remove-additional-check-for-failed-units_rhbz#2053025.patch
 Patch0023:      0023-ipatests-fix-TestOTPToken-rhbz#2053025.patch
+Patch0024:      0024-ipatests-Tests-for-Autoprivate-group.patch
+Patch0025:      0025-mark-xfail-for-test_idoverride_with_auto_private_gro.patch
+Patch0026:      0026-Mark-xfail-test_gidnumber_not_corresponding_existing.patch
+Patch0027:      0027-KRB-instance-make-provision-to-work-with-crypto-poli.patch
+Patch0028:      0028-tests-ensure-AD-SUPPORT-subpolicy-is-active.patch
+Patch0029:      0029-ipatests-extend-AES-keyset-to-SHA2-based-ones.patch
+Patch0030:      0030-freeipa.spec-bump-crypto-policies-dependency-for-Cen.patch
+Patch0031:      0031-Kerberos-instance-default-to-AES256-SHA2-for-master-.patch
+Patch0032:      0032-test_otp-do-not-use-paramiko-unless-it-is-really-nee.patch
+Patch0033:      0033-test_krbtpolicy-skip-SPAKE-related-tests-in-FIPS-mod.patch
+Patch0034:      0034-Support-AES-for-KRA-archival-wrapping.patch
+Patch0035:      0035-Set-AES-as-default-for-KRA-archival-wrapping.patch
 Patch1001:      1001-Change-branding-to-IPA-and-Identity-Management.patch
 %endif
 %endif
@@ -713,6 +725,12 @@ Provides: %{name}-admintools = %{version}-%{release}
 Conflicts: crypto-policies < 20200629-1
 %endif
 
+%if 0%{?rhel} == 9
+# Conflict with crypto-policies < 20220223-1 to get upgraded AD-SUPPORT and
+# AD-SUPPORT-LEGACY policy modules
+Conflicts: crypto-policies < 20220223-1
+%endif 
+
 %description client
 IPA is an integrated solution to provide centrally managed Identity (users,
 hosts, services), Authentication (SSO, 2FA), and Authorization
@@ -1732,6 +1750,24 @@ fi
 %endif
 
 %changelog
+* Mon Mar 21 2022 Florence Blanc-Renaud <frenaud@redhat.com> - 4.9.8-7
+- Resolves: rhbz#2057471 Consequences of FIPS crypto policy tightening in RHEL 9
+  - KRB instance: make provision to work with crypto policy without SHA-1 HMAC types
+  - tests: ensure AD-SUPPORT subpolicy is active
+  - ipatests: extend AES keyset to SHA2-based ones
+  - freeipa.spec: bump crypto-policies dependency for CentOS 9 Stream
+  - Kerberos instance: default to AES256-SHA2 for master key encryption
+  - test_otp: do not use paramiko unless it is really needed
+  - test_krbtpolicy: skip SPAKE-related tests in FIPS mode
+  - Support AES for KRA archival wrapping
+  - Set AES as default for KRA archival wrapping
+
+* Thu Feb 24 2022 Florence Blanc-Renaud <frenaud@redhat.com> - 4.9.8-6
+- Resolves: rhbz#2057467 Backport latest test fixes in python3-ipatests
+  - ipatests: Tests for Autoprivate group.
+  - mark xfail for test_idoverride_with_auto_private_group[hybrid]
+  - Mark xfail test_gidnumber_not_corresponding_existing_group[true,hybrid]
+
 * Mon Feb 14 2022 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.8-5
 - Resolves: rhbz#2053025
   - add IPA test suite fixes