diff --git a/SOURCES/0003-ad-filter-trusted-domains.patch b/SOURCES/0003-ad-filter-trusted-domains.patch
new file mode 100644
index 0000000..7f8afc3
--- /dev/null
+++ b/SOURCES/0003-ad-filter-trusted-domains.patch
@@ -0,0 +1,187 @@
+From 4c48c4a7792961cf8a228c76975ac370d32904e1 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Wed, 6 Oct 2021 13:03:27 +0200
+Subject: [PATCH] ad: filter trusted domains
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The fix for https://github.com/SSSD/sssd/issues/5528 might discover
+domains which are not trusted (one-way trust) or are from a different
+forest (direct trust). Both should be ignored because they are not
+trusted or can currently not be handled properly. This patch filters out
+those domains.
+
+Resolves: https://github.com/SSSD/sssd/issues/5819
+
+Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/providers/ad/ad_subdomains.c | 104 +++++++++++++++++++++++++++++--
+ 1 file changed, 99 insertions(+), 5 deletions(-)
+
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index 3eb49c93f..ac463026f 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -46,6 +46,7 @@
+ #define AD_AT_TRUST_PARTNER "trustPartner"
+ #define AD_AT_TRUST_ATTRS   "trustAttributes"
+ #define AD_AT_DOMAIN_NAME   "cn"
++#define AD_AT_TRUST_DIRECTION   "trustDirection"
+ 
+ /* 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
+@@ -69,6 +70,12 @@
+ /* do not refresh more often than every 5 seconds for now */
+ #define AD_SUBDOMAIN_REFRESH_LIMIT 5
+ 
++/* Flags of trustAttributes attribute, see MS-ADTS 6.1.6.7.9 for details */
++#define TRUST_ATTRIBUTE_WITHIN_FOREST 0x00000020
++
++/* Flags for trustDirection attribute, see MS-ADTS 6.1.6.7.12 for details */
++#define TRUST_DIRECTION_OUTBOUND 0x00000002
++
+ static void
+ ad_disable_gc(struct ad_options *ad_options)
+ {
+@@ -646,6 +653,85 @@ done:
+     return ret;
+ }
+ 
++/* When reading trusted domains from the local DC we are basically interested
++ * in domains from the local forest we are trusting, i.e. users from this
++ * domain can connect to us. To not unnecessarily bloat the list of domains
++ * and make multi-domain searches slow we filter domains from other forest and
++ * domains we do not trust.
++ * In future we might add config options to broaden the scope and allow more
++ * domains.
++ * If ad_filter_domains() returns successfully with EOK in input array is not
++ * valid anymore and should be freed by the caller. */
++static errno_t ad_filter_domains(TALLOC_CTX *mem_ctx,
++                                 struct sysdb_attrs **subdomains,
++                                 size_t num_subdomains,
++                                 struct sysdb_attrs ***_sd_out,
++                                 size_t *_num_sd_out)
++{
++    int ret;
++    size_t c;
++    uint32_t tmp_uint32_t;
++    const char *value;
++    struct sysdb_attrs **sd_out;
++    size_t num_sd_out = 0;
++
++    sd_out = talloc_zero_array(mem_ctx, struct sysdb_attrs *,
++                               num_subdomains + 1);
++    if (sd_out == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE,
++              "Failed to allocate memory for sub-domain list.\n");
++        return ENOMEM;
++    }
++
++    for (c = 0; c < num_subdomains; c++) {
++        ret = sysdb_attrs_get_string(subdomains[c], AD_AT_TRUST_PARTNER,
++                                     &value);
++        if (ret != EOK) {
++            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
++            talloc_free(sd_out);
++            return ret;
++        }
++
++        /* Ignore direct trusts to domains from other forests
++         * (TRUST_ATTRIBUTE_WITHIN_FOREST is not set) or domains we do not
++         * trust (TRUST_DIRECTION_OUTBOUND is not set) */
++
++        tmp_uint32_t = 0;
++        ret = sysdb_attrs_get_uint32_t(subdomains[c], AD_AT_TRUST_ATTRS,
++                                       &tmp_uint32_t);
++        if (ret != EOK
++                || (tmp_uint32_t & TRUST_ATTRIBUTE_WITHIN_FOREST) == 0) {
++            DEBUG(SSSDBG_FUNC_DATA,
++                  "TRUST_ATTRIBUTE_WITHIN_FOREST not set for [%s].\n",
++                  value);
++            continue;
++        }
++
++        tmp_uint32_t = 0;
++        ret = sysdb_attrs_get_uint32_t(subdomains[c], AD_AT_TRUST_DIRECTION,
++                                       &tmp_uint32_t);
++        if (ret != EOK
++                || (tmp_uint32_t & TRUST_DIRECTION_OUTBOUND) == 0) {
++            DEBUG(SSSDBG_FUNC_DATA,
++                  "TRUST_DIRECTION_OUTBOUND not set for [%s].\n",
++                  value);
++            continue;
++        }
++
++        sd_out[num_sd_out] = subdomains[c];
++        num_sd_out++;
++    }
++
++    for (c = 0; c < num_sd_out; c++) {
++        sd_out[c] = talloc_steal(sd_out, sd_out[c]);
++    }
++
++    *_sd_out = sd_out;
++    *_num_sd_out = num_sd_out;
++
++    return EOK;
++}
++
+ /* How many times we keep a domain not found during searches before it will be
+  * removed. */
+ #define MAX_NOT_FOUND 6
+@@ -1125,7 +1211,7 @@ static void ad_get_slave_domain_connect_done(struct tevent_req *subreq)
+     errno_t ret;
+     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_TRUST_DIRECTION, NULL };
+ 
+     req = tevent_req_callback_data(subreq, struct tevent_req);
+     state = tevent_req_data(req, struct ad_get_slave_domain_state);
+@@ -1333,7 +1419,7 @@ ad_get_root_domain_send(TALLOC_CTX *mem_ctx,
+     struct sdap_options *opts;
+     errno_t ret;
+     const char *attrs[] = { AD_AT_FLATNAME, AD_AT_TRUST_PARTNER,
+-                            AD_AT_SID, AD_AT_TRUST_TYPE,
++                            AD_AT_SID, AD_AT_TRUST_TYPE, AD_AT_TRUST_DIRECTION,
+                             AD_AT_TRUST_ATTRS, AD_AT_DOMAIN_NAME, NULL };
+ 
+     req = tevent_req_create(mem_ctx, &state, struct ad_get_root_domain_state);
+@@ -1411,13 +1497,15 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
+     struct ad_get_root_domain_state *state;
+     errno_t ret;
+     bool has_changes = false;
++    struct sysdb_attrs **unfiltered_reply;
++    size_t unfiltered_reply_count;
+ 
+     req = tevent_req_callback_data(subreq, struct tevent_req);
+     state = tevent_req_data(req, struct ad_get_root_domain_state);
+ 
+     ret = sdap_search_bases_return_first_recv(subreq, state,
+-                                              &state->reply_count,
+-                                              &state->reply);
++                                              &unfiltered_reply_count,
++                                              &unfiltered_reply);
+     talloc_zfree(subreq);
+     if (ret != EOK) {
+         DEBUG(SSSDBG_OP_FAILURE, "Unable to lookup forest root information "
+@@ -1425,7 +1513,13 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
+         goto done;
+     }
+ 
+-    find_domain(state->reply_count, state->reply, state->forest);
++    ret = ad_filter_domains(state, unfiltered_reply, unfiltered_reply_count,
++                            &state->reply, &state->reply_count);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE,
++              "Failed to filter list of returned domains.\n");
++        goto done;
++    }
+ 
+     if (state->reply_count == 0
+             || find_domain(state->reply_count, state->reply,
+-- 
+2.26.3
+
diff --git a/SOURCES/0004-cache_req-return-success-for-autofs-when-ENOENT-is-r.patch b/SOURCES/0004-cache_req-return-success-for-autofs-when-ENOENT-is-r.patch
new file mode 100644
index 0000000..acaf14c
--- /dev/null
+++ b/SOURCES/0004-cache_req-return-success-for-autofs-when-ENOENT-is-r.patch
@@ -0,0 +1,62 @@
+From bb94a18f0f0cba1e9fb5abf78b995d69e5f3c559 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
+Date: Mon, 18 Oct 2021 12:29:06 +0200
+Subject: [PATCH] cache_req: return success for autofs when ENOENT is returned
+ from provider
+
+The receive function should return true if data provider lookup was
+successfull and false if there was an error. "Not found" result is
+considered a successful lookup, only failure to perform a search
+should result in false return code.
+
+Resolves: https://github.com/SSSD/sssd/issues/5832
+
+Reviewed-by: Pawel Polawski <ppolawsk@redhat.com>
+---
+ .../common/cache_req/plugins/cache_req_autofs_entry_by_name.c   | 2 +-
+ .../common/cache_req/plugins/cache_req_autofs_map_by_name.c     | 2 +-
+ .../common/cache_req/plugins/cache_req_autofs_map_entries.c     | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/responder/common/cache_req/plugins/cache_req_autofs_entry_by_name.c b/src/responder/common/cache_req/plugins/cache_req_autofs_entry_by_name.c
+index 0dc6a585a..788b6708c 100644
+--- a/src/responder/common/cache_req/plugins/cache_req_autofs_entry_by_name.c
++++ b/src/responder/common/cache_req/plugins/cache_req_autofs_entry_by_name.c
+@@ -97,7 +97,7 @@ cache_req_autofs_entry_by_name_dp_recv(struct tevent_req *subreq,
+ 
+     ret = sbus_call_dp_autofs_GetEntry_recv(subreq);
+ 
+-    if (ret == ERR_MISSING_DP_TARGET) {
++    if (ret == ERR_MISSING_DP_TARGET || ret == ENOENT) {
+         ret = EOK;
+     }
+ 
+diff --git a/src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c b/src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c
+index 6a665c58e..5d82641cc 100644
+--- a/src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c
++++ b/src/responder/common/cache_req/plugins/cache_req_autofs_map_by_name.c
+@@ -93,7 +93,7 @@ cache_req_autofs_map_by_name_dp_recv(struct tevent_req *subreq,
+ 
+     ret = sbus_call_dp_autofs_GetMap_recv(subreq);
+ 
+-    if (ret == ERR_MISSING_DP_TARGET) {
++    if (ret == ERR_MISSING_DP_TARGET || ret == ENOENT) {
+         ret = EOK;
+     }
+ 
+diff --git a/src/responder/common/cache_req/plugins/cache_req_autofs_map_entries.c b/src/responder/common/cache_req/plugins/cache_req_autofs_map_entries.c
+index 46776b980..29f289723 100644
+--- a/src/responder/common/cache_req/plugins/cache_req_autofs_map_entries.c
++++ b/src/responder/common/cache_req/plugins/cache_req_autofs_map_entries.c
+@@ -125,7 +125,7 @@ cache_req_autofs_map_entries_dp_recv(struct tevent_req *subreq,
+ 
+     ret = sbus_call_dp_autofs_Enumerate_recv(subreq);
+ 
+-    if (ret == ERR_MISSING_DP_TARGET) {
++    if (ret == ERR_MISSING_DP_TARGET || ret == ENOENT) {
+         ret = EOK;
+     }
+ 
+-- 
+2.26.3
+
diff --git a/SOURCES/0005-MONITOR-reduce-logs-severity-around-signalling-and-t.patch b/SOURCES/0005-MONITOR-reduce-logs-severity-around-signalling-and-t.patch
new file mode 100644
index 0000000..62083f5
--- /dev/null
+++ b/SOURCES/0005-MONITOR-reduce-logs-severity-around-signalling-and-t.patch
@@ -0,0 +1,81 @@
+From 01ff8155baea989c42664985ea939cb93beb31e7 Mon Sep 17 00:00:00 2001
+From: Alexey Tikhonov <atikhono@redhat.com>
+Date: Fri, 1 Oct 2021 18:01:21 +0200
+Subject: [PATCH] MONITOR: reduce logs severity around signalling and
+ termination of services to avoid useless in those cases backtraces
+
+Reviewed-by: Sumit Bose <sbose@redhat.com>
+---
+ src/monitor/monitor.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
+index 42def7451..b5fee7e7a 100644
+--- a/src/monitor/monitor.c
++++ b/src/monitor/monitor.c
+@@ -655,7 +655,7 @@ static int service_signal(struct mt_svc *svc,
+          * order a service to reload that hasn't started
+          * yet.
+          */
+-        DEBUG(SSSDBG_CRIT_FAILURE,
++        DEBUG(SSSDBG_IMPORTANT_INFO,
+               "Could not signal service [%s].\n", svc->name);
+         return EIO;
+     }
+@@ -684,8 +684,8 @@ static void service_signal_done(struct tevent_req *req)
+         return;
+     }
+ 
+-    DEBUG(SSSDBG_FATAL_FAILURE, "Unable to signal service [%d]: %s\n",
+-          ret, sss_strerror(ret));
++    DEBUG(ret == ENOENT ? SSSDBG_MINOR_FAILURE : SSSDBG_OP_FAILURE,
++          "Unable to signal service [%d]: %s\n", ret, sss_strerror(ret));
+ }
+ 
+ static int service_signal_dns_reload(struct mt_svc *svc)
+@@ -1363,14 +1363,14 @@ static void monitor_quit(struct mt_ctx *mt_ctx, int ret)
+         }
+ 
+         killed = false;
+-        DEBUG(SSSDBG_CRIT_FAILURE,
++        DEBUG(SSSDBG_IMPORTANT_INFO,
+               "Terminating [%s][%d]\n", svc->name, svc->pid);
+         do {
+             errno = 0;
+             kret = kill(-svc->pid, SIGTERM);
+             if (kret < 0) {
+                 error = errno;
+-                DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't kill [%s][%d]: [%s]\n",
++                DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't terminate [%s][%d]: [%s]\n",
+                           svc->name, svc->pid, strerror(error));
+             }
+ 
+@@ -1384,7 +1384,7 @@ static void monitor_quit(struct mt_ctx *mt_ctx, int ret)
+                     if (error == ECHILD) {
+                         killed = true;
+                     } else if (error != EINTR) {
+-                        DEBUG(SSSDBG_FATAL_FAILURE,
++                        DEBUG(SSSDBG_IMPORTANT_INFO,
+                               "[%d][%s] while waiting for [%s]\n",
+                                   error, strerror(error), svc->name);
+                         /* Forcibly kill this child */
+@@ -1394,13 +1394,13 @@ static void monitor_quit(struct mt_ctx *mt_ctx, int ret)
+                 } else if (pid != 0) {
+                     error = 0;
+                     if (WIFEXITED(status)) {
+-                        DEBUG(SSSDBG_CRIT_FAILURE,
++                        DEBUG(SSSDBG_IMPORTANT_INFO,
+                               "Child [%s] exited gracefully\n", svc->name);
+                     } else if (WIFSIGNALED(status)) {
+-                        DEBUG(SSSDBG_CRIT_FAILURE,
++                        DEBUG(SSSDBG_IMPORTANT_INFO,
+                               "Child [%s] terminated with a signal\n", svc->name);
+                     } else {
+-                        DEBUG(SSSDBG_CRIT_FAILURE,
++                        DEBUG(SSSDBG_IMPORTANT_INFO,
+                               "Child [%s] did not exit cleanly\n", svc->name);
+                         /* Forcibly kill this child */
+                         kill(-svc->pid, SIGKILL);
+-- 
+2.26.3
+
diff --git a/SOURCES/0006-DEBUG-avoid-backtrace-dups.patch b/SOURCES/0006-DEBUG-avoid-backtrace-dups.patch
new file mode 100644
index 0000000..44e0de2
--- /dev/null
+++ b/SOURCES/0006-DEBUG-avoid-backtrace-dups.patch
@@ -0,0 +1,145 @@
+From bb8da4303851642318b626aad507ab7c39f6a80d Mon Sep 17 00:00:00 2001
+From: Alexey Tikhonov <atikhono@redhat.com>
+Date: Mon, 1 Nov 2021 20:09:02 +0100
+Subject: [PATCH] DEBUG: avoid backtrace dups.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In case the same error(s) is repeated again and again repeating the same
+backtrace doesn't add much value. In this case let's add just a note.
+
+Reviewed-by: Tomáš Halman <thalman@redhat.com>
+---
+ src/util/debug.c           |  4 +--
+ src/util/debug_backtrace.c | 51 +++++++++++++++++++++++++++++++++++---
+ 2 files changed, 50 insertions(+), 5 deletions(-)
+
+diff --git a/src/util/debug.c b/src/util/debug.c
+index 7c03fb7df..953123718 100644
+--- a/src/util/debug.c
++++ b/src/util/debug.c
+@@ -42,7 +42,7 @@
+ void sss_debug_backtrace_init(void);
+ void sss_debug_backtrace_vprintf(int level, const char *format, va_list ap);
+ void sss_debug_backtrace_printf(int level, const char *format, ...);
+-void sss_debug_backtrace_endmsg(int level);
++void sss_debug_backtrace_endmsg(const char *file, long line, int level);
+ 
+ const char *debug_prg_name = "sssd";
+ 
+@@ -359,7 +359,7 @@ void sss_vdebug_fn(const char *file,
+     if (flags & APPEND_LINE_FEED) {
+         sss_debug_backtrace_printf(level, "\n");
+     }
+-    sss_debug_backtrace_endmsg(level);
++    sss_debug_backtrace_endmsg(file, line, level);
+ }
+ 
+ void sss_debug_fn(const char *file,
+diff --git a/src/util/debug_backtrace.c b/src/util/debug_backtrace.c
+index d99325ab6..e376f815b 100644
+--- a/src/util/debug_backtrace.c
++++ b/src/util/debug_backtrace.c
+@@ -30,6 +30,9 @@ extern FILE *_sss_debug_file;
+ static const unsigned SSS_DEBUG_BACKTRACE_DEFAULT_SIZE = 100*1024; /* bytes */
+ static const unsigned SSS_DEBUG_BACKTRACE_LEVEL        = SSSDBG_BE_FO;
+ 
++/* Size of locations history to keep to avoid duplicating backtraces */
++#define SSS_DEBUG_BACKTRACE_LOCATIONS 5
++
+ 
+ /*                     -->
+  * ring buffer = [*******t...\n............e000]
+@@ -46,12 +49,21 @@ static struct {
+     char     *buffer;  /* buffer start */
+     char     *end;     /* end data border */
+     char     *tail;    /* tail of "current" message */
++
++    /* locations where last backtraces happened */
++    struct {
++        const char *file;
++        long        line;
++    } locations[SSS_DEBUG_BACKTRACE_LOCATIONS];
++    unsigned last_location_idx;
+ } _bt;
+ 
+ 
+ static inline bool _all_levels_enabled(void);
+ static inline bool _backtrace_is_enabled(int level);
+ static inline bool _is_trigger_level(int level);
++static void _store_location(const char *file, long line);
++static bool _is_recent_location(const char *file, long line);
+ static void _backtrace_vprintf(const char *format, va_list ap);
+ static void _backtrace_printf(const char *format, ...);
+ static void _backtrace_dump(void);
+@@ -75,6 +87,8 @@ void sss_debug_backtrace_init(void)
+     _bt.enabled     = true;
+     _bt.initialized = true;
+ 
++    /* locations[] & last_location_idx are zero-initialized */
++
+     _backtrace_printf("   *  ");
+ }
+ 
+@@ -116,7 +130,7 @@ void sss_debug_backtrace_printf(int level, const char *format, ...)
+ }
+ 
+ 
+-void sss_debug_backtrace_endmsg(int level)
++void sss_debug_backtrace_endmsg(const char *file, long line, int level)
+ {
+     if (DEBUG_IS_SET(level)) {
+         _debug_fflush();
+@@ -124,7 +138,16 @@ void sss_debug_backtrace_endmsg(int level)
+ 
+     if (_backtrace_is_enabled(level)) {
+         if (_is_trigger_level(level)) {
+-            _backtrace_dump();
++            if (!_is_recent_location(file, line)) {
++                _backtrace_dump();
++                _store_location(file, line);
++            } else {
++                fprintf(_sss_debug_file ? _sss_debug_file : stderr,
++                        "   *  ... skipping repetitive backtrace ...\n");
++                /* and reset */
++                _bt.end  = _bt.buffer;
++                _bt.tail = _bt.buffer;
++            }
+         }
+         _backtrace_printf("   *  ");
+     }
+@@ -191,7 +214,29 @@ static inline bool _backtrace_is_enabled(int level)
+ }
+ 
+ 
+- /* prints to buffer */
++static void _store_location(const char *file, long line)
++{
++    _bt.last_location_idx = (_bt.last_location_idx + 1) % SSS_DEBUG_BACKTRACE_LOCATIONS;
++     /* __FILE__ is a character string literal with static storage duration. */
++    _bt.locations[_bt.last_location_idx].file = file;
++    _bt.locations[_bt.last_location_idx].line = line;
++}
++
++
++static bool _is_recent_location(const char *file, long line)
++{
++    for (unsigned idx = 0; idx < SSS_DEBUG_BACKTRACE_LOCATIONS; ++idx) {
++        if ((line == _bt.locations[idx].line) &&
++            (_bt.locations[idx].file != NULL) &&
++            (strcmp(file, _bt.locations[idx].file) == 0)) {
++            return true;
++        }
++    }
++    return false;
++}
++
++
++/* prints to buffer */
+ static void _backtrace_vprintf(const char *format, va_list ap)
+ {
+     int buff_tail_size = _bt.size - (_bt.tail - _bt.buffer);
+-- 
+2.26.3
+
diff --git a/SOURCES/0007-cache_req-cache_first-fix-for-fully-qualified-names.patch b/SOURCES/0007-cache_req-cache_first-fix-for-fully-qualified-names.patch
new file mode 100644
index 0000000..02eaa73
--- /dev/null
+++ b/SOURCES/0007-cache_req-cache_first-fix-for-fully-qualified-names.patch
@@ -0,0 +1,131 @@
+From 26654d3e5f5882dd1681116cb49228d108351d48 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Thu, 12 Aug 2021 09:27:57 +0200
+Subject: [PATCH] cache_req: cache_first fix for fully-qualified names
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With commit b572871236a7f9059d375a5ab1bff8cbfd519956 "cache_req:
+introduce cache_behavior enumeration" the processing of cache and
+backend lookups was refactored. Unfortunately this introduce an issue
+when looking up users or groups with a fully-qualified name and the
+'cache_first = True' option is set.
+
+In the old code the case when a domain name is available was handle
+before the cache_first first option was evaluated and cache_req was
+instructed to first look in the cache and then call the backend if the
+object is not available or expired, i.e. the default behavior. Since
+only a single domain is involved this is in agreement with 'cache_first
+= True' and only a single iteration is needed.
+
+In the new code the cache_first option is evaluated before the presence
+of a domain name is checked and as a result even for single domain
+searches the first cache_req iteration is only looking at the cache and
+will not call the backend. This means the now for searches with a
+fully-qualified name a second iteration is needed if the object was not
+found in the cache.
+
+Unfortunately the old exit condition that if a domain name is present
+only a single iteration is needed is still present in the new code which
+effectively makes requests with fully-qualified named only search the
+cache and never call the backends. This patch removes the exit condition
+and does a second iteration for fully-qualified names as well if
+'cache_first = True' is set.
+
+Resolves: https://github.com/SSSD/sssd/issues/5744
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/responder/common/cache_req/cache_req.c  |  3 +-
+ src/tests/cmocka/test_responder_cache_req.c | 53 +++++++++++++++++++++
+ 2 files changed, 54 insertions(+), 2 deletions(-)
+
+diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c
+index 750d655c1..56ec077f3 100644
+--- a/src/responder/common/cache_req/cache_req.c
++++ b/src/responder/common/cache_req/cache_req.c
+@@ -1331,8 +1331,7 @@ static errno_t cache_req_select_domains(struct tevent_req *req,
+ 
+     state = tevent_req_data(req, struct cache_req_state);
+ 
+-    if ((state->cr->cache_behavior != CACHE_REQ_CACHE_FIRST)
+-        || (domain_name != NULL)) {
++    if (state->cr->cache_behavior != CACHE_REQ_CACHE_FIRST) {
+ 
+         if (!state->first_iteration) {
+             /* We're done here. */
+diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
+index 5cf7660e7..27a525f6e 100644
+--- a/src/tests/cmocka/test_responder_cache_req.c
++++ b/src/tests/cmocka/test_responder_cache_req.c
+@@ -992,6 +992,56 @@ void test_user_by_name_missing_notfound(void **state)
+     assert_true(test_ctx->dp_called);
+ }
+ 
++void test_user_by_name_missing_notfound_cache_first(void **state)
++{
++    struct cache_req_test_ctx *test_ctx = NULL;
++
++    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
++    test_ctx->rctx->cache_first = true;
++
++    /* Mock values. */
++    will_return(__wrap_sss_dp_get_account_send, test_ctx);
++    mock_account_recv_simple();
++    mock_parse_inp(users[0].short_name, NULL, ERR_OK);
++
++    /* Test. */
++    run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
++    assert_true(test_ctx->dp_called);
++}
++
++void test_user_by_name_missing_notfound_full_name(void **state)
++{
++    struct cache_req_test_ctx *test_ctx = NULL;
++
++    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
++
++    /* Mock values. */
++    will_return(__wrap_sss_dp_get_account_send, test_ctx);
++    mock_account_recv_simple();
++    mock_parse_inp(users[0].short_name, TEST_DOM_NAME, ERR_OK);
++
++    /* Test. */
++    run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
++    assert_true(test_ctx->dp_called);
++}
++
++void test_user_by_name_missing_notfound_cache_first_full_name(void **state)
++{
++    struct cache_req_test_ctx *test_ctx = NULL;
++
++    test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx);
++    test_ctx->rctx->cache_first = true;
++
++    /* Mock values. */
++    will_return(__wrap_sss_dp_get_account_send, test_ctx);
++    mock_account_recv_simple();
++    mock_parse_inp(users[0].short_name, TEST_DOM_NAME, ERR_OK);
++
++    /* Test. */
++    run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
++    assert_true(test_ctx->dp_called);
++}
++
+ void test_user_by_name_multiple_domains_requested_domains_found(void **state)
+ {
+     struct cache_req_test_ctx *test_ctx = NULL;
+@@ -4255,6 +4305,9 @@ int main(int argc, const char *argv[])
+         new_single_domain_test(user_by_name_ncache),
+         new_single_domain_test(user_by_name_missing_found),
+         new_single_domain_test(user_by_name_missing_notfound),
++        new_single_domain_test(user_by_name_missing_notfound_cache_first),
++        new_single_domain_test(user_by_name_missing_notfound_full_name),
++        new_single_domain_test(user_by_name_missing_notfound_cache_first_full_name),
+         new_multi_domain_test(user_by_name_multiple_domains_found),
+         new_multi_domain_test(user_by_name_multiple_domains_notfound),
+         new_multi_domain_test(user_by_name_multiple_domains_parse),
+-- 
+2.26.3
+
diff --git a/SOURCES/0008-utils-ignore-systemd-and-sd-pam-process-in-get_activ.patch b/SOURCES/0008-utils-ignore-systemd-and-sd-pam-process-in-get_activ.patch
new file mode 100644
index 0000000..7fbb111
--- /dev/null
+++ b/SOURCES/0008-utils-ignore-systemd-and-sd-pam-process-in-get_activ.patch
@@ -0,0 +1,111 @@
+From a56b8d1aaf030fea196b65545dfe207ea10bdf50 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
+Date: Fri, 3 Dec 2021 13:38:44 +0100
+Subject: [PATCH] utils: ignore systemd and sd-pam process in
+ get_active_uid_linux()
+
+We iterate processes in /proc to get the list of active users (users
+that has any process running). However, recent change in systemd makes
+systemd and sd-pam process ligner for few more seconds when the user has
+logged out which breaks the no-session functionality in pam responder.
+
+If user is logged in, another process then systemd and sd-pam must be
+running. Therefore we can just ignore these from the list.
+
+```
+admin     351997  0.4  0.0  22648 14636 ?        Ss   13:25   0:00 /usr/lib/systemd/systemd --user
+admin     351999  0.0  0.0 201464  7756 ?        S    13:25   0:00 (sd-pam)
+```
+
+Resolves: https://github.com/SSSD/sssd/issues/5900
+
+:fixes: Quick log out and log in did not correctly refresh
+  user's initgroups in `no_session` PAM schema due to lingering
+  systemd processes.
+
+Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
+Reviewed-by: Sumit Bose <sbose@redhat.com>
+---
+ src/util/find_uid.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/src/util/find_uid.c b/src/util/find_uid.c
+index 38e8f6164..1b506dfc3 100644
+--- a/src/util/find_uid.c
++++ b/src/util/find_uid.c
+@@ -58,7 +58,7 @@ static void hash_talloc_free(void *ptr, void *pvt)
+     talloc_free(ptr);
+ }
+ 
+-static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid)
++static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid, bool *is_systemd)
+ {
+     int ret;
+     char path[PATHLEN];
+@@ -138,6 +138,7 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid)
+               "close failed [%d][%s].\n", error, strerror(error));
+     }
+ 
++    /* Get uid */
+     p = strstr(buf, "\nUid:\t");
+     if (p != NULL) {
+         p += 6;
+@@ -165,6 +166,24 @@ static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid)
+         return EINVAL;
+     }
+ 
++    /* Get process name. */
++    p = strstr(buf, "Name:\t");
++    if (p == NULL) {
++        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
++        return EINVAL;
++    }
++    p += 6;
++    e = strchr(p,'\n');
++    if (e == NULL) {
++        DEBUG(SSSDBG_CRIT_FAILURE, "format error\n");
++        return EINVAL;
++    }
++    if (strncmp(p, "systemd", e-p) == 0 || strncmp(p, "(sd-pam)", e-p) == 0) {
++        *is_systemd = true;
++    } else {
++        *is_systemd = false;
++    }
++
+     *uid = num;
+ 
+     return EOK;
+@@ -215,6 +234,7 @@ static errno_t get_active_uid_linux(hash_table_t *table, uid_t search_uid)
+     struct dirent *dirent;
+     int ret, err;
+     pid_t pid = -1;
++    bool is_systemd;
+     uid_t uid;
+ 
+     hash_key_t key;
+@@ -238,7 +258,7 @@ static errno_t get_active_uid_linux(hash_table_t *table, uid_t search_uid)
+             goto done;
+         }
+ 
+-        ret = get_uid_from_pid(pid, &uid);
++        ret = get_uid_from_pid(pid, &uid, &is_systemd);
+         if (ret != EOK) {
+             /* Most probably this /proc entry disappeared.
+                Anyway, just skip it.
+@@ -248,6 +268,13 @@ static errno_t get_active_uid_linux(hash_table_t *table, uid_t search_uid)
+             continue;
+         }
+ 
++        if (is_systemd) {
++            /* Systemd process may linger for a while even when user.
++             * is logged out. Lets ignore it and focus only
++             * on non-systemd processes. */
++            continue;
++        }
++
+         if (table != NULL) {
+             key.type = HASH_KEY_ULONG;
+             key.ul = (unsigned long) uid;
+-- 
+2.26.3
+
diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec
index 110fb31..d947ab6 100644
--- a/SPECS/sssd.spec
+++ b/SPECS/sssd.spec
@@ -19,7 +19,7 @@
 
 Name: sssd
 Version: 2.5.2
-Release: 2%{?dist}.1
+Release: 2%{?dist}.3
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -29,6 +29,12 @@ Source0: https://github.com/SSSD/sssd/releases/download/%{version}/sssd-%{versio
 ### Patches ###
 Patch0001: 0001-TOOLS-replace-system-with-execvp.patch
 Patch0002: 0002-po-update-translations.patch
+Patch0003: 0003-ad-filter-trusted-domains.patch
+Patch0004: 0004-cache_req-return-success-for-autofs-when-ENOENT-is-r.patch
+Patch0005: 0005-MONITOR-reduce-logs-severity-around-signalling-and-t.patch
+Patch0006: 0006-DEBUG-avoid-backtrace-dups.patch
+Patch0007: 0007-cache_req-cache_first-fix-for-fully-qualified-names.patch
+Patch0008: 0008-utils-ignore-systemd-and-sd-pam-process-in-get_activ.patch
 
 ### Downstream Patches ###
 
@@ -1145,6 +1151,15 @@ fi
 %systemd_postun_with_restart sssd.service
 
 %changelog
+* Tue Dec 07 2021 Alexey Tikhonov <atikhono@redhat.com> - 2.5.2-2.3
+- Resolves: rhbz#2028828 - pam responder does not call initgroups to refresh the user entry [rhel-8.5.0.z]
+
+* Mon Nov 29 2021 Alexey Tikhonov <atikhono@redhat.com> - 2.5.2-2.2
+- Resolves: rhbz#2018440 - 2.5.x based SSSD adds more AD domains than it should based on the configuration file (not trusted and from a different forest) [rhel-8.5.0.z]
+- Resolves: rhbz#2016923 - autofs lookups for unknown mounts are delayed for 50s [rhel-8.5.0.z]
+- Resolves: rhbz#2021499 - Make backtrace less "chatty" (avoid duplicate backtraces) [rhel-8.5.0.z]
+- Resolves: rhbz#2013379 - Lookup with fully-qualified name does not work with 'cache_first = True' [rhel-8.5.0.z]
+
 * Mon Oct 18 2021 Alexey Tikhonov <atikhono@redhat.com> - 2.5.2-2.1
 - Resolves: rhbz#2014460 - tps tests fail with cross dependency on sssd debuginfo package: removal of 'sssd-libwbclient-debuginfo' is missing [rhel-8.5.0.z]