diff --git a/SOURCES/0062-UTIL-find_domain_by_object_name_ex-changed-log-level.patch b/SOURCES/0062-UTIL-find_domain_by_object_name_ex-changed-log-level.patch
new file mode 100644
index 0000000..708327b
--- /dev/null
+++ b/SOURCES/0062-UTIL-find_domain_by_object_name_ex-changed-log-level.patch
@@ -0,0 +1,36 @@
+From ba06302d262aa3571620455fafadb43aaa93139e Mon Sep 17 00:00:00 2001
+From: Alexey Tikhonov <atikhono@redhat.com>
+Date: Tue, 15 Dec 2020 18:47:25 +0100
+Subject: [PATCH] UTIL: find_domain_by_object_name_ex() changed log level
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It's up to user of this function to judge if fail to parse fqname is
+a critical error.
+
+Reviewed-by: Pawel Polawski <ppolawsk@redhat.com>
+Reviewed-by: Sumit Bose <sbose@redhat.com>
+(cherry picked from commit bd2f38abe95645b9b16b12d12dac6008b0d2a03b)
+
+Reviewed-by: Tomáš Halman <thalman@redhat.com>
+---
+ src/util/domain_info_utils.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
+index 71dfcba02..5a374074b 100644
+--- a/src/util/domain_info_utils.c
++++ b/src/util/domain_info_utils.c
+@@ -207,7 +207,7 @@ find_domain_by_object_name_ex(struct sss_domain_info *domain,
+     ret = sss_parse_internal_fqname(tmp_ctx, object_name,
+                                     NULL, &domainname);
+     if (ret != EOK) {
+-        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name '%s' [%d]: %s\n",
++        DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse name '%s' [%d]: %s\n",
+                                     object_name, ret, sss_strerror(ret));
+         goto done;
+     }
+-- 
+2.26.3
+
diff --git a/SOURCES/0063-sudo-do-not-search-by-low-usn-value-to-improve-perfo.patch b/SOURCES/0063-sudo-do-not-search-by-low-usn-value-to-improve-perfo.patch
new file mode 100644
index 0000000..cfd972d
--- /dev/null
+++ b/SOURCES/0063-sudo-do-not-search-by-low-usn-value-to-improve-perfo.patch
@@ -0,0 +1,122 @@
+From 73f35e5e6836c3d63cfdc4d85dfbfed99f0bcf5a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
+Date: Fri, 29 Jan 2021 12:41:28 +0100
+Subject: [PATCH] sudo: do not search by low usn value to improve performance
+
+This is a follow up on these two commits.
+
+- 819d70ef6e6fa0e736ebd60a7f8a26f672927d57
+- 6815844daa7701c76e31addbbdff74656cd30bea
+
+The first one improved the search filter little bit to achieve better
+performance, however it also changed the behavior: we started to search
+for `usn >= 1` in the filter if no usn number was known.
+
+This caused issues on OpenLDAP server which was fixed by the second patch.
+However, the fix was wrong and searching by this meaningfully low number
+can cause performance issues depending on how the filter is optimized and
+evaluated on the server.
+
+Now we omit the usn attribute from the filter if there is no meaningful value.
+
+How to test:
+1. Setup LDAP with no sudo rules defined
+2. Make sure that the LDAP server does not support USN or use the following diff
+   to enforce modifyTimestamp (last USN is always available from rootDSE)
+```diff
+
+Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
+(cherry picked from commit b100efbfabd96dcfb2825777b75b9a9dfaacb937)
+---
+ src/providers/ldap/sdap.c              |  4 ++--
+ src/providers/ldap/sdap_sudo_refresh.c |  6 ++++--
+ src/providers/ldap/sdap_sudo_shared.c  | 21 ++++++---------------
+ 3 files changed, 12 insertions(+), 19 deletions(-)
+
+diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
+index a1a00df56..0413930bc 100644
+--- a/src/providers/ldap/sdap.c
++++ b/src/providers/ldap/sdap.c
+@@ -1322,7 +1322,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
+     last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name;
+     entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name;
+     if (rootdse) {
+-        if (last_usn_name) {
++        if (false) {
+             ret = sysdb_attrs_get_string(rootdse,
+                                           last_usn_name, &last_usn_value);
+             if (ret != EOK) {
+@@ -1431,7 +1431,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
+         }
+     }
+ 
+-    if (!last_usn_name) {
++    if (true) {
+         DEBUG(SSSDBG_FUNC_DATA,
+               "No known USN scheme is supported by this server!\n");
+         if (!entry_usn_name) {
+diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
+index 5c72c6ec5..fd5deeb7a 100644
+--- a/src/providers/ldap/sdap_sudo_refresh.c
++++ b/src/providers/ldap/sdap_sudo_refresh.c
+@@ -181,8 +181,10 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
+     state->sysdb = id_ctx->be->domain->sysdb;
+ 
+     /* Download all rules from LDAP that are newer than usn */
+-    if (srv_opts == NULL || srv_opts->max_sudo_value == 0) {
+-        DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n");
++    if (srv_opts == NULL || srv_opts->max_sudo_value == NULL
++         || strcmp(srv_opts->max_sudo_value, "0") == 0) {
++        DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero and "
++              "omitting it from the filter.\n");
+         usn = "0";
+         search_filter = talloc_asprintf(state, "(%s=%s)",
+                                         map[SDAP_AT_SUDO_OC].name,
+diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
+index bd3a24da0..5f6afb1ac 100644
+--- a/src/providers/ldap/sdap_sudo_shared.c
++++ b/src/providers/ldap/sdap_sudo_shared.c
+@@ -127,25 +127,17 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
+ static char *
+ sdap_sudo_new_usn(TALLOC_CTX *mem_ctx,
+                   unsigned long usn,
+-                  const char *leftover,
+-                  bool supports_usn)
++                  const char *leftover)
+ {
+     const char *str = leftover == NULL ? "" : leftover;
+     char *newusn;
+ 
+-    /* This is a fresh start and server uses modifyTimestamp. We need to
+-     * provide proper datetime value. */
+-    if (!supports_usn && usn == 0) {
+-        newusn = talloc_strdup(mem_ctx, "00000101000000Z");
+-        if (newusn == NULL) {
+-            DEBUG(SSSDBG_MINOR_FAILURE, "Unable to change USN value (OOM)!\n");
+-            return NULL;
+-        }
+-
+-        return newusn;
++    /* Current largest USN is unknown so we keep "0" to indicate it. */
++    if (usn == 0) {
++        return talloc_strdup(mem_ctx, "0");
+     }
+ 
+-    /* We increment USN number so that we can later use simplify filter
++    /* We increment USN number so that we can later use simplified filter
+      * (just usn >= last+1 instead of usn >= last && usn != last).
+      */
+     usn++;
+@@ -217,8 +209,7 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
+         srv_opts->last_usn = usn_number;
+     }
+ 
+-    newusn = sdap_sudo_new_usn(srv_opts, srv_opts->last_usn, timezone,
+-                               srv_opts->supports_usn);
++    newusn = sdap_sudo_new_usn(srv_opts, srv_opts->last_usn, timezone);
+     if (newusn == NULL) {
+         return;
+     }
+-- 
+2.26.3
+
diff --git a/SOURCES/0064-ldap-fix-modifytimestamp-debugging-leftovers.patch b/SOURCES/0064-ldap-fix-modifytimestamp-debugging-leftovers.patch
new file mode 100644
index 0000000..e985de6
--- /dev/null
+++ b/SOURCES/0064-ldap-fix-modifytimestamp-debugging-leftovers.patch
@@ -0,0 +1,36 @@
+From b816fa19ec6be3c5eb183d1caa03f0153538e2ac Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
+Date: Fri, 12 Feb 2021 15:30:59 +0100
+Subject: [PATCH] ldap: fix modifytimestamp debugging leftovers
+
+Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
+(cherry picked from commit 75343ff575f05a69750a6482de9abc29d85100bf)
+---
+ src/providers/ldap/sdap.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
+index 0413930bc..a1a00df56 100644
+--- a/src/providers/ldap/sdap.c
++++ b/src/providers/ldap/sdap.c
+@@ -1322,7 +1322,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
+     last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name;
+     entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name;
+     if (rootdse) {
+-        if (false) {
++        if (last_usn_name) {
+             ret = sysdb_attrs_get_string(rootdse,
+                                           last_usn_name, &last_usn_value);
+             if (ret != EOK) {
+@@ -1431,7 +1431,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
+         }
+     }
+ 
+-    if (true) {
++    if (!last_usn_name) {
+         DEBUG(SSSDBG_FUNC_DATA,
+               "No known USN scheme is supported by this server!\n");
+         if (!entry_usn_name) {
+-- 
+2.26.3
+
diff --git a/SOURCES/0065-sss_domain_info-add-not_found_counter.patch b/SOURCES/0065-sss_domain_info-add-not_found_counter.patch
new file mode 100644
index 0000000..906cf28
--- /dev/null
+++ b/SOURCES/0065-sss_domain_info-add-not_found_counter.patch
@@ -0,0 +1,67 @@
+From f511e73867f22fff9d0867b07013accb4f44cb1f Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 14 Apr 2021 17:22:06 +0200
+Subject: [PATCH 65/66] sss_domain_info: add not_found_counter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This new counter should be used to track how often a domain could not be
+found while discovering the environment so that it can be deleted after
+a number of failed attempts.
+
+Resolves: https://github.com/SSSD/sssd/issues/5528
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit 5d65411f1aa16af929ae2271ee4d3d9101728a67 with changes)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/confdb/confdb.c       | 1 +
+ src/confdb/confdb.h       | 4 ++++
+ src/db/sysdb_subdomains.c | 2 ++
+ 3 files changed, 7 insertions(+)
+
+diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
+index 97de6d3b1..a33f352e7 100644
+--- a/src/confdb/confdb.c
++++ b/src/confdb/confdb.c
+@@ -1474,6 +1474,7 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
+     domain->view_name = NULL;
+ 
+     domain->state = DOM_ACTIVE;
++    domain->not_found_counter = 0;
+ 
+     *_domain = domain;
+     ret = EOK;
+diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
+index b0d52ba49..a1ac676a6 100644
+--- a/src/confdb/confdb.h
++++ b/src/confdb/confdb.h
+@@ -406,6 +406,10 @@ struct sss_domain_info {
+     /* Do not use the _output_fqnames property directly in new code, but rather
+      * use sss_domain_info_{get,set}_output_fqnames(). */
+     bool output_fqnames;
++
++    /* Counts how often the domain was not found during a refresh of the
++     * domain list */
++    size_t not_found_counter;
+ };
+ 
+ /**
+diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
+index ee3c7f1aa..cbb11342e 100644
+--- a/src/db/sysdb_subdomains.c
++++ b/src/db/sysdb_subdomains.c
+@@ -171,6 +171,8 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
+     dom->homedir_substr = parent->homedir_substr;
+     dom->override_gid = parent->override_gid;
+ 
++    dom->not_found_counter = 0;
++
+     if (parent->sysdb == NULL) {
+         DEBUG(SSSDBG_OP_FAILURE, "Missing sysdb context in parent domain.\n");
+         goto fail;
+-- 
+2.26.3
+
diff --git a/SOURCES/0066-AD-read-trusted-domains-from-local-domain-as-well.patch b/SOURCES/0066-AD-read-trusted-domains-from-local-domain-as-well.patch
new file mode 100644
index 0000000..c735dc4
--- /dev/null
+++ b/SOURCES/0066-AD-read-trusted-domains-from-local-domain-as-well.patch
@@ -0,0 +1,244 @@
+From 2519d5ea3757862bebc17d73d74c7e5c57bdc815 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Tue, 16 Feb 2021 14:30:55 +0100
+Subject: [PATCH 66/66] AD: read trusted domains from local domain as well
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently SSSD only uses information stored in a domain controller of
+the forest root domain to get the names of other trusted domains in the
+forest. Depending on how the forest was created the forest root might
+not have LDAP objects for all domains in the forest. It looks like a
+typical case are child domains of other domains in the forest.
+
+As a start SSSD can now include trusted domains stored in the LDAP tree
+of a local domain controller as well. In a long run it would make sense
+to allow SSSD to explicitly search for domain by looking up DNS entries
+and checking a potential domain controller with a CLDAP ping.
+
+Resolves: https://github.com/SSSD/sssd/issues/5528
+
+:feature: Besides trusted domains known by the forest root, trusted
+          domains known by the local domain are used as well.
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit 95adf488f94f5968f6cfba9e3bef74c07c02ccff)
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/providers/ad/ad_subdomains.c | 105 +++++++++++++++++++++++++------
+ 1 file changed, 86 insertions(+), 19 deletions(-)
+
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index ba4efe975..16aecbc64 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -45,6 +45,7 @@
+ #define AD_AT_TRUST_TYPE    "trustType"
+ #define AD_AT_TRUST_PARTNER "trustPartner"
+ #define AD_AT_TRUST_ATTRS   "trustAttributes"
++#define AD_AT_DOMAIN_NAME   "cn"
+ 
+ /* trustType=2 denotes uplevel (NT5 and later) trusted domains. See
+  * http://msdn.microsoft.com/en-us/library/windows/desktop/ms680342%28v=vs.85%29.aspx
+@@ -56,7 +57,6 @@
+  */
+ #define SLAVE_DOMAIN_FILTER_BASE "(objectclass=trustedDomain)(trustType=2)(!(msDS-TrustForestTrustInfo=*))"
+ #define SLAVE_DOMAIN_FILTER      "(&"SLAVE_DOMAIN_FILTER_BASE")"
+-#define FOREST_ROOT_FILTER_FMT   "(&"SLAVE_DOMAIN_FILTER_BASE"(cn=%s))"
+ 
+ /* Attributes of schema objects. See e.g.
+  * https://docs.microsoft.com/en-us/windows/desktop/AD/characteristics-of-attributes
+@@ -646,6 +646,10 @@ done:
+     return ret;
+ }
+ 
++/* How many times we keep a domain not found during searches before it will be
++ * removed. */
++#define MAX_NOT_FOUND 6
++
+ static errno_t ad_subdomains_refresh(struct be_ctx *be_ctx,
+                                      struct sdap_idmap_ctx *idmap_ctx,
+                                      struct sdap_options *opts,
+@@ -706,6 +710,25 @@ static errno_t ad_subdomains_refresh(struct be_ctx *be_ctx,
+         }
+ 
+         if (c >= num_subdomains) {
++            DEBUG(SSSDBG_CONF_SETTINGS, "Domain [%s] not in current list.\n",
++                                        dom->name);
++            /* Since the forest root might not have trustedDomain objects for
++             * each domain in the forest, especially e.g. for child-domains of
++             * child-domains, we cannot reliable say if a domain is still
++             * present or not.
++             * Maybe it would work to check the crossRef objects in
++             * CN=Partitions,CN=Configuration as well to understand if a
++             * domain is still known in the forest or not.
++             * For the time being we use a counter, if a domain was not found
++             * after multiple attempts it will be deleted. */
++
++            if (dom->not_found_counter++ < MAX_NOT_FOUND) {
++                DEBUG(SSSDBG_TRACE_ALL,
++                      "Domain [%s] was not found [%zu] times.\n", dom->name,
++                      dom->not_found_counter);
++                continue;
++            }
++
+             /* ok this subdomain does not exist anymore, let's clean up */
+             sss_domain_set_state(dom, DOM_DISABLED);
+ 
+@@ -743,6 +766,7 @@ static errno_t ad_subdomains_refresh(struct be_ctx *be_ctx,
+             /* terminate all requests for this subdomain so we can free it */
+             dp_terminate_domain_requests(be_ctx->provider, dom->name);
+             talloc_zfree(sdom);
++
+         } else {
+             /* ok let's try to update it */
+             ret = ad_subdom_enumerates(domain, subdomains[c], &enumerate);
+@@ -750,6 +774,7 @@ static errno_t ad_subdomains_refresh(struct be_ctx *be_ctx,
+                 goto done;
+             }
+ 
++            dom->not_found_counter = 0;
+             ret = ad_subdom_store(be_ctx->cdb, idmap_ctx, domain,
+                                   subdomains[c], enumerate);
+             if (ret) {
+@@ -1310,10 +1335,9 @@ ad_get_root_domain_send(TALLOC_CTX *mem_ctx,
+     struct tevent_req *req;
+     struct sdap_options *opts;
+     errno_t ret;
+-    const char *filter;
+     const char *attrs[] = { AD_AT_FLATNAME, AD_AT_TRUST_PARTNER,
+                             AD_AT_SID, AD_AT_TRUST_TYPE,
+-                            AD_AT_TRUST_ATTRS, NULL };
++                            AD_AT_TRUST_ATTRS, AD_AT_DOMAIN_NAME, NULL };
+ 
+     req = tevent_req_create(mem_ctx, &state, struct ad_get_root_domain_state);
+     if (req == NULL) {
+@@ -1338,15 +1362,10 @@ ad_get_root_domain_send(TALLOC_CTX *mem_ctx,
+     state->domain = domain;
+     state->forest = forest;
+ 
+-    filter = talloc_asprintf(state, FOREST_ROOT_FILTER_FMT, forest);
+-    if (filter == NULL) {
+-        ret = ENOMEM;
+-        goto immediately;
+-    }
+-
+     subreq = sdap_search_bases_return_first_send(state, ev, opts, sh,
+                                                  opts->sdom->search_bases,
+-                                                 NULL, false, 0, filter, attrs,
++                                                 NULL, false, 0,
++                                                 SLAVE_DOMAIN_FILTER, attrs,
+                                                  NULL);
+     if (subreq == NULL) {
+         ret = ENOMEM;
+@@ -1368,11 +1387,33 @@ immediately:
+     return req;
+ }
+ 
++static struct sysdb_attrs *find_domain(size_t count, struct sysdb_attrs **reply,
++                                       const char *dom_name)
++{
++    size_t c;
++    const char *name;
++    int ret;
++
++    for (c = 0; c < count; c++) {
++        ret = sysdb_attrs_get_string(reply[c], AD_AT_DOMAIN_NAME, &name);
++        if (ret != EOK) {
++            DEBUG(SSSDBG_OP_FAILURE, "Failed to find domain name, skipping");
++            continue;
++        }
++        if (strcasecmp(name, dom_name) == 0) {
++            return reply[c];
++        }
++    }
++
++    return NULL;
++}
++
+ static void ad_get_root_domain_done(struct tevent_req *subreq)
+ {
+     struct tevent_req *req;
+     struct ad_get_root_domain_state *state;
+     errno_t ret;
++    bool has_changes = false;
+ 
+     req = tevent_req_callback_data(subreq, struct tevent_req);
+     state = tevent_req_data(req, struct ad_get_root_domain_state);
+@@ -1387,7 +1428,37 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
+         goto done;
+     }
+ 
+-    if (state->reply_count == 0) {
++    find_domain(state->reply_count, state->reply, state->forest);
++
++    if (state->reply_count == 0
++            || find_domain(state->reply_count, state->reply,
++                           state->forest) == NULL) {
++
++        if (state->reply_count > 0) {
++            /* refresh the other domains we have found before checking forest
++             * root */
++            ret = ad_subdomains_refresh(state->be_ctx, state->idmap_ctx,
++                                        state->opts,
++                                        state->reply, state->reply_count, false,
++                                        &state->sd_ctx->last_refreshed,
++                                        &has_changes);
++            if (ret != EOK) {
++                DEBUG(SSSDBG_OP_FAILURE,
++                      "ad_subdomains_refresh failed [%d]: %s\n",
++                      ret, sss_strerror(ret));
++                goto done;
++            }
++
++            if (has_changes) {
++                ret = ad_subdom_reinit(state->sd_ctx);
++                if (ret != EOK) {
++                    DEBUG(SSSDBG_OP_FAILURE,
++                          "Could not reinitialize subdomains\n");
++                    goto done;
++                }
++            }
++        }
++
+         DEBUG(SSSDBG_OP_FAILURE,
+               "No information provided for root domain, trying directly.\n");
+         subreq = ad_check_domain_send(state, state->ev, state->be_ctx,
+@@ -1400,11 +1471,6 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
+         }
+         tevent_req_set_callback(subreq, ad_check_root_domain_done, req);
+         return;
+-    } else if (state->reply_count > 1) {
+-        DEBUG(SSSDBG_CRIT_FAILURE, "Multiple results for root domain search, "
+-              "domain list might be incomplete!\n");
+-        ret = ERR_MALFORMED_ENTRY;
+-        goto done;
+     }
+ 
+     ret = ad_get_root_domain_refresh(state);
+@@ -1522,7 +1588,7 @@ ad_get_root_domain_refresh(struct ad_get_root_domain_state *state)
+     errno_t ret;
+ 
+     ret = ad_subdomains_refresh(state->be_ctx, state->idmap_ctx, state->opts,
+-                                state->reply, state->reply_count, true,
++                                state->reply, state->reply_count, false,
+                                 &state->sd_ctx->last_refreshed,
+                                 &has_changes);
+     if (ret != EOK) {
+@@ -1539,8 +1605,9 @@ ad_get_root_domain_refresh(struct ad_get_root_domain_state *state)
+         }
+     }
+ 
+-    state->root_domain_attrs = state->reply[0];
+-    root_domain = ads_get_root_domain(state->be_ctx, state->reply[0]);
++    state->root_domain_attrs = find_domain(state->reply_count, state->reply,
++                                           state->forest);
++    root_domain = ads_get_root_domain(state->be_ctx, state->root_domain_attrs);
+     if (root_domain == NULL) {
+         DEBUG(SSSDBG_OP_FAILURE, "Could not find the root domain\n");
+         ret = EFAULT;
+-- 
+2.26.3
+
diff --git a/SOURCES/0067-negcache-use-right-domain-in-nss_protocol_fill_initg.patch b/SOURCES/0067-negcache-use-right-domain-in-nss_protocol_fill_initg.patch
new file mode 100644
index 0000000..3a4f404
--- /dev/null
+++ b/SOURCES/0067-negcache-use-right-domain-in-nss_protocol_fill_initg.patch
@@ -0,0 +1,107 @@
+From 48f27f74c9a9d5aebf8d2be941dfb282578ba9ba Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 12 Mar 2021 14:38:54 +0100
+Subject: [PATCH] negcache: use right domain in nss_protocol_fill_initgr()
+
+When checking if a group returned by an initgroups request is filtered
+in the negative cache the domain of the user was used. This does not
+work reliable if the user can be a member of groups from multiple
+domains.
+
+With this patch th domain the group belongs to is determined and used
+while checking the negative cache.
+
+Resolves: https://github.com/SSSD/sssd/issues/5534
+(cherry picked from commit 231d1118727b989a4af9911a45a465912fe659d6 with changes)
+
+Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
+---
+ src/db/sysdb.c                         | 22 ++++++++++++++++++++++
+ src/db/sysdb.h                         |  7 +++++++
+ src/responder/nss/nss_protocol_grent.c |  8 +++++---
+ 3 files changed, 34 insertions(+), 3 deletions(-)
+
+diff --git a/src/db/sysdb.c b/src/db/sysdb.c
+index 279bd5839..f9929c7ba 100644
+--- a/src/db/sysdb.c
++++ b/src/db/sysdb.c
+@@ -1978,3 +1978,25 @@ done:
+     talloc_free(tmp_ctx);
+     return differs;
+ }
++
++struct sss_domain_info *find_domain_by_msg(struct sss_domain_info *dom,
++                                           struct ldb_message *msg)
++{
++    const char *name;
++    struct sss_domain_info *obj_dom = NULL;
++
++    name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
++    if (name == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE,
++              "Object does not have a name attribute.\n");
++        return dom;
++    }
++
++    obj_dom = find_domain_by_object_name(get_domains_head(dom), name);
++    if (obj_dom == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "No domain found for [%s].\n", name);
++        return dom;
++    }
++
++    return obj_dom;
++}
+diff --git a/src/db/sysdb.h b/src/db/sysdb.h
+index 679763bad..d47099eff 100644
+--- a/src/db/sysdb.h
++++ b/src/db/sysdb.h
+@@ -1505,4 +1505,11 @@ errno_t sysdb_handle_original_uuid(const char *orig_name,
+                                    struct sysdb_attrs *dest_attrs,
+                                    const char *dest_name);
+ 
++/* Try to detect the object domain from the object's SYSDB_NAME attribute and
++ * return the matching sss_domain_info. This should work reliable with user
++ * and group objects since fully-qualified names are used here. If the proper
++ * domain cannot be detected the given domain is returned. */
++struct sss_domain_info *find_domain_by_msg(struct sss_domain_info *dom,
++                                           struct ldb_message *msg);
++
+ #endif /* __SYS_DB_H__ */
+diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c
+index 4c7ea9aed..e4494826a 100644
+--- a/src/responder/nss/nss_protocol_grent.c
++++ b/src/responder/nss/nss_protocol_grent.c
+@@ -343,6 +343,7 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
+                          struct cache_req_result *result)
+ {
+     struct sss_domain_info *domain;
++    struct sss_domain_info *grp_dom;
+     struct ldb_message *user;
+     struct ldb_message *msg;
+     struct ldb_message *primary_group_msg;
+@@ -400,10 +401,11 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
+     num_results = 0;
+     for (i = 1; i < result->count; i++) {
+         msg = result->msgs[i];
+-        gid = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, SYSDB_GIDNUM,
++        grp_dom = find_domain_by_msg(domain, msg);
++        gid = sss_view_ldb_msg_find_attr_as_uint64(grp_dom, msg, SYSDB_GIDNUM,
+                                                    0);
+         posix = ldb_msg_find_attr_as_string(msg, SYSDB_POSIX, NULL);
+-        grp_name = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_NAME,
++        grp_name = sss_view_ldb_msg_find_attr_as_string(grp_dom, msg, SYSDB_NAME,
+                                                         NULL);
+ 
+         if (gid == 0) {
+@@ -417,7 +419,7 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
+             }
+         }
+ 
+-        if (is_group_filtered(nss_ctx->rctx->ncache, domain, grp_name, gid)) {
++        if (is_group_filtered(nss_ctx->rctx->ncache, grp_dom, grp_name, gid)) {
+             continue;
+         }
+ 
+-- 
+2.26.3
+
diff --git a/SOURCES/0068-ldap-retry-ldap_install_tls-when-watchdog-interrupti.patch b/SOURCES/0068-ldap-retry-ldap_install_tls-when-watchdog-interrupti.patch
new file mode 100644
index 0000000..9f16683
--- /dev/null
+++ b/SOURCES/0068-ldap-retry-ldap_install_tls-when-watchdog-interrupti.patch
@@ -0,0 +1,180 @@
+From ee16c609497f29731c5a590821d27d0db0ffc91f Mon Sep 17 00:00:00 2001
+From: Iker Pedrosa <ipedrosa@redhat.com>
+Date: Wed, 3 Mar 2021 15:34:49 +0100
+Subject: [PATCH] ldap: retry ldap_install_tls() when watchdog interruption
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When the call to ldap_install_tls() fails because the watchdog
+interrupted it, retry it. The watchdog interruption is detected by
+checking the value of the ticks before and after the call to
+ldap_install_tls().
+
+Resolves: https://github.com/SSSD/sssd/issues/5531
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/providers/ldap/sdap_async_connection.c | 27 +++++++++++++++++++++-
+ src/util/sss_ldap.c                        | 12 ++++++++++
+ src/util/util.h                            |  1 +
+ src/util/util_errors.c                     |  3 +++
+ src/util/util_errors.h                     |  3 +++
+ src/util/util_watchdog.c                   |  5 ++++
+ 6 files changed, 50 insertions(+), 1 deletion(-)
+
+diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
+index afa31ea0f..db963044e 100644
+--- a/src/providers/ldap/sdap_async_connection.c
++++ b/src/providers/ldap/sdap_async_connection.c
+@@ -30,6 +30,8 @@
+ #include "providers/ldap/sdap_async_private.h"
+ #include "providers/ldap/ldap_common.h"
+ 
++#define MAX_RETRY_ATTEMPTS 1
++
+ /* ==Connect-to-LDAP-Server=============================================== */
+ 
+ struct sdap_rebind_proc_params {
+@@ -1447,6 +1449,8 @@ struct sdap_cli_connect_state {
+     enum connect_tls force_tls;
+     bool do_auth;
+     bool use_tls;
++
++    int retry_attempts;
+ };
+ 
+ static int sdap_cli_resolve_next(struct tevent_req *req);
+@@ -1599,16 +1603,37 @@ static void sdap_cli_connect_done(struct tevent_req *subreq)
+     talloc_zfree(state->sh);
+     ret = sdap_connect_recv(subreq, state, &state->sh);
+     talloc_zfree(subreq);
+-    if (ret) {
++    if (ret == ERR_TLS_HANDSHAKE_INTERRUPTED &&
++        state->retry_attempts < MAX_RETRY_ATTEMPTS) {
++        DEBUG(SSSDBG_OP_FAILURE,
++              "TLS handshake was interruped, provider will retry\n");
++        state->retry_attempts++;
++        subreq = sdap_connect_send(state, state->ev, state->opts,
++                                   state->service->uri,
++                                   state->service->sockaddr,
++                                   state->use_tls);
++
++        if (!subreq) {
++            tevent_req_error(req, ENOMEM);
++            return;
++        }
++
++        tevent_req_set_callback(subreq, sdap_cli_connect_done, req);
++        return;
++    } else if (ret != EOK) {
++        state->retry_attempts = 0;
+         /* retry another server */
+         be_fo_set_port_status(state->be, state->service->name,
+                               state->srv, PORT_NOT_WORKING);
++
+         ret = sdap_cli_resolve_next(req);
+         if (ret != EOK) {
+             tevent_req_error(req, ret);
+         }
++
+         return;
+     }
++    state->retry_attempts = 0;
+ 
+     if (state->use_rootdse) {
+         /* fetch the rootDSE this time */
+diff --git a/src/util/sss_ldap.c b/src/util/sss_ldap.c
+index 9d1e95217..652b08ea7 100644
+--- a/src/util/sss_ldap.c
++++ b/src/util/sss_ldap.c
+@@ -234,6 +234,8 @@ static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq)
+     int ret;
+     int lret;
+     int optret;
++    int ticks_before_install;
++    int ticks_after_install;
+ 
+     ret = sssd_async_socket_init_recv(subreq, &state->sd);
+     talloc_zfree(subreq);
+@@ -261,7 +263,9 @@ static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq)
+     }
+ 
+     if (ldap_is_ldaps_url(state->uri)) {
++        ticks_before_install = get_watchdog_ticks();
+         lret = ldap_install_tls(state->ldap);
++        ticks_after_install = get_watchdog_ticks();
+         if (lret != LDAP_SUCCESS) {
+             if (lret == LDAP_LOCAL_ERROR) {
+                 DEBUG(SSSDBG_FUNC_DATA, "TLS/SSL already in place.\n");
+@@ -283,6 +287,14 @@ static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq)
+                                          "Check for certificate issues.");
+                 }
+ 
++                if (ticks_after_install > ticks_before_install) {
++                    ret = ERR_TLS_HANDSHAKE_INTERRUPTED;
++                    DEBUG(SSSDBG_CRIT_FAILURE,
++                          "Assuming %s\n",
++                          sss_ldap_err2string(ret));
++                    goto fail;
++                }
++
+                 ret = EIO;
+                 goto fail;
+             }
+diff --git a/src/util/util.h b/src/util/util.h
+index 486394448..94c2e6e3b 100644
+--- a/src/util/util.h
++++ b/src/util/util.h
+@@ -737,6 +737,7 @@ int sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl);
+ /* from util_watchdog.c */
+ int setup_watchdog(struct tevent_context *ev, int interval);
+ void teardown_watchdog(void);
++int get_watchdog_ticks(void);
+ 
+ /* from files.c */
+ int sss_remove_tree(const char *root);
+diff --git a/src/util/util_errors.c b/src/util/util_errors.c
+index c35a99a54..0eeaa346c 100644
+--- a/src/util/util_errors.c
++++ b/src/util/util_errors.c
+@@ -121,6 +121,9 @@ struct err_string error_to_str[] = {
+     { "The last GetAccountDomain() result is still valid" }, /* ERR_GET_ACCT_DOM_CACHED */
+     { "ID is outside the allowed range" }, /* ERR_ID_OUTSIDE_RANGE */
+     { "Group ID is duplicated" }, /* ERR_GID_DUPLICATED */
++
++    { "TLS handshake was interrupted"}, /* ERR_TLS_HANDSHAKE_INTERRUPTED */
++
+     { "ERR_LAST" } /* ERR_LAST */
+ };
+ 
+diff --git a/src/util/util_errors.h b/src/util/util_errors.h
+index 470f62f9e..366b75650 100644
+--- a/src/util/util_errors.h
++++ b/src/util/util_errors.h
+@@ -143,6 +143,9 @@ enum sssd_errors {
+     ERR_GET_ACCT_DOM_CACHED,
+     ERR_ID_OUTSIDE_RANGE,
+     ERR_GID_DUPLICATED,
++
++    ERR_TLS_HANDSHAKE_INTERRUPTED,
++
+     ERR_LAST            /* ALWAYS LAST */
+ };
+ 
+diff --git a/src/util/util_watchdog.c b/src/util/util_watchdog.c
+index 69160fbdf..7642bfd53 100644
+--- a/src/util/util_watchdog.c
++++ b/src/util/util_watchdog.c
+@@ -259,3 +259,8 @@ void teardown_watchdog(void)
+     /* and kill the watchdog event */
+     talloc_free(watchdog_ctx.te);
+ }
++
++int get_watchdog_ticks(void)
++{
++    return __sync_add_and_fetch(&watchdog_ctx.ticks, 0);
++}
+-- 
+2.26.3
+
diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec
index 18f2e38..a9f72f5 100644
--- a/SPECS/sssd.spec
+++ b/SPECS/sssd.spec
@@ -50,7 +50,7 @@
 
 Name: sssd
 Version: 1.16.5
-Release: 10%{?dist}.7
+Release: 10%{?dist}.8
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -120,6 +120,13 @@ Patch0058: 0058-nss-check-if-groups-are-filtered-during-initgroups.patch
 Patch0059: 0059-CACHE-Create-timestamp-if-missing.patch
 Patch0060: 0060-TESTS-Add-test-for-recreating-cache-timestamp.patch
 Patch0061: 0061-cert-matching.patch
+Patch0062: 0062-UTIL-find_domain_by_object_name_ex-changed-log-level.patch
+Patch0063: 0063-sudo-do-not-search-by-low-usn-value-to-improve-perfo.patch
+Patch0064: 0064-ldap-fix-modifytimestamp-debugging-leftovers.patch
+Patch0065: 0065-sss_domain_info-add-not_found_counter.patch
+Patch0066: 0066-AD-read-trusted-domains-from-local-domain-as-well.patch
+Patch0067: 0067-negcache-use-right-domain-in-nss_protocol_fill_initg.patch
+Patch0068: 0068-ldap-retry-ldap_install_tls-when-watchdog-interrupti.patch
 
 #Those patches should not be removed in RHEL-7
 Patch0999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec
@@ -1295,6 +1302,13 @@ systemctl try-restart sssd >/dev/null 2>&1 || :
 }
 
 %changelog
+* Mon Apr 26 2021 Alexey Tikhonov <atikhono@redhat.com> 1.16.5-10.8
+- Resolves: rhbz#1910131 - sssd throwing error " Unable to parse name test' [1432158283]: The internal name format cannot be parsed" at debug_level 2 [rhel-7.9.z]
+- Resolves: rhbz#1922244 - First smart refresh query contains modifyTimestamp even if the modifyTimestamp is 0. [rhel-7.9.z]
+- Resolves: rhbz#1935685 - SSSD not detecting subdomain from AD forest (7.9z)
+- Resolves: rhbz#1945552 - IPA missing secondary IPA Posix groups in latest sssd 1.16.5-10.el7_9.7 [rhel-7.9.z]
+- Resolves: rhbz#1839972 - Authentication handshake (ldap_install_tls()) fails due to underlying openssl operation failing with EINTR [rhel-7.9.z]
+
 * Thu Dec 10 2020 Alexey Tikhonov <atikhono@redhat.com> 1.16.5-10.7
 - Resolves: rhbz#1875514 - filter_groups option partially filters the group from 'id' output of the user because gidNumber still appears in 'id' output [rhel-7.9.z]
 - Resolves: rhbz#1772513 - SSSD is generating lot of LDAP queries in a very large environment [rhel-7.9.z]