diff --git a/SOURCES/0077-SSSD-man-man_dns_resolver_parameter_modification.patch b/SOURCES/0077-SSSD-man-man_dns_resolver_parameter_modification.patch
new file mode 100644
index 0000000..fb7c497
--- /dev/null
+++ b/SOURCES/0077-SSSD-man-man_dns_resolver_parameter_modification.patch
@@ -0,0 +1,75 @@
+From 4b02c9632c44265124e4fa130170bc86de369b8c Mon Sep 17 00:00:00 2001
+From: Deepak Das <ddas@redhat.com>
+Date: Thu, 20 May 2021 20:30:33 +0530
+Subject: [PATCH 77/83] SSSD man: man_dns_resolver_parameter_modification
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Adding parameter dns_resolver_server_timeout
+and dns_resolver_op_timeout in sssd.conf
+
+Resolves: https://github.com/SSSD/sssd/issues/5616
+
+Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
+Reviewed-by: Justin Stephenson <jstephen@redhat.com>
+(cherry picked from commit 43b9b0922aa24a03ea466c673646d5e3079403fe)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/man/sssd.conf.5.xml | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
+index 8adbb8de9..a597828ca 100644
+--- a/src/man/sssd.conf.5.xml
++++ b/src/man/sssd.conf.5.xml
+@@ -2809,6 +2809,45 @@ pam_p11_allowed_services = +my_pam_service, -login
+                     </listitem>
+                 </varlistentry>
+ 
++                <varlistentry>
++                    <term>dns_resolver_server_timeout (integer)</term>
++                    <listitem>
++                        <para>
++                            Defines the amount of time (in milliseconds)
++                            SSSD would try to talk to DNS server before
++                            trying next DNS server.
++                        </para>
++                        <para>
++                            Please see the section <quote>FAILOVER</quote>
++                            for more information about the service
++                            resolution.
++                        </para>
++                        <para>
++                            Default: 1000
++                        </para>
++                    </listitem>
++                </varlistentry>
++
++                <varlistentry>
++                    <term>dns_resolver_op_timeout (integer)</term>
++                    <listitem>
++                        <para>
++                            Defines the amount of time (in seconds) to
++                            wait to resolve single DNS query
++                            (e.g. resolution of a hostname or an SRV record)
++                            before try next hostname or DNS discovery.
++                        </para>
++                        <para>
++                            Please see the section <quote>FAILOVER</quote>
++                            for more information about the service
++                            resolution.
++                        </para>
++                        <para>
++                            Default: 3
++                        </para>
++                    </listitem>
++                </varlistentry>
++
+                 <varlistentry>
+                     <term>dns_resolver_timeout (integer)</term>
+                     <listitem>
+-- 
+2.26.3
+
diff --git a/SOURCES/0078-ad-require-name-when-looking-up-root-domain.patch b/SOURCES/0078-ad-require-name-when-looking-up-root-domain.patch
new file mode 100644
index 0000000..d976074
--- /dev/null
+++ b/SOURCES/0078-ad-require-name-when-looking-up-root-domain.patch
@@ -0,0 +1,45 @@
+From 4b59b0af3d97b2a6b0acc08fa80377a5f59e5bfe Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 8 Oct 2021 12:44:37 +0200
+Subject: [PATCH 78/83] ad: require name when looking up root domain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+To properly identify the forest root domain the name of this domain is
+needed. It is discovered with a cldap-ping requesting the netlogon
+attribute. If the name is missing it does not make sense to proceed
+further because there is currently no other way to determine the forest
+root domain.
+
+Resolves: https://github.com/SSSD/sssd/issues/5820
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit b37e2713a9b86936f5b82a17e47757562900b911)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/providers/ad/ad_subdomains.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index 6b98cdf1d..5be7c2003 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -1431,7 +1431,12 @@ ad_get_root_domain_send(TALLOC_CTX *mem_ctx,
+         return NULL;
+     }
+ 
+-    if (forest != NULL && strcasecmp(domain, forest) == 0) {
++    if (forest == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "Name of forest root domain not available, l"
++                                 "using cached data, if available.\n");
++        ret = EINVAL;
++        goto immediately;
++    } else if (strcasecmp(domain, forest) == 0) {
+         state->root_id_ctx = sd_ctx->ad_id_ctx;
+         state->root_domain_attrs = NULL;
+         ret = EOK;
+-- 
+2.26.3
+
diff --git a/SOURCES/0079-ad-move-current-site-and-forest-name-to-a-more-globa.patch b/SOURCES/0079-ad-move-current-site-and-forest-name-to-a-more-globa.patch
new file mode 100644
index 0000000..ac95c95
--- /dev/null
+++ b/SOURCES/0079-ad-move-current-site-and-forest-name-to-a-more-globa.patch
@@ -0,0 +1,234 @@
+From ecfb7df52fd3b0edf8549d42cfa6b378407fb982 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 8 Oct 2021 13:14:30 +0200
+Subject: [PATCH 79/83] ad: move current site and forest name to a more global
+ context
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently only during the DNS discovery steps the stored forest and site
+name are reused to avoid redundant lookups. Since those names are needed
+in other areas of the code as well it would be good to make them
+available in a more global context.
+
+Resolves: https://github.com/SSSD/sssd/issues/5820
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit 4508ef5f7183c640191393605ea163044d9ac267)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/providers/ad/ad_cldap_ping.c          | 15 ++++++-----
+ src/providers/ad/ad_common.h              |  4 +++
+ src/providers/ad/ad_init.c                |  1 +
+ src/providers/ad/ad_srv.c                 | 33 +++++++++++++----------
+ src/providers/ad/ad_srv.h                 |  4 +--
+ src/providers/ad/ad_subdomains.c          |  1 +
+ src/providers/ipa/ipa_subdomains_server.c |  1 +
+ 7 files changed, 37 insertions(+), 22 deletions(-)
+
+diff --git a/src/providers/ad/ad_cldap_ping.c b/src/providers/ad/ad_cldap_ping.c
+index ab234f4d7..100d448f5 100644
+--- a/src/providers/ad/ad_cldap_ping.c
++++ b/src/providers/ad/ad_cldap_ping.c
+@@ -601,10 +601,12 @@ struct tevent_req *ad_cldap_ping_send(TALLOC_CTX *mem_ctx,
+     }
+ 
+     if (!srv_ctx->renew_site) {
+-        state->site = talloc_strdup(state, srv_ctx->current_site);
+-        state->forest = talloc_strdup(state, srv_ctx->current_forest);
+-        if ((srv_ctx->current_site != NULL && state->site == NULL)
+-                || (srv_ctx->current_forest != NULL && state->forest == NULL)) {
++        state->site = talloc_strdup(state, srv_ctx->ad_options->current_site);
++        state->forest = talloc_strdup(state,
++                                      srv_ctx->ad_options->current_forest);
++        if ((srv_ctx->ad_options->current_site != NULL && state->site == NULL)
++                || (srv_ctx->ad_options->current_forest != NULL
++                                    && state->forest == NULL)) {
+             DEBUG(SSSDBG_OP_FAILURE,
+                   "Failed to copy current site or forest name.\n");
+             ret = ENOMEM;
+@@ -629,9 +631,10 @@ struct tevent_req *ad_cldap_ping_send(TALLOC_CTX *mem_ctx,
+     state->discovery_domain = discovery_domain;
+ 
+     /* If possible, lookup the information in the current site first. */
+-    if (srv_ctx->current_site != NULL) {
++    if (srv_ctx->ad_options->current_site != NULL) {
+         state->all_tried = false;
+-        domain = ad_site_dns_discovery_domain(state, srv_ctx->current_site,
++        domain = ad_site_dns_discovery_domain(state,
++                                              srv_ctx->ad_options->current_site,
+                                               discovery_domain);
+         if (domain == NULL) {
+             DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory!");
+diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
+index 815b41419..311b84f4c 100644
+--- a/src/providers/ad/ad_common.h
++++ b/src/providers/ad/ad_common.h
+@@ -105,6 +105,10 @@ struct ad_options {
+     /* Dynamic DNS updates */
+     struct be_resolv_ctx *be_res;
+     struct be_nsupdate_ctx *dyndns_ctx;
++
++    /* Discovered site and forest names */
++    const char *current_site;
++    const char *current_forest;
+ };
+ 
+ errno_t
+diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
+index 5abd28b7c..9f258e2bd 100644
+--- a/src/providers/ad/ad_init.c
++++ b/src/providers/ad/ad_init.c
+@@ -206,6 +206,7 @@ static errno_t ad_init_srv_plugin(struct be_ctx *be_ctx,
+ 
+     srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res,
+                                      default_host_dbs, ad_options->id,
++                                     ad_options,
+                                      hostname, ad_domain,
+                                      ad_site_override);
+     if (srv_ctx == NULL) {
+diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
+index e58c19aac..a10c6a247 100644
+--- a/src/providers/ad/ad_srv.c
++++ b/src/providers/ad/ad_srv.c
+@@ -130,6 +130,7 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
+                        struct be_resolv_ctx *be_res,
+                        enum host_database *host_dbs,
+                        struct sdap_options *opts,
++                       struct ad_options *ad_options,
+                        const char *hostname,
+                        const char *ad_domain,
+                        const char *ad_site_override)
+@@ -147,6 +148,7 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
+     ctx->host_dbs = host_dbs;
+     ctx->opts = opts;
+     ctx->renew_site = true;
++    ctx->ad_options = ad_options;
+ 
+     ctx->hostname = talloc_strdup(ctx, hostname);
+     if (ctx->hostname == NULL) {
+@@ -164,18 +166,20 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
+             goto fail;
+         }
+ 
+-        ctx->current_site = talloc_strdup(ctx, ad_site_override);
+-        if (ctx->current_site == NULL) {
++        ctx->ad_options->current_site = talloc_strdup(ctx->ad_options,
++                                                      ad_site_override);
++        if (ctx->ad_options->current_site == NULL) {
+             goto fail;
+         }
+     } else {
+-        ret = sysdb_get_site(ctx, be_ctx->domain, &ctx->current_site);
++        ret = sysdb_get_site(ctx->ad_options, be_ctx->domain,
++                             &ctx->ad_options->current_site);
+         if (ret != EOK) {
+             /* Not fatal. */
+             DEBUG(SSSDBG_MINOR_FAILURE,
+                   "Unable to get current site from cache [%d]: %s\n",
+                   ret, sss_strerror(ret));
+-            ctx->current_site = NULL;
++            ctx->ad_options->current_site = NULL;
+         }
+     }
+ 
+@@ -203,34 +207,35 @@ ad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx,
+ 
+     /* Switch forest. */
+     if (new_forest != NULL
+-        && (ctx->current_forest == NULL
+-            || strcmp(ctx->current_forest, new_forest) != 0)) {
+-        forest = talloc_strdup(ctx, new_forest);
++        && (ctx->ad_options->current_forest == NULL
++            || strcmp(ctx->ad_options->current_forest, new_forest) != 0)) {
++        forest = talloc_strdup(ctx->ad_options, new_forest);
+         if (forest == NULL) {
+             return ENOMEM;
+         }
+ 
+-        talloc_zfree(ctx->current_forest);
+-        ctx->current_forest = forest;
++        talloc_zfree(ctx->ad_options->current_forest);
++        ctx->ad_options->current_forest = forest;
+     }
+ 
+     if (new_site == NULL) {
+         return EOK;
+     }
+ 
+-    if (ctx->current_site != NULL && strcmp(ctx->current_site, new_site) == 0) {
++    if (ctx->ad_options->current_site != NULL
++                    && strcmp(ctx->ad_options->current_site, new_site) == 0) {
+         return EOK;
+     }
+ 
+-    site = talloc_strdup(ctx, new_site);
++    site = talloc_strdup(ctx->ad_options, new_site);
+     if (site == NULL) {
+         return ENOMEM;
+     }
+ 
+-    talloc_zfree(ctx->current_site);
+-    ctx->current_site = site;
++    talloc_zfree(ctx->ad_options->current_site);
++    ctx->ad_options->current_site = site;
+ 
+-    ret = sysdb_set_site(ctx->be_ctx->domain, ctx->current_site);
++    ret = sysdb_set_site(ctx->be_ctx->domain, ctx->ad_options->current_site);
+     if (ret != EOK) {
+         /* Not fatal. */
+         DEBUG(SSSDBG_MINOR_FAILURE, "Unable to store site information "
+diff --git a/src/providers/ad/ad_srv.h b/src/providers/ad/ad_srv.h
+index 3c6a779ea..fd70f15a8 100644
+--- a/src/providers/ad/ad_srv.h
++++ b/src/providers/ad/ad_srv.h
+@@ -26,11 +26,10 @@ struct ad_srv_plugin_ctx {
+     struct be_resolv_ctx *be_res;
+     enum host_database *host_dbs;
+     struct sdap_options *opts;
++    struct ad_options *ad_options;
+     const char *hostname;
+     const char *ad_domain;
+     const char *ad_site_override;
+-    const char *current_site;
+-    const char *current_forest;
+ 
+     bool renew_site;
+ };
+@@ -41,6 +40,7 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
+                        struct be_resolv_ctx *be_res,
+                        enum host_database *host_dbs,
+                        struct sdap_options *opts,
++                       struct ad_options *ad_options,
+                        const char *hostname,
+                        const char *ad_domain,
+                        const char *ad_site_override);
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index 5be7c2003..8a331c503 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -416,6 +416,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
+     srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res,
+                                      default_host_dbs,
+                                      ad_id_ctx->ad_options->id,
++                                     ad_id_ctx->ad_options,
+                                      hostname,
+                                      ad_domain,
+                                      ad_site_override);
+diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
+index f0d8a6a20..ed363c22f 100644
+--- a/src/providers/ipa/ipa_subdomains_server.c
++++ b/src/providers/ipa/ipa_subdomains_server.c
+@@ -342,6 +342,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
+     srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res,
+                                      default_host_dbs,
+                                      ad_id_ctx->ad_options->id,
++                                     ad_id_ctx->ad_options,
+                                      id_ctx->server_mode->hostname,
+                                      ad_domain,
+                                      ad_site_override);
+-- 
+2.26.3
+
diff --git a/SOURCES/0080-ad-use-already-discovered-forest-name.patch b/SOURCES/0080-ad-use-already-discovered-forest-name.patch
new file mode 100644
index 0000000..35c48d7
--- /dev/null
+++ b/SOURCES/0080-ad-use-already-discovered-forest-name.patch
@@ -0,0 +1,53 @@
+From f60a6fc682646a8c16fa8875456300c61cf3e979 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 8 Oct 2021 13:49:01 +0200
+Subject: [PATCH 80/83] ad: use already discovered forest name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If the cldap-ping on the current connection does not return a reply with
+the name of the forest root and the site of the client the stored values
+from the DNS discovery step are used.
+
+Resolves: https://github.com/SSSD/sssd/issues/5820
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit 99c4161910e542dd40c740032196d268c4163d07)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/providers/ad/ad_subdomains.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index 8a331c503..562047a02 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -2095,6 +2095,23 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
+         return;
+     }
+ 
++    if (state->forest == NULL) {
++        DEBUG(SSSDBG_MINOR_FAILURE, "Forest name was not found, using the one "
++                                    "which was already discovered [%s].\n",
++                                    state->ad_options->current_forest != NULL ?
++                                        state->ad_options->current_forest :
++                                        "- not available-");
++        if (state->ad_options->current_forest != NULL) {
++            state->forest = talloc_strdup(state,
++                                          state->ad_options->current_forest);
++            if (state->forest == NULL) {
++                DEBUG(SSSDBG_OP_FAILURE, "Failed to copy forest name.\n");
++                tevent_req_error(req, ENOMEM);
++                return;
++            }
++        }
++    }
++
+     realm = dp_opt_get_cstring(state->ad_options->basic, AD_KRB5_REALM);
+     if (realm == NULL) {
+         DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm.\n");
+-- 
+2.26.3
+
diff --git a/SOURCES/0081-ad-make-ad_srv_plugin_ctx_switch_site-public.patch b/SOURCES/0081-ad-make-ad_srv_plugin_ctx_switch_site-public.patch
new file mode 100644
index 0000000..0d40213
--- /dev/null
+++ b/SOURCES/0081-ad-make-ad_srv_plugin_ctx_switch_site-public.patch
@@ -0,0 +1,256 @@
+From 664ae9d2247b5139d2286975228baa0cea39a8e4 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 20 Oct 2021 13:59:40 +0200
+Subject: [PATCH 81/83] ad: make ad_srv_plugin_ctx_switch_site() public
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If the name of the AD DCs are given explicitly with the ad_server option
+the forest and site lookups are not done in the discovery phase, which
+is skipped, but with a netlogon query on the current connection. This
+patch makes sure the results are stored in the same way as during the
+discovery step.
+
+Resolves: https://github.com/SSSD/sssd/issues/5820
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit 918abaf37d7f13d72b29863933e133bcbd24d87c)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/providers/ad/ad_common.c      | 48 +++++++++++++++++++++
+ src/providers/ad/ad_common.h      |  3 ++
+ src/providers/ad/ad_domain_info.h |  1 -
+ src/providers/ad/ad_srv.c         | 70 ++++++-------------------------
+ src/providers/ad/ad_subdomains.c  | 34 ++++++++++++++-
+ 5 files changed, 96 insertions(+), 60 deletions(-)
+
+diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
+index c99c4d110..4463349e4 100644
+--- a/src/providers/ad/ad_common.c
++++ b/src/providers/ad/ad_common.c
+@@ -1554,3 +1554,51 @@ done:
+ 
+     return ret;
+ }
++
++errno_t
++ad_options_switch_site(struct ad_options *ad_options, struct be_ctx *be_ctx,
++                       const char *new_site, const char *new_forest)
++{
++    const char *site;
++    const char *forest;
++    errno_t ret;
++
++    /* Switch forest. */
++    if (new_forest != NULL
++        && (ad_options->current_forest == NULL
++            || strcmp(ad_options->current_forest, new_forest) != 0)) {
++        forest = talloc_strdup(ad_options, new_forest);
++        if (forest == NULL) {
++            return ENOMEM;
++        }
++
++        talloc_zfree(ad_options->current_forest);
++        ad_options->current_forest = forest;
++    }
++
++    if (new_site == NULL) {
++        return EOK;
++    }
++
++    if (ad_options->current_site != NULL
++                    && strcmp(ad_options->current_site, new_site) == 0) {
++        return EOK;
++    }
++
++    site = talloc_strdup(ad_options, new_site);
++    if (site == NULL) {
++        return ENOMEM;
++    }
++
++    talloc_zfree(ad_options->current_site);
++    ad_options->current_site = site;
++
++    ret = sysdb_set_site(be_ctx->domain, ad_options->current_site);
++    if (ret != EOK) {
++        /* Not fatal. */
++        DEBUG(SSSDBG_MINOR_FAILURE, "Unable to store site information "
++              "[%d]: %s\n", ret, sss_strerror(ret));
++    }
++
++    return EOK;
++}
+diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
+index 311b84f4c..08fcc00fd 100644
+--- a/src/providers/ad/ad_common.h
++++ b/src/providers/ad/ad_common.h
+@@ -238,4 +238,7 @@ errno_t ad_inherit_opts_if_needed(struct dp_option *parent_opts,
+ errno_t ad_refresh_init(struct be_ctx *be_ctx,
+                         struct ad_id_ctx *id_ctx);
+ 
++errno_t
++ad_options_switch_site(struct ad_options *ad_options, struct be_ctx *be_ctx,
++                       const char *new_site, const char *new_forest);
+ #endif /* AD_COMMON_H_ */
+diff --git a/src/providers/ad/ad_domain_info.h b/src/providers/ad/ad_domain_info.h
+index 631e543f5..cf601cff6 100644
+--- a/src/providers/ad/ad_domain_info.h
++++ b/src/providers/ad/ad_domain_info.h
+@@ -39,5 +39,4 @@ ad_domain_info_recv(struct tevent_req *req,
+                       char **_id,
+                       char **_site,
+                       char **_forest);
+-
+ #endif /* _AD_DOMAIN_INFO_H_ */
+diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
+index a10c6a247..d45f1601e 100644
+--- a/src/providers/ad/ad_srv.c
++++ b/src/providers/ad/ad_srv.c
+@@ -196,55 +196,6 @@ fail:
+     return NULL;
+ }
+ 
+-static errno_t
+-ad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx,
+-                              const char *new_site,
+-                              const char *new_forest)
+-{
+-    const char *site;
+-    const char *forest;
+-    errno_t ret;
+-
+-    /* Switch forest. */
+-    if (new_forest != NULL
+-        && (ctx->ad_options->current_forest == NULL
+-            || strcmp(ctx->ad_options->current_forest, new_forest) != 0)) {
+-        forest = talloc_strdup(ctx->ad_options, new_forest);
+-        if (forest == NULL) {
+-            return ENOMEM;
+-        }
+-
+-        talloc_zfree(ctx->ad_options->current_forest);
+-        ctx->ad_options->current_forest = forest;
+-    }
+-
+-    if (new_site == NULL) {
+-        return EOK;
+-    }
+-
+-    if (ctx->ad_options->current_site != NULL
+-                    && strcmp(ctx->ad_options->current_site, new_site) == 0) {
+-        return EOK;
+-    }
+-
+-    site = talloc_strdup(ctx->ad_options, new_site);
+-    if (site == NULL) {
+-        return ENOMEM;
+-    }
+-
+-    talloc_zfree(ctx->ad_options->current_site);
+-    ctx->ad_options->current_site = site;
+-
+-    ret = sysdb_set_site(ctx->be_ctx->domain, ctx->ad_options->current_site);
+-    if (ret != EOK) {
+-        /* Not fatal. */
+-        DEBUG(SSSDBG_MINOR_FAILURE, "Unable to store site information "
+-              "[%d]: %s\n", ret, sss_strerror(ret));
+-    }
+-
+-    return EOK;
+-}
+-
+ struct ad_srv_plugin_state {
+     struct tevent_context *ev;
+     struct ad_srv_plugin_ctx *ctx;
+@@ -382,16 +333,19 @@ static void ad_srv_plugin_ping_done(struct tevent_req *subreq)
+         /* Remember current site so it can be used during next lookup so
+          * we can contact directory controllers within a known reachable
+          * site first. */
+-        ret = ad_srv_plugin_ctx_switch_site(state->ctx, state->site,
+-                                            state->forest);
+-        if (ret != EOK) {
+-            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set site [%d]: %s\n",
+-                  ret, sss_strerror(ret));
+-            goto done;
+-        }
++        if (state->site != NULL) {
++            ret = ad_options_switch_site(state->ctx->ad_options,
++                                         state->ctx->be_ctx,
++                                         state->site, state->forest);
++            if (ret != EOK) {
++                DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set site [%d]: %s\n",
++                      ret, sss_strerror(ret));
++                goto done;
++            }
+ 
+-        /* Do not renew the site again unless we go offline. */
+-        state->ctx->renew_site = false;
++            /* Do not renew the site again unless we go offline. */
++            state->ctx->renew_site = false;
++        }
+ 
+         if (strcmp(state->service, "gc") == 0) {
+             if (state->forest != NULL) {
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index 562047a02..e4e248c1d 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -2080,13 +2080,15 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
+     const char *realm;
+     char *master_sid;
+     char *flat_name;
++    char *site = NULL;
+     errno_t ret;
++    char *ad_site_override = NULL;
+ 
+     req = tevent_req_callback_data(subreq, struct tevent_req);
+     state = tevent_req_data(req, struct ad_subdomains_refresh_state);
+ 
+     ret = ad_domain_info_recv(subreq, state, &flat_name, &master_sid,
+-                              NULL, &state->forest);
++                              &site, &state->forest);
+     talloc_zfree(subreq);
+     if (ret != EOK) {
+         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get master domain information "
+@@ -2112,6 +2114,36 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
+         }
+     }
+ 
++    /* If the site was not discovered during the DNS discovery, e.g. because
++     * the server name was given explicitly in sssd.conf, we try to set the
++     * site here. */
++    if (state->ad_options->current_site == NULL) {
++        /* Ignore AD site found in netlogon attribute if specific site is set in
++         * configuration file. */
++        ad_site_override = dp_opt_get_string(state->ad_options->basic, AD_SITE);
++        if (ad_site_override != NULL) {
++            DEBUG(SSSDBG_TRACE_INTERNAL,
++                  "Ignoring AD site found by DNS discovery: '%s', "
++                  "using configured value: '%s' instead.\n",
++                  site, ad_site_override);
++            site = ad_site_override;
++        }
++
++        if (site != NULL) {
++            ret = ad_options_switch_site(state->ad_options, state->be_ctx, site,
++                                         state->forest);
++            if (ret != EOK) {
++                DEBUG(SSSDBG_OP_FAILURE, "Failed to store forest and site name, "
++                                         "will try again after a new lookup.\n");
++            }
++        } else {
++            DEBUG(SSSDBG_MINOR_FAILURE,
++                  "Site name currently not available will try again later. "
++                  "The site name can be added manually my setting 'ad_site' "
++                  "in sssd.conf.\n");
++        }
++    }
++
+     realm = dp_opt_get_cstring(state->ad_options->basic, AD_KRB5_REALM);
+     if (realm == NULL) {
+         DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm.\n");
+-- 
+2.26.3
+
diff --git a/SOURCES/0082-ad-only-send-cldap-ping-to-our-local-domain.patch b/SOURCES/0082-ad-only-send-cldap-ping-to-our-local-domain.patch
new file mode 100644
index 0000000..6f079b3
--- /dev/null
+++ b/SOURCES/0082-ad-only-send-cldap-ping-to-our-local-domain.patch
@@ -0,0 +1,45 @@
+From ed243335d3e74ab2cde49eacc9a85ca5408a8dec Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 15 Oct 2021 13:39:50 +0200
+Subject: [PATCH 82/83] ad: only send cldap-ping to our local domain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since we are using the name of the local domain in the search filter of
+the CLDAP ping only a DC from the local domain can send a proper reply.
+DCs from other domains will only return an error so we can skip the
+CLDAP ping for those domains.
+
+Resolves: https://github.com/SSSD/sssd/issues/5822
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit 724293d0873ee3229866ae4c13e1c8829375146f)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/providers/ad/ad_cldap_ping.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/src/providers/ad/ad_cldap_ping.c b/src/providers/ad/ad_cldap_ping.c
+index 100d448f5..91db81bfc 100644
+--- a/src/providers/ad/ad_cldap_ping.c
++++ b/src/providers/ad/ad_cldap_ping.c
+@@ -621,6 +621,14 @@ struct tevent_req *ad_cldap_ping_send(TALLOC_CTX *mem_ctx,
+         goto done;
+     }
+ 
++    if (strcmp(srv_ctx->ad_domain, discovery_domain) != 0) {
++        DEBUG(SSSDBG_TRACE_ALL, "Trying to discover domain [%s] "
++              "which is not our local domain [%s], skipping CLDAP ping.\n",
++              discovery_domain, srv_ctx->ad_domain);
++        ret = EOK;
++        goto done;
++    }
++
+     DEBUG(SSSDBG_TRACE_FUNC, "Sending CLDAP ping\n");
+ 
+     state->ev = ev;
+-- 
+2.26.3
+
diff --git a/SOURCES/0083-cldap-use-dns_resolver_server_timeout-timeout-for-cl.patch b/SOURCES/0083-cldap-use-dns_resolver_server_timeout-timeout-for-cl.patch
new file mode 100644
index 0000000..2112ae5
--- /dev/null
+++ b/SOURCES/0083-cldap-use-dns_resolver_server_timeout-timeout-for-cl.patch
@@ -0,0 +1,93 @@
+From be3ee30c68dd9d2e5184da226dfbe66f516a4b92 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Tue, 16 Nov 2021 15:01:20 +0100
+Subject: [PATCH 83/83] cldap: use dns_resolver_server_timeout timeout for
+ cldap ping
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently the cldap ping is using the ldap_search_timeout since it is
+basically a LDAP search operation. However, the default of
+ldap_search_timeout is 6s which is quite a long time for the discovery
+of the AD DCs where the cldap ping is a part of. The default even
+collides which the default of dns_resolver_timeout which might easily
+lead to failures during the discovery phase.
+
+To avoid the addition of a new option this patch is using
+dns_resolver_server_timeout, which has a default of 1000ms (1s), as new
+timeout for the clapd ping. Since the original purpose of the timeout is
+the waiting time for a reply from a DNS server and both DNS and cldap by
+default use UDP I think reusing the option here is justified.
+
+Resolves: https://github.com/SSSD/sssd/issues/5875
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit c0941810fc3c3d74a00697349723f14e2f6bbdd2)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/man/sssd.conf.5.xml          |  4 ++++
+ src/providers/ad/ad_cldap_ping.c | 10 +++++++++-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
+index a597828ca..d81ec35a6 100644
+--- a/src/man/sssd.conf.5.xml
++++ b/src/man/sssd.conf.5.xml
+@@ -2817,6 +2817,10 @@ pam_p11_allowed_services = +my_pam_service, -login
+                             SSSD would try to talk to DNS server before
+                             trying next DNS server.
+                         </para>
++                        <para>
++                                The AD provider will use this option for the
++                                CLDAP ping timeouts as well.
++                        </para>
+                         <para>
+                             Please see the section <quote>FAILOVER</quote>
+                             for more information about the service
+diff --git a/src/providers/ad/ad_cldap_ping.c b/src/providers/ad/ad_cldap_ping.c
+index 91db81bfc..8ae65e8c9 100644
+--- a/src/providers/ad/ad_cldap_ping.c
++++ b/src/providers/ad/ad_cldap_ping.c
+@@ -39,6 +39,7 @@
+ struct ad_cldap_ping_dc_state {
+     struct tevent_context *ev;
+     struct sdap_options *opts;
++    struct be_resolv_ctx *be_res;
+     struct fo_server_info *dc;
+     struct sdap_handle *sh;
+     const char *ad_domain;
+@@ -72,6 +73,7 @@ static struct tevent_req *ad_cldap_ping_dc_send(TALLOC_CTX *mem_ctx,
+ 
+     state->ev = ev;
+     state->opts = opts;
++    state->be_res = be_res;
+     state->dc = dc;
+     state->ad_domain = ad_domain;
+ 
+@@ -103,6 +105,7 @@ static void ad_cldap_ping_dc_connect_done(struct tevent_req *subreq)
+     char *filter;
+     int timeout;
+     errno_t ret;
++    div_t timeout_int;
+ 
+     req = tevent_req_callback_data(subreq, struct tevent_req);
+     state = tevent_req_data(req, struct ad_cldap_ping_dc_state);
+@@ -127,7 +130,12 @@ static void ad_cldap_ping_dc_connect_done(struct tevent_req *subreq)
+         goto done;
+     }
+ 
+-    timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
++    /* DP_RES_OPT_RESOLVER_SERVER_TIMEOUT is in milli-seconds and
++     * sdap_get_generic_send() expects seconds */
++    timeout_int = div(dp_opt_get_int(state->be_res->opts,
++                                     DP_RES_OPT_RESOLVER_SERVER_TIMEOUT),
++                      1000);
++    timeout = (timeout_int.quot > 0) ? timeout_int.quot : 1;
+     subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, "",
+                                    LDAP_SCOPE_BASE, filter, attrs, NULL,
+                                    0, timeout, false);
+-- 
+2.26.3
+
diff --git a/SOURCES/0084-sysdb-more-specific-mpg-search-filter.patch b/SOURCES/0084-sysdb-more-specific-mpg-search-filter.patch
new file mode 100644
index 0000000..8738ccf
--- /dev/null
+++ b/SOURCES/0084-sysdb-more-specific-mpg-search-filter.patch
@@ -0,0 +1,60 @@
+From 0dde096aac1db7d8533f51254f6a8c22a67114d8 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Mon, 2 Aug 2021 15:53:42 +0200
+Subject: [PATCH] sysdb: more specific mpg search filter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Originally all user of an mpg domain had an automatically created
+user-private group and as a result the ID space was unified in the sense
+that a given ID either belongs to a group or to a user with a
+user-private group.
+
+With the introduction of id-overrides and the auto_private_groups option
+this assumption is not true anymore and as a result the search filter
+for GIDs must be more specific with respect to the user objects.
+
+Resolves: https://github.com/SSSD/sssd/issues/5790
+
+:fixes: Improve mpg search filter to be more reliable with id-overrides
+  and the new auto_private_groups options.
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit 4be5fcd9afd62b1094eb27970627d327ac770127)
+
+Reviewed-by: Tomáš Halman <thalman@redhat.com>
+---
+ src/db/sysdb.h        | 2 +-
+ src/db/sysdb_search.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/db/sysdb.h b/src/db/sysdb.h
+index c771ce633..c601c251f 100644
+--- a/src/db/sysdb.h
++++ b/src/db/sysdb.h
+@@ -215,7 +215,7 @@
+ #define SYSDB_GRSID_FILTER "(&("SYSDB_GC")("SYSDB_SID_STR"=%s))"
+ #define SYSDB_GRENT_FILTER "("SYSDB_GC")"
+ #define SYSDB_GRNAM_MPG_FILTER "(&("SYSDB_MPGC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"
+-#define SYSDB_GRGID_MPG_FILTER "(&("SYSDB_MPGC")("SYSDB_GIDNUM"=%lu))"
++#define SYSDB_GRGID_MPG_FILTER "(|(&("SYSDB_GC")("SYSDB_GIDNUM"=%lu))(&("SYSDB_UC")("SYSDB_GIDNUM"=%lu)("SYSDB_UIDNUM"=%lu)))"
+ #define SYSDB_GRENT_MPG_FILTER "("SYSDB_MPGC")"
+ 
+ #define SYSDB_INITGR_FILTER "(&("SYSDB_GC")("SYSDB_GIDNUM"=*))"
+diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
+index 7939944ba..d783abc68 100644
+--- a/src/db/sysdb_search.c
++++ b/src/db/sysdb_search.c
+@@ -1355,7 +1355,7 @@ int sysdb_getgrgid_attrs(TALLOC_CTX *mem_ctx,
+         }
+ 
+         ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
+-                         LDB_SCOPE_SUBTREE, attrs, fmt_filter, ul_gid);
++                         LDB_SCOPE_SUBTREE, attrs, fmt_filter, ul_gid, ul_gid, ul_gid);
+         if (ret != EOK) {
+             ret = sysdb_error_to_errno(ret);
+             goto done;
+-- 
+2.26.3
+
diff --git a/SOURCES/0085-ad-add-required-cn-attribute-to-subdomain-object.patch b/SOURCES/0085-ad-add-required-cn-attribute-to-subdomain-object.patch
new file mode 100644
index 0000000..f3fe3d3
--- /dev/null
+++ b/SOURCES/0085-ad-add-required-cn-attribute-to-subdomain-object.patch
@@ -0,0 +1,43 @@
+From 64192cf7c2823ae93820623b0ae285b697fabe12 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Thu, 16 Dec 2021 11:14:18 +0100
+Subject: [PATCH] ad: add required 'cn' attribute to subdomain object
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If the forest root is not part of the return trusted domain objects
+from the local domain controller we generate an object for further
+processing. During this processing it is expected that the 'cn'
+attribute is set and contains the name of the forest root. So far this
+attribute was missing and it is now added by this patch.
+
+Resolves: https://github.com/SSSD/sssd/issues/5926
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit bf6059eb55c8caa3111ef718db1676c96a67c084)
+---
+ src/providers/ad/ad_subdomains.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index e4e248c1d..c92faba95 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -1649,6 +1649,13 @@ static void ad_check_root_domain_done(struct tevent_req *subreq)
+         goto done;
+     }
+ 
++    ret = sysdb_attrs_add_string(state->reply[0], AD_AT_DOMAIN_NAME,
++                                 state->forest);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string() failed.\n");
++        goto done;
++    }
++
+     err = sss_idmap_sid_to_bin_sid(state->idmap_ctx->map, id,
+                                    &id_val.data, &id_val.length);
+     if (err != IDMAP_SUCCESS) {
+-- 
+2.26.3
+
diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec
index 72da1e1..6103e53 100644
--- a/SPECS/sssd.spec
+++ b/SPECS/sssd.spec
@@ -50,7 +50,7 @@
 
 Name: sssd
 Version: 1.16.5
-Release: 10%{?dist}.11
+Release: 10%{?dist}.12
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -135,6 +135,15 @@ Patch0073: 0073-cldap.patch
 Patch0074: 0074-util-inotify-fixed-bug-in-inotify-event-processing.patch
 Patch0075: 0075-sdap-always-create-sdap-object-for-a-forest-root.patch
 Patch0076: 0076-ad-filter-trusted-domains.patch
+Patch0077: 0077-SSSD-man-man_dns_resolver_parameter_modification.patch
+Patch0078: 0078-ad-require-name-when-looking-up-root-domain.patch
+Patch0079: 0079-ad-move-current-site-and-forest-name-to-a-more-globa.patch
+Patch0080: 0080-ad-use-already-discovered-forest-name.patch
+Patch0081: 0081-ad-make-ad_srv_plugin_ctx_switch_site-public.patch
+Patch0082: 0082-ad-only-send-cldap-ping-to-our-local-domain.patch
+Patch0083: 0083-cldap-use-dns_resolver_server_timeout-timeout-for-cl.patch
+Patch0084: 0084-sysdb-more-specific-mpg-search-filter.patch
+Patch0085: 0085-ad-add-required-cn-attribute-to-subdomain-object.patch
 
 #Those patches should not be removed in RHEL-7
 Patch0999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec
@@ -1310,6 +1319,12 @@ systemctl try-restart sssd >/dev/null 2>&1 || :
 }
 
 %changelog
+* Mon Jan 31 2022 Alexey Tikhonov <atikhono@redhat.com> 1.16.5-10.12
+- Resolves: rhbz#2006382 - IPA Intermittence fetching groups
+- Resolves: rhbz#2006866 - sssd_be segfault due to empty forest root name
+- Resolves: rhbz#2031729 - IPA clients fail to resolve override group names.
+- Resolves: rhbz#2032867 - AD Domain in the AD Forest Missing after sssd latest update
+
 * Tue Nov 02 2021 Alexey Tikhonov <atikhono@redhat.com> 1.16.5-10.11
 - Resolves: rhbz#1968316 - SSSD: User authentication failing after server reboot.
 - Resolves: rhbz#2000238 - disabled root ad domain causes subdomains to be marked offline