diff --git a/SOURCES/0039-BE_REFRESH-Do-not-try-to-refresh-domains-from-other-.patch b/SOURCES/0039-BE_REFRESH-Do-not-try-to-refresh-domains-from-other-.patch
new file mode 100644
index 0000000..5eeafe6
--- /dev/null
+++ b/SOURCES/0039-BE_REFRESH-Do-not-try-to-refresh-domains-from-other-.patch
@@ -0,0 +1,37 @@
+From 154d73a06f1eb1fda85da54034ad79ba9bcd485b Mon Sep 17 00:00:00 2001
+From: Lukas Slebodnik <lslebodn@redhat.com>
+Date: Wed, 22 Jan 2020 09:43:21 +0000
+Subject: [PATCH] BE_REFRESH: Do not try to refresh domains from other backends
+
+We cannot refresh domains from different sssd_be processes.
+We can refresh just subdomains
+
+Resolves:
+https://pagure.io/SSSD/sssd/issue/4142
+
+Merges: https://pagure.io/SSSD/sssd/pull-request/4139
+
+Reviewed-by: Sumit Bose <sbose@redhat.com>
+(cherry picked from commit 007d5b79b7aef67dd843ed9a3b65095faaeb580f)
+---
+ src/providers/be_refresh.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c
+index 8fcfb86b4..fd63dae66 100644
+--- a/src/providers/be_refresh.c
++++ b/src/providers/be_refresh.c
+@@ -388,6 +388,10 @@ static errno_t be_refresh_step(struct tevent_req *req)
+         if (state->index == BE_REFRESH_TYPE_SENTINEL) {
+             state->domain = get_next_domain(state->domain,
+                                             SSS_GND_DESCEND);
++            /* we can update just subdomains */
++            if (state->domain != NULL && !IS_SUBDOMAIN(state->domain)) {
++                break;
++            }
+             state->index = 0;
+             continue;
+         }
+-- 
+2.21.3
+
diff --git a/SOURCES/0040-UTIL-DN-sanitization.patch b/SOURCES/0040-UTIL-DN-sanitization.patch
new file mode 100644
index 0000000..e2bbb32
--- /dev/null
+++ b/SOURCES/0040-UTIL-DN-sanitization.patch
@@ -0,0 +1,278 @@
+From d0cc9f3b8b8b7aebb4980d1eb7228f0df2051672 Mon Sep 17 00:00:00 2001
+From: Tomas Halman <thalman@redhat.com>
+Date: Fri, 31 Jul 2020 11:12:02 +0200
+Subject: [PATCH 40/41] UTIL: DN sanitization
+
+Some of the ldap servers returns DN in attributes such as isMemberOf
+with spaces like dc=example, dc=com. That should be fine and we
+should ignore them (cut them out) instead of escaping.
+
+Resolves:
+https://github.com/SSSD/sssd/issues/5261
+(cherry picked from commit 882307cdc1b596ba0cc346a0001f4fc014818d82)
+---
+ src/tests/cmocka/test_utils.c |  70 +++++++++++++++++++
+ src/util/util.c               | 127 ++++++++++++++++++++++++++++++++++
+ src/util/util.h               |  20 ++++++
+ 3 files changed, 217 insertions(+)
+
+diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
+index bd2c9e65d..aa245f00b 100644
+--- a/src/tests/cmocka/test_utils.c
++++ b/src/tests/cmocka/test_utils.c
+@@ -1935,6 +1935,73 @@ static void test_sss_get_domain_mappings_content(void **state)
+      * capaths might not be as expected. */
+ }
+ 
++
++static void test_sss_filter_sanitize_dn(void **state)
++{
++    TALLOC_CTX *tmp_ctx;
++    char *trimmed;
++    int ret;
++    const char *DN = "cn=user,ou=people,dc=example,dc=com";
++
++    tmp_ctx = talloc_new(NULL);
++    assert_non_null(tmp_ctx);
++
++    /* test that we remove spaces around '=' and ','*/
++    ret = sss_filter_sanitize_dn(tmp_ctx, DN, &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal(DN, trimmed);
++    talloc_free(trimmed);
++
++    ret = sss_filter_sanitize_dn(tmp_ctx, "cn=user,ou=people,dc=example,dc=com", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal(DN, trimmed);
++    talloc_free(trimmed);
++
++    ret = sss_filter_sanitize_dn(tmp_ctx, "cn= user,ou =people,dc = example,dc  =  com", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal(DN, trimmed);
++    talloc_free(trimmed);
++
++    ret = sss_filter_sanitize_dn(tmp_ctx, "cn=user, ou=people ,dc=example , dc=com", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal(DN, trimmed);
++    talloc_free(trimmed);
++
++    ret = sss_filter_sanitize_dn(tmp_ctx, "cn=user,  ou=people  ,dc=example  ,   dc=com", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal(DN, trimmed);
++    talloc_free(trimmed);
++
++    ret = sss_filter_sanitize_dn(tmp_ctx, "cn= user, ou =people ,dc = example  ,  dc  = com", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal(DN, trimmed);
++    talloc_free(trimmed);
++
++    ret = sss_filter_sanitize_dn(tmp_ctx, " cn=user,ou=people,dc=example,dc=com ", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal(DN, trimmed);
++    talloc_free(trimmed);
++
++    ret = sss_filter_sanitize_dn(tmp_ctx, "  cn=user, ou=people, dc=example, dc=com  ", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal(DN, trimmed);
++    talloc_free(trimmed);
++
++    /* test that we keep spaces inside a value */
++    ret = sss_filter_sanitize_dn(tmp_ctx, "cn = user one, ou=people  branch, dc=example, dc=com", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal("cn=user\\20one,ou=people\\20\\20branch,dc=example,dc=com", trimmed);
++    talloc_free(trimmed);
++
++    /* test that we keep escape special chars like () */
++    ret = sss_filter_sanitize_dn(tmp_ctx, "cn = user one, ou=p(e)ople, dc=example, dc=com", &trimmed);
++    assert_int_equal(ret, EOK);
++    assert_string_equal("cn=user\\20one,ou=p\\28e\\29ople,dc=example,dc=com", trimmed);
++    talloc_free(trimmed);
++
++    talloc_free(tmp_ctx);
++}
++
+ int main(int argc, const char *argv[])
+ {
+     poptContext pc;
+@@ -2044,6 +2111,9 @@ int main(int argc, const char *argv[])
+         cmocka_unit_test_setup_teardown(test_sss_ptr_hash_without_cb,
+                                         setup_leak_tests,
+                                         teardown_leak_tests),
++        cmocka_unit_test_setup_teardown(test_sss_filter_sanitize_dn,
++                                        setup_leak_tests,
++                                        teardown_leak_tests),
+     };
+ 
+     /* Set debug level to invalid value so we can decide if -d 0 was used. */
+diff --git a/src/util/util.c b/src/util/util.c
+index e3efa7fef..4051c1f4e 100644
+--- a/src/util/util.c
++++ b/src/util/util.c
+@@ -530,6 +530,133 @@ errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
+     return sss_filter_sanitize_ex(mem_ctx, input, sanitized, NULL);
+ }
+ 
++
++/* There is similar function ldap_dn_normalize in openldap.
++ * To avoid dependecies across project we have this own func.
++ * Also ldb can do this but doesn't handle all the cases
++ */
++static errno_t sss_trim_dn(TALLOC_CTX *mem_ctx,
++                           const char *input,
++                           char **trimmed)
++{
++    int i = 0;
++    int o = 0;
++    int s;
++    char *output;
++    enum sss_trim_dn_state {
++        SSS_TRIM_DN_STATE_READING_NAME,
++        SSS_TRIM_DN_STATE_READING_VALUE
++    } state = SSS_TRIM_DN_STATE_READING_NAME;
++
++    *trimmed = NULL;
++
++    output = talloc_array(mem_ctx, char, strlen(input) + 1);
++    if (!output) {
++        return ENOMEM;
++    }
++
++    /* skip leading spaces */
++    while(isspace(input[i])) {
++        ++i;
++    }
++
++    while(input[i] != '\0') {
++        if (!isspace(input[i])) {
++            switch (input[i]) {
++            case '=':
++                output[o++] = input[i++];
++                if (state == SSS_TRIM_DN_STATE_READING_NAME) {
++                    while (isspace(input[i])) {
++                        ++i;
++                    }
++                    state = SSS_TRIM_DN_STATE_READING_VALUE;
++                }
++                break;
++            case ',':
++                output[o++] = input[i++];
++                if (state == SSS_TRIM_DN_STATE_READING_VALUE) {
++                    while (isspace(input[i])) {
++                        ++i;
++                    }
++                    state = SSS_TRIM_DN_STATE_READING_NAME;
++                }
++                break;
++            case '\\':
++                output[o++] = input[i++];
++                if (input[i] != '\0') {
++                    output[o++] = input[i++];
++                }
++                break;
++            default:
++                if (input[i] != '\0') {
++                    output[o++] = input[i++];
++                }
++                break;
++            }
++
++            continue;
++        }
++
++        /* non escaped space found */
++        s = 1;
++        while (isspace(input[i + s])) {
++            ++s;
++        }
++
++        switch (state) {
++        case SSS_TRIM_DN_STATE_READING_NAME:
++            if (input[i + s] != '=') {
++                /* this is not trailing space - should not be removed */
++                while (isspace(input[i])) {
++                    output[o++] = input[i++];
++                }
++            } else {
++                i += s;
++            }
++            break;
++        case SSS_TRIM_DN_STATE_READING_VALUE:
++            if (input[i + s] != ',') {
++                /* this is not trailing space - should not be removed */
++                while (isspace(input[i])) {
++                    output[o++] = input[i++];
++                }
++            } else {
++                i += s;
++            }
++            break;
++        }
++    }
++
++    output[o--] = '\0';
++
++    /* trim trailing space */
++    while (o >= 0 && isspace(output[o])) {
++        output[o--] = '\0';
++    }
++
++    *trimmed = output;
++    return EOK;
++}
++
++errno_t sss_filter_sanitize_dn(TALLOC_CTX *mem_ctx,
++                               const char *input,
++                               char **sanitized)
++{
++    errno_t ret;
++    char *trimmed_dn = NULL;
++
++    ret = sss_trim_dn(mem_ctx, input, &trimmed_dn);
++    if (ret != EOK) {
++        goto done;
++    }
++
++    ret = sss_filter_sanitize_ex(mem_ctx, trimmed_dn, sanitized, NULL);
++
++ done:
++    talloc_free(trimmed_dn);
++    return ret;
++}
++
+ char *
+ sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr)
+ {
+diff --git a/src/util/util.h b/src/util/util.h
+index 8dc887cab..d7d2017fa 100644
+--- a/src/util/util.h
++++ b/src/util/util.h
+@@ -477,6 +477,26 @@ errno_t sss_filter_sanitize_for_dom(TALLOC_CTX *mem_ctx,
+                                     char **sanitized,
+                                     char **lc_sanitized);
+ 
++/* Sanitize an input string (e.g. a DN) for use in
++ * an LDAP/LDB filter
++ *
++ * It is basically the same as sss_filter_sanitize(_ex),
++ * just extra spaces inside DN around '=' and ',' are removed
++ * before sanitizing other characters . According the documentation
++ * spaces in DN are allowed and some ldap servers can return them
++ * in isMemberOf or member attributes.
++ *
++ * (dc = my example, dc = com => dc=my\20example,dc=com)
++ *
++ * Returns a newly-constructed string attached to mem_ctx
++ * It will fail only on an out of memory condition, where it
++ * will return ENOMEM.
++ *
++ */
++errno_t sss_filter_sanitize_dn(TALLOC_CTX *mem_ctx,
++                               const char *input,
++                               char **sanitized);
++
+ char *
+ sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr);
+ 
+-- 
+2.21.3
+
diff --git a/SOURCES/0041-UTIL-Use-sss_sanitize_dn-where-we-deal-with-DN.patch b/SOURCES/0041-UTIL-Use-sss_sanitize_dn-where-we-deal-with-DN.patch
new file mode 100644
index 0000000..e5ae271
--- /dev/null
+++ b/SOURCES/0041-UTIL-Use-sss_sanitize_dn-where-we-deal-with-DN.patch
@@ -0,0 +1,121 @@
+From a7edcbca35800ff697c002168b0d566e9563eadf Mon Sep 17 00:00:00 2001
+From: Tomas Halman <thalman@redhat.com>
+Date: Fri, 31 Jul 2020 11:21:44 +0200
+Subject: [PATCH 41/41] UTIL: Use sss_sanitize_dn where we deal with DN
+
+Resolves:
+https://github.com/SSSD/sssd/issues/5261
+(cherry picked from commit 2635e1538a1ef8c01a6587ef3f28ab3367e3459f)
+---
+ src/db/sysdb_ops.c                         | 2 +-
+ src/providers/ipa/ipa_deskprofile_rules.c  | 2 +-
+ src/providers/ipa/ipa_hbac_rules.c         | 2 +-
+ src/providers/ipa/ipa_netgroups.c          | 2 +-
+ src/providers/ldap/sdap_async_groups.c     | 2 +-
+ src/providers/ldap/sdap_async_groups_ad.c  | 2 +-
+ src/providers/ldap/sdap_async_initgroups.c | 4 ++--
+ 7 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
+index b51c821ae..d4ad69e39 100644
+--- a/src/db/sysdb_ops.c
++++ b/src/db/sysdb_ops.c
+@@ -3494,7 +3494,7 @@ errno_t sysdb_search_by_orig_dn(TALLOC_CTX *mem_ctx,
+         return ENOMEM;
+     }
+ 
+-    ret = sss_filter_sanitize(tmp_ctx, member_dn, &sanitized_dn);
++    ret = sss_filter_sanitize_dn(tmp_ctx, member_dn, &sanitized_dn);
+     if (ret != EOK) {
+         goto done;
+     }
+diff --git a/src/providers/ipa/ipa_deskprofile_rules.c b/src/providers/ipa/ipa_deskprofile_rules.c
+index 65994356e..cce6184db 100644
+--- a/src/providers/ipa/ipa_deskprofile_rules.c
++++ b/src/providers/ipa/ipa_deskprofile_rules.c
+@@ -91,7 +91,7 @@ ipa_deskprofile_rule_info_send(TALLOC_CTX *mem_ctx,
+         goto immediate;
+     }
+ 
+-    ret = sss_filter_sanitize(state, host_dn, &host_dn_clean);
++    ret = sss_filter_sanitize_dn(state, host_dn, &host_dn_clean);
+     if (ret != EOK) {
+         goto immediate;
+     }
+diff --git a/src/providers/ipa/ipa_hbac_rules.c b/src/providers/ipa/ipa_hbac_rules.c
+index 0634a277e..e2c97ae3d 100644
+--- a/src/providers/ipa/ipa_hbac_rules.c
++++ b/src/providers/ipa/ipa_hbac_rules.c
+@@ -84,7 +84,7 @@ ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx,
+         goto immediate;
+     }
+ 
+-    ret = sss_filter_sanitize(state, host_dn, &host_dn_clean);
++    ret = sss_filter_sanitize_dn(state, host_dn, &host_dn_clean);
+     if (ret != EOK) goto immediate;
+ 
+     state->ev = ev;
+diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c
+index 05ebac758..e14f48fb0 100644
+--- a/src/providers/ipa/ipa_netgroups.c
++++ b/src/providers/ipa/ipa_netgroups.c
+@@ -376,7 +376,7 @@ static void ipa_get_netgroups_process(struct tevent_req *subreq)
+             continue;
+         }
+ 
+-        ret = sss_filter_sanitize(state, orig_dn, &dn);
++        ret = sss_filter_sanitize_dn(state, orig_dn, &dn);
+         if (ret != EOK) {
+             goto done;
+         }
+diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
+index 09e15bc3d..abe2ed275 100644
+--- a/src/providers/ldap/sdap_async_groups.c
++++ b/src/providers/ldap/sdap_async_groups.c
+@@ -52,7 +52,7 @@ static int sdap_find_entry_by_origDN(TALLOC_CTX *memctx,
+         return ENOMEM;
+     }
+ 
+-    ret = sss_filter_sanitize(tmpctx, orig_dn, &sanitized_dn);
++    ret = sss_filter_sanitize_dn(tmpctx, orig_dn, &sanitized_dn);
+     if (ret != EOK) {
+         ret = ENOMEM;
+         goto done;
+diff --git a/src/providers/ldap/sdap_async_groups_ad.c b/src/providers/ldap/sdap_async_groups_ad.c
+index 3f842b26d..c954398bb 100644
+--- a/src/providers/ldap/sdap_async_groups_ad.c
++++ b/src/providers/ldap/sdap_async_groups_ad.c
+@@ -91,7 +91,7 @@ sdap_get_ad_match_rule_members_send(TALLOC_CTX *mem_ctx,
+     }
+ 
+     /* Sanitize it in case we have special characters in DN */
+-    ret = sss_filter_sanitize(state, group_dn, &sanitized_group_dn);
++    ret = sss_filter_sanitize_dn(state, group_dn, &sanitized_group_dn);
+     if (ret != EOK) {
+         DEBUG(SSSDBG_MINOR_FAILURE,
+               "Could not sanitize group DN: %s\n",
+diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
+index 620782b6f..055bdaefc 100644
+--- a/src/providers/ldap/sdap_async_initgroups.c
++++ b/src/providers/ldap/sdap_async_initgroups.c
+@@ -1647,7 +1647,7 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
+                                attr_filter, &state->attrs, NULL);
+     if (ret != EOK) goto done;
+ 
+-    ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn);
++    ret = sss_filter_sanitize_dn(state, orig_dn, &clean_orig_dn);
+     if (ret != EOK) goto done;
+ 
+     use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
+@@ -2429,7 +2429,7 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
+         goto done;
+     }
+ 
+-    ret = sss_filter_sanitize(tmp_ctx, state->orig_dn, &clean_orig_dn);
++    ret = sss_filter_sanitize_dn(tmp_ctx, state->orig_dn, &clean_orig_dn);
+     if (ret != EOK) {
+         goto done;
+     }
+-- 
+2.21.3
+
diff --git a/SOURCES/0042-UTIL-Use-sss_sanitize_dn-where-we-deal-with-DN-2.patch b/SOURCES/0042-UTIL-Use-sss_sanitize_dn-where-we-deal-with-DN-2.patch
new file mode 100644
index 0000000..b410846
--- /dev/null
+++ b/SOURCES/0042-UTIL-Use-sss_sanitize_dn-where-we-deal-with-DN-2.patch
@@ -0,0 +1,63 @@
+From 63bc622a1c6558f7dd51645031f95d0890aeec7c Mon Sep 17 00:00:00 2001
+From: Tomas Halman <thalman@redhat.com>
+Date: Wed, 19 Aug 2020 15:17:44 +0200
+Subject: [PATCH] UTIL: Use sss_sanitize_dn where we deal with DN 2
+
+Tests show that also ldb_dn_get_linearized can
+return DN with extra spaces. We have to trim that too.
+
+Resolves:
+https://github.com/SSSD/sssd/issues/5261
+(cherry picked from commit 12bbd26e6c551d59793ba9a02a1d7cae4062f189)
+---
+ src/ldb_modules/memberof.c           | 6 +++---
+ src/providers/ldap/ldap_id_cleanup.c | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/ldb_modules/memberof.c b/src/ldb_modules/memberof.c
+index dae51938b..5de3b7c3b 100644
+--- a/src/ldb_modules/memberof.c
++++ b/src/ldb_modules/memberof.c
+@@ -1364,7 +1364,7 @@ static int memberof_del(struct ldb_module *module, struct ldb_request *req)
+         return LDB_ERR_OPERATIONS_ERROR;
+     }
+ 
+-    sret = sss_filter_sanitize(del_ctx, dn, &clean_dn);
++    sret = sss_filter_sanitize_dn(del_ctx, dn, &clean_dn);
+     if (sret != 0) {
+         talloc_free(ctx);
+         return LDB_ERR_OPERATIONS_ERROR;
+@@ -1781,7 +1781,7 @@ static int mbof_del_execute_op(struct mbof_del_operation *delop)
+         return LDB_ERR_OPERATIONS_ERROR;
+     }
+ 
+-    ret = sss_filter_sanitize(del_ctx, dn, &clean_dn);
++    ret = sss_filter_sanitize_dn(del_ctx, dn, &clean_dn);
+     if (ret != 0) {
+         return LDB_ERR_OPERATIONS_ERROR;
+     }
+@@ -3054,7 +3054,7 @@ static int mbof_get_ghost_from_parent(struct mbof_mod_del_op *igh)
+         return LDB_ERR_OPERATIONS_ERROR;
+     }
+ 
+-    ret = sss_filter_sanitize(igh, dn, &clean_dn);
++    ret = sss_filter_sanitize_dn(igh, dn, &clean_dn);
+     if (ret != 0) {
+         return LDB_ERR_OPERATIONS_ERROR;
+     }
+diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c
+index 8c0f0c18b..cd10126f4 100644
+--- a/src/providers/ldap/ldap_id_cleanup.c
++++ b/src/providers/ldap/ldap_id_cleanup.c
+@@ -422,7 +422,7 @@ static int cleanup_groups(TALLOC_CTX *memctx,
+         }
+ 
+         /* sanitize dn */
+-        ret = sss_filter_sanitize(tmpctx, dn, &sanitized_dn);
++        ret = sss_filter_sanitize_dn(tmpctx, dn, &sanitized_dn);
+         if (ret != EOK) {
+             DEBUG(SSSDBG_MINOR_FAILURE,
+                   "sss_filter_sanitize failed: %s:[%d]\n",
+-- 
+2.21.3
+
diff --git a/SOURCES/0043-ldap-use-member-DN-to-create-ghost-user-hash-table.patch b/SOURCES/0043-ldap-use-member-DN-to-create-ghost-user-hash-table.patch
new file mode 100644
index 0000000..7dad92a
--- /dev/null
+++ b/SOURCES/0043-ldap-use-member-DN-to-create-ghost-user-hash-table.patch
@@ -0,0 +1,123 @@
+From 4d6be3c36169c954c4d61399607fde229902cb07 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 26 Aug 2020 15:40:53 +0200
+Subject: [PATCH] ldap: use member DN to create ghost user hash table
+
+---
+ src/db/sysdb.h                                |  1 +
+ src/providers/ldap/sdap.c                     | 10 ++++++++++
+ src/providers/ldap/sdap_async_groups.c        | 17 +++++++++++++++-
+ src/providers/ldap/sdap_async_nested_groups.c | 20 +++++++++++++++++--
+ 4 files changed, 45 insertions(+), 3 deletions(-)
+
+diff --git a/src/db/sysdb.h b/src/db/sysdb.h
+index a2bc8ed3b..679763bad 100644
+--- a/src/db/sysdb.h
++++ b/src/db/sysdb.h
+@@ -129,6 +129,7 @@
+ #define SYSDB_UPN "userPrincipalName"
+ #define SYSDB_CANONICAL_UPN "canonicalUserPrincipalName"
+ #define SYSDB_CCACHE_FILE "ccacheFile"
++#define SYSDB_DN_FOR_MEMBER_HASH_TABLE "dnForMemberHashTable"
+ 
+ #define SYSDB_ORIG_DN "originalDN"
+ #define SYSDB_ORIG_MODSTAMP "originalModifyTimestamp"
+diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
+index a9c8b92b8..a1a00df56 100644
+--- a/src/providers/ldap/sdap.c
++++ b/src/providers/ldap/sdap.c
+@@ -771,6 +771,16 @@ errno_t sdap_parse_deref(TALLOC_CTX *mem_ctx,
+             goto done;
+         }
+ 
++        /* The dereference control seems to return the DN from the dereference
++         * attribute (e.g. member) so we can use it as key for the hash table
++         * later. */
++        ret = sysdb_attrs_add_string(res[mi]->attrs,
++                                     SYSDB_DN_FOR_MEMBER_HASH_TABLE, orig_dn);
++        if (ret) {
++            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n");
++            goto done;
++        }
++
+         for (dval = dref->attrVals; dval != NULL; dval = dval->next) {
+             DEBUG(SSSDBG_TRACE_INTERNAL,
+                   "Dereferenced attribute: %s\n", dval->type);
+diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
+index abe2ed275..4e3c524a4 100644
+--- a/src/providers/ldap/sdap_async_groups.c
++++ b/src/providers/ldap/sdap_async_groups.c
+@@ -2509,6 +2509,7 @@ static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx,
+     struct ldb_message_element *el;
+     const char *username;
+     const char *original_dn;
++    const char *hash_key_dn;
+     struct sss_domain_info *user_dom;
+     struct sdap_domain *sdap_dom;
+ 
+@@ -2607,8 +2608,22 @@ static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx,
+                                        SYSDB_MOD_REP);
+             if (ret != EOK) goto done;
+         } else {
++            /* The DN of the user object and the DN in the member attribute
++             * might differ, e.g. in case. Since we later search the hash with
++             * DNs from the member attribute we should try to use DN from the
++             * member attribute here as well. This should be added earlier in
++             * the SYSDB_DN_FOR_MEMBER_HASH_TABLE attribute. If this does not
++             * exists we fall-back to original_dn which should work in the
++             * most cases as well. */
++            ret = sysdb_attrs_get_string(users[i],
++                                         SYSDB_DN_FOR_MEMBER_HASH_TABLE,
++                                         &hash_key_dn);
++            if (ret != EOK) {
++                hash_key_dn = original_dn;
++            }
++
+             key.type = HASH_KEY_STRING;
+-            key.str = talloc_steal(ghosts, discard_const(original_dn));
++            key.str = talloc_steal(ghosts, discard_const(hash_key_dn));
+             value.type = HASH_VALUE_PTR;
+             /* Already qualified from sdap_get_user_primary_name() */
+             value.ptr = talloc_steal(ghosts, discard_const(username));
+diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
+index 055de29ca..635b46403 100644
+--- a/src/providers/ldap/sdap_async_nested_groups.c
++++ b/src/providers/ldap/sdap_async_nested_groups.c
+@@ -241,9 +241,12 @@ static errno_t sdap_nested_group_hash_entry(hash_table_t *table,
+     const char *name = NULL;
+     errno_t ret;
+ 
+-    ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name);
++    ret = sysdb_attrs_get_string(entry, SYSDB_DN_FOR_MEMBER_HASH_TABLE, &name);
+     if (ret != EOK) {
+-        return ret;
++        ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name);
++        if (ret != EOK) {
++            return ret;
++        }
+     }
+ 
+     return sdap_nested_group_hash_insert(table, name, entry, false, table_name);
+@@ -1495,6 +1498,19 @@ sdap_nested_group_single_step_process(struct tevent_req *subreq)
+             }
+         }
+ 
++        /* The original DN of the user object itself might differ from the one
++         * used inthe member attribute, e.g. different case. To make sure if
++         * can be found in a hash table when iterating over group members the
++         * DN from the member attribute used for the search as saved as well.
++         */
++        ret = sysdb_attrs_add_string(entry,
++                                     SYSDB_DN_FOR_MEMBER_HASH_TABLE,
++                                     state->current_member->dn);
++        if (ret != EOK) {
++            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n");
++            goto done;
++        }
++
+         /* save user in hash table */
+         ret = sdap_nested_group_hash_user(state->group_ctx, entry);
+         if (ret == EEXIST) {
+-- 
+2.21.3
+
diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec
index 50e2eb2..5a57ad9 100644
--- a/SPECS/sssd.spec
+++ b/SPECS/sssd.spec
@@ -50,7 +50,7 @@
 
 Name: sssd
 Version: 1.16.5
-Release: 10%{?dist}
+Release: 10%{?dist}.5
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -97,6 +97,11 @@ Patch0035: 0035-ad-add-ad_check_domain_-send-recv.patch
 Patch0036: 0036-ad-check-forest-root-directly-if-not-present-on-loca.patch
 Patch0037: 0037-pam_sss-add-SERVICE_IS_GDM_SMARTCARD.patch
 Patch0038: 0038-pam_sss-special-handling-for-gdm-smartcard.patch
+Patch0039: 0039-BE_REFRESH-Do-not-try-to-refresh-domains-from-other-.patch
+Patch0040: 0040-UTIL-DN-sanitization.patch
+Patch0041: 0041-UTIL-Use-sss_sanitize_dn-where-we-deal-with-DN.patch
+Patch0042: 0042-UTIL-Use-sss_sanitize_dn-where-we-deal-with-DN-2.patch
+Patch0043: 0043-ldap-use-member-DN-to-create-ghost-user-hash-table.patch
 
 #Those patches should not be removed in RHEL-7
 Patch0999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec
@@ -1271,6 +1276,28 @@ systemctl try-restart sssd >/dev/null 2>&1 || :
 }
 
 %changelog
+* Fri Aug 28 2020 Alexey Tikhonov <Alexey Tikhonov> 1.16.5-10.5
+- Resolves: rhbz#1859554 - Secondary LDAP group go missing from 'id' command on RHEL 7.8 with sssd-1.16.2-37.el7_8.1 [rhel-7.9.z]
+  (Previous attempt to fix this issue was incomplete (again))
+- just bumping the version to build for proper target
+
+* Fri Aug 28 2020 Alexey Tikhonov <Alexey Tikhonov> 1.16.5-10.4
+- Resolves: rhbz#1859554 - Secondary LDAP group go missing from 'id' command on RHEL 7.8 with sssd-1.16.2-37.el7_8.1 [rhel-7.9.z]
+  (Previous attempt to fix this issue was incomplete (again))
+
+* Wed Aug 19 2020 Alexey Tikhonov <Alexey Tikhonov> 1.16.5-10.3
+- Resolves: rhbz#1859554 - Secondary LDAP group go missing from 'id' command on RHEL 7.8 with sssd-1.16.2-37.el7_8.1 [rhel-7.9.z]
+  (Previous attempt to fix this issue was incomplete)
+
+* Tue Aug 18 2020 Alexey Tikhonov <Alexey Tikhonov> 1.16.5-10.2
+- Resolves: rhbz#1854317 - sssd crashes after last update to sssd-common-1.16.4-37.el7_8.1 with servers configured with multiple domains [rhel-7.9.z]
+- Resolves: rhbz#1859554 - Secondary LDAP group go missing from 'id' command on RHEL 7.8 with sssd-1.16.2-37.el7_8.1 [rhel-7.9.z]
+- just bumping the version to build for proper target
+
+* Tue Aug 18 2020 Alexey Tikhonov <Alexey Tikhonov> 1.16.5-10.1
+- Resolves: rhbz#1854317 - sssd crashes after last update to sssd-common-1.16.4-37.el7_8.1 with servers configured with multiple domains [rhel-7.9.z]
+- Resolves: rhbz#1859554 - Secondary LDAP group go missing from 'id' command on RHEL 7.8 with sssd-1.16.2-37.el7_8.1 [rhel-7.9.z]
+
 * Fri Jun 05 2020 Alexey Tikhonov <Alexey Tikhonov> 1.16.5-10
 - Resolves: rhbz#1804005 - sssd doesn't follow the link order of AD Group Policy Management
 - Resolves: rhbz#1773409 - sssd is failing to discover other subdomains in the forest if LDAP entries do not contain AD forest root information