From a5f300adf19ec9c3087c62bd93a5175db799687a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Tue, 11 Jul 2017 12:41:57 +0200 Subject: [PATCH 33/93] sudo: add a threshold option to reduce size of rules refresh filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a large number of rules is expired at one time the ldap filter may become too large to be processed by server. This commits adds a new option "sudo_threshold" to sudo responder. If the threshold is exceeded a full refreshed is done instead of rules refresh. Resolves: https://pagure.io/SSSD/sssd/issue/3478 Reviewed-by: Jakub Hrozek Reviewed-by: Fabiano FidĂȘncio --- src/confdb/confdb.h | 2 ++ src/config/SSSDConfig/__init__.py.in | 1 + src/config/cfg_rules.ini | 1 + src/config/etc/sssd.api.conf | 1 + src/man/sssd.conf.5.xml | 19 +++++++++++++++++++ src/responder/sudo/sudosrv.c | 11 +++++++++++ src/responder/sudo/sudosrv_get_sudorules.c | 25 ++++++++++++++++++++----- src/responder/sudo/sudosrv_private.h | 1 + 8 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 3773358374064c68b2ae254fd18f43ca4c43d834..66ecc041398fda973c0f30a47a3f5944c88d19c2 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -139,6 +139,8 @@ #define CONFDB_DEFAULT_SUDO_TIMED false #define CONFDB_SUDO_INVERSE_ORDER "sudo_inverse_order" #define CONFDB_DEFAULT_SUDO_INVERSE_ORDER false +#define CONFDB_SUDO_THRESHOLD "sudo_threshold" +#define CONFDB_DEFAULT_SUDO_THRESHOLD 50 /* autofs */ #define CONFDB_AUTOFS_CONF_ENTRY "config/autofs" diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index 0e0c3be6d0c6531daddd3927c53156d28a657d2b..de757521cff58460049bb8c4873efaf6bf0b8d95 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -107,6 +107,7 @@ option_strings = { # [sudo] 'sudo_timed' : _('Whether to evaluate the time-based attributes in sudo rules'), 'sudo_inverse_order' : _('If true, SSSD will switch back to lower-wins ordering logic'), + 'sudo_threshold' : _('Maximum number of rules that can be refreshed at once. If this is exceeded, full refresh is performed.'), # [autofs] 'autofs_negative_timeout' : _('Negative cache timeout length (seconds)'), diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini index 4537d0fe87d7084cdff5e591451298393b7f632f..cba59d2c3813f44b8ab85b4c246108232f9d8fd4 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -145,6 +145,7 @@ option = cache_first # sudo service option = sudo_timed option = sudo_inverse_order +option = sudo_threshold [rule/allowed_autofs_options] validator = ini_allowed_options diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index ef910f0dfc96241feca6db241219783d774891ef..0d11771ae3df50ba9f380e44747a5385a224544d 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -79,6 +79,7 @@ pam_app_services = str, None, false # sudo service sudo_timed = bool, None, false sudo_inverse_order = bool, None, false +sudo_threshold = int, None, false [autofs] # autofs service diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index 7cd6ffd7a632449e23672da14586560500b9d185..7b5abebbf68a832c3b0af9bcff9c535eca77778a 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -1378,6 +1378,25 @@ pam_account_locked_message = Account locked, please contact help desk. + + + sudo_threshold (integer) + + + Maximum number of expired rules that can be + refreshed at once. If number of expired rules + is below threshold, those rules are refreshed + with rules refresh mechanism. If + the threshold is exceeded a + full refresh of sudo rules is + triggered instead. + + + Default: 50 + + + + diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c index b427878d4dbe9090824a01386a7475be88b699c0..dca70ea4afc0e6df6d1b1864338c7b1091a98fee 100644 --- a/src/responder/sudo/sudosrv.c +++ b/src/responder/sudo/sudosrv.c @@ -148,6 +148,17 @@ int sudo_process_init(TALLOC_CTX *mem_ctx, goto fail; } + /* Get sudo_inverse_order option */ + ret = confdb_get_int(sudo_ctx->rctx->cdb, + CONFDB_SUDO_CONF_ENTRY, CONFDB_SUDO_THRESHOLD, + CONFDB_DEFAULT_SUDO_THRESHOLD, + &sudo_ctx->threshold); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", + ret, strerror(ret)); + goto fail; + } + ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c index cfdbfc9c9c66d96f774822d6a4d4aaaf1327abe3..3272e634d895acf4854309371779a00cf1525126 100644 --- a/src/responder/sudo/sudosrv_get_sudorules.c +++ b/src/responder/sudo/sudosrv_get_sudorules.c @@ -479,6 +479,7 @@ sudosrv_refresh_rules_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_domain_info *domain, + int threshold, uid_t uid, const char *username, char **groups) @@ -520,9 +521,20 @@ sudosrv_refresh_rules_send(TALLOC_CTX *mem_ctx, DEBUG(SSSDBG_TRACE_INTERNAL, "Refreshing %d expired rules of [%s@%s]\n", num_rules, username, domain->name); - subreq = sss_dp_get_sudoers_send(state, rctx, domain, false, - SSS_DP_SUDO_REFRESH_RULES, - username, num_rules, rules); + if (num_rules > threshold) { + DEBUG(SSSDBG_TRACE_INTERNAL, + "Rules threshold [%d] is reached, performing full refresh " + "instead.\n", threshold); + + subreq = sss_dp_get_sudoers_send(state, rctx, domain, false, + SSS_DP_SUDO_FULL_REFRESH, + username, 0, NULL); + } else { + subreq = sss_dp_get_sudoers_send(state, rctx, domain, false, + SSS_DP_SUDO_REFRESH_RULES, + username, num_rules, rules); + } + if (subreq == NULL) { ret = ENOMEM; goto immediately; @@ -609,6 +621,7 @@ struct sudosrv_get_rules_state { struct sss_domain_info *domain; char **groups; bool inverse_order; + int threshold; struct sysdb_attrs **rules; uint32_t num_rules; @@ -640,6 +653,7 @@ struct tevent_req *sudosrv_get_rules_send(TALLOC_CTX *mem_ctx, state->type = type; state->uid = uid; state->inverse_order = sudo_ctx->inverse_order; + state->threshold = sudo_ctx->threshold; DEBUG(SSSDBG_TRACE_FUNC, "Running initgroups for [%s]\n", username); @@ -696,8 +710,9 @@ static void sudosrv_get_rules_initgr_done(struct tevent_req *subreq) } subreq = sudosrv_refresh_rules_send(state, state->ev, state->rctx, - state->domain, state->uid, - state->username, state->groups); + state->domain, state->threshold, + state->uid, state->username, + state->groups); if (subreq == NULL) { ret = ENOMEM; goto done; diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h index 94f3c4458ab20e64db3e0bfce726d5d30a70a202..c76bdd3955bc29b7ba2cda58c503a4c616d7e63a 100644 --- a/src/responder/sudo/sudosrv_private.h +++ b/src/responder/sudo/sudosrv_private.h @@ -48,6 +48,7 @@ struct sudo_ctx { */ bool timed; bool inverse_order; + int threshold; }; struct sudo_cmd_ctx { -- 2.14.1