From bd201746f8cf0e95615b3e98868555451b5e66b8 Mon Sep 17 00:00:00 2001 From: Tomas Halman Date: Dec 04 2019 10:56:59 +0000 Subject: sdap: Add randomness to ldap connection timeout In case of mass deployment, mass registration of IPA clients roughly on the same time leads to regular CPU load spikes on IPA servers, the load spikes are caused by all/most clients refreshing their LDAP connections (ldap_connection_expire_timeout) every 15 minutes. This patch introduces new random value (from 0 up to ldap_connection_expire_offset) that is added to the timeout. Resolves: https://pagure.io/SSSD/sssd/issue/3630 Reviewed-by: Alexey Tikhonov --- diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini index 8c73c89..c56d5a6 100644 --- a/src/config/cfg_rules.ini +++ b/src/config/cfg_rules.ini @@ -600,6 +600,7 @@ option = ldap_chpass_dns_service_name option = ldap_chpass_update_last_change option = ldap_chpass_uri option = ldap_connection_expire_timeout +option = ldap_connection_expire_offset option = ldap_default_authtok option = ldap_default_authtok_type option = ldap_default_bind_dn diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf index 80e329b..aaa0b23 100644 --- a/src/config/etc/sssd.api.d/sssd-ad.conf +++ b/src/config/etc/sssd.api.d/sssd-ad.conf @@ -58,6 +58,7 @@ ldap_deref = str, None, false ldap_page_size = int, None, false ldap_deref_threshold = int, None, false ldap_connection_expire_timeout = int, None, false +ldap_connection_expire_offset = int, None, false ldap_disable_paging = bool, None, false krb5_confd_path = str, None, false wildcard_limit = int, None, false diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf index e2d46db..7ed153d 100644 --- a/src/config/etc/sssd.api.d/sssd-ipa.conf +++ b/src/config/etc/sssd.api.d/sssd-ipa.conf @@ -52,6 +52,7 @@ ldap_deref = str, None, false ldap_page_size = int, None, false ldap_deref_threshold = int, None, false ldap_connection_expire_timeout = int, None, false +ldap_connection_expire_offset = int, None, false ldap_disable_paging = bool, None, false krb5_confd_path = str, None, false wildcard_limit = int, None, false diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index 01c1d7f..4f73e90 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -36,6 +36,7 @@ ldap_deref_threshold = int, None, false ldap_sasl_canonicalize = bool, None, false ldap_sasl_minssf = int, None, false ldap_connection_expire_timeout = int, None, false +ldap_connection_expire_offset = int, None, false ldap_disable_paging = bool, None, false ldap_disable_range_retrieval = bool, None, false wildcard_limit = int, None, false diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index 6d1ae23..f8bb973 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -510,12 +510,31 @@ will be used. + This timeout can be extended of a random + value specified by + ldap_connection_expire_offset + + Default: 900 (15 minutes) + ldap_connection_expire_offset (integer) + + + Random offset between 0 and configured value + is added to + ldap_connection_expire_timeout. + + + Default: 0 + + + + + ldap_page_size (integer) diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c index cd568e4..1293219 100644 --- a/src/providers/ad/ad_opts.c +++ b/src/providers/ad/ad_opts.c @@ -137,6 +137,7 @@ struct dp_option ad_def_ldap_opts[] = { { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, + { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER }, diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c index 7974cb8..4fafa07 100644 --- a/src/providers/ipa/ipa_opts.c +++ b/src/providers/ipa/ipa_opts.c @@ -147,6 +147,7 @@ struct dp_option ipa_def_ldap_opts[] = { { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, + { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER }, diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c index a20ec0d..ffd0c6b 100644 --- a/src/providers/ldap/ldap_opts.c +++ b/src/providers/ldap/ldap_opts.c @@ -107,6 +107,7 @@ struct dp_option default_basic_opts[] = { { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, + { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER }, diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index d0a19a6..f27b3c4 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -221,6 +221,7 @@ enum sdap_basic_opt { SDAP_DEREF_THRESHOLD, SDAP_SASL_CANONICALIZE, SDAP_EXPIRE_TIMEOUT, + SDAP_EXPIRE_OFFSET, SDAP_DISABLE_PAGING, SDAP_IDMAP_LOWER, SDAP_IDMAP_UPPER, diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c index 0260cba..7438d14 100644 --- a/src/providers/ldap/sdap_async_connection.c +++ b/src/providers/ldap/sdap_async_connection.c @@ -1803,6 +1803,8 @@ static void sdap_cli_auth_step(struct tevent_req *req) struct tevent_req *subreq; time_t now; int expire_timeout; + int expire_offset; + const char *sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH); const char *user_dn = dp_opt_get_string(state->opts->basic, @@ -1832,6 +1834,16 @@ static void sdap_cli_auth_step(struct tevent_req *req) */ now = time(NULL); expire_timeout = dp_opt_get_int(state->opts->basic, SDAP_EXPIRE_TIMEOUT); + expire_offset = dp_opt_get_int(state->opts->basic, SDAP_EXPIRE_OFFSET); + if (expire_offset > 0) { + expire_timeout += sss_rand() % (expire_offset + 1); + } else if (expire_offset < 0) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Negative value [%d] of ldap_connection_expire_offset " + "is not allowed.\n", + expire_offset); + } + DEBUG(SSSDBG_CONF_SETTINGS, "expire timeout is %d\n", expire_timeout); if (!state->sh->expire_time || (state->sh->expire_time > (now + expire_timeout))) {