From 584a0599820ec9f70b303a479dd1712bf006c16c Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 21 Dec 2021 04:09:22 -0500 Subject: [PATCH] import sssd-2.5.2-2.el8_5.3 --- SOURCES/0003-ad-filter-trusted-domains.patch | 187 ++++++++++++++++++ ...-success-for-autofs-when-ENOENT-is-r.patch | 62 ++++++ ...ogs-severity-around-signalling-and-t.patch | 81 ++++++++ SOURCES/0006-DEBUG-avoid-backtrace-dups.patch | 145 ++++++++++++++ ..._first-fix-for-fully-qualified-names.patch | 131 ++++++++++++ ...temd-and-sd-pam-process-in-get_activ.patch | 111 +++++++++++ SPECS/sssd.spec | 17 +- 7 files changed, 733 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0003-ad-filter-trusted-domains.patch create mode 100644 SOURCES/0004-cache_req-return-success-for-autofs-when-ENOENT-is-r.patch create mode 100644 SOURCES/0005-MONITOR-reduce-logs-severity-around-signalling-and-t.patch create mode 100644 SOURCES/0006-DEBUG-avoid-backtrace-dups.patch create mode 100644 SOURCES/0007-cache_req-cache_first-fix-for-fully-qualified-names.patch create mode 100644 SOURCES/0008-utils-ignore-systemd-and-sd-pam-process-in-get_activ.patch 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 +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 +Reviewed-by: Pavel Březina +--- + 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?= +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 +--- + .../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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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?= +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 +Reviewed-by: Sumit Bose +--- + 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 - 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 - 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 - 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]