Blame SOURCES/0009-sdap-Add-randomness-to-ldap-connection-timeout.patch

0d097b
From bd201746f8cf0e95615b3e98868555451b5e66b8 Mon Sep 17 00:00:00 2001
0d097b
From: Tomas Halman <thalman@redhat.com>
0d097b
Date: Mon, 2 Dec 2019 11:11:52 +0100
0d097b
Subject: [PATCH] sdap: Add randomness to ldap connection timeout
0d097b
0d097b
In case of mass deployment, mass registration of IPA clients roughly on
0d097b
the same time leads to regular CPU load spikes on IPA servers, the load
0d097b
spikes are caused by all/most clients refreshing their LDAP connections
0d097b
(ldap_connection_expire_timeout) every 15 minutes.
0d097b
0d097b
This patch introduces new random value (from 0 up to
0d097b
ldap_connection_expire_offset) that is added to the timeout.
0d097b
0d097b
Resolves:
0d097b
https://pagure.io/SSSD/sssd/issue/3630
0d097b
0d097b
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
0d097b
---
0d097b
 src/config/cfg_rules.ini                   |  1 +
0d097b
 src/config/etc/sssd.api.d/sssd-ad.conf     |  1 +
0d097b
 src/config/etc/sssd.api.d/sssd-ipa.conf    |  1 +
0d097b
 src/config/etc/sssd.api.d/sssd-ldap.conf   |  1 +
0d097b
 src/man/sssd-ldap.5.xml                    | 19 +++++++++++++++++++
0d097b
 src/providers/ad/ad_opts.c                 |  1 +
0d097b
 src/providers/ipa/ipa_opts.c               |  1 +
0d097b
 src/providers/ldap/ldap_opts.c             |  1 +
0d097b
 src/providers/ldap/sdap.h                  |  1 +
0d097b
 src/providers/ldap/sdap_async_connection.c | 12 ++++++++++++
0d097b
 10 files changed, 39 insertions(+)
0d097b
0d097b
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
0d097b
index 8c73c89ac..c56d5a668 100644
0d097b
--- a/src/config/cfg_rules.ini
0d097b
+++ b/src/config/cfg_rules.ini
0d097b
@@ -600,6 +600,7 @@ option = ldap_chpass_dns_service_name
0d097b
 option = ldap_chpass_update_last_change
0d097b
 option = ldap_chpass_uri
0d097b
 option = ldap_connection_expire_timeout
0d097b
+option = ldap_connection_expire_offset
0d097b
 option = ldap_default_authtok
0d097b
 option = ldap_default_authtok_type
0d097b
 option = ldap_default_bind_dn
0d097b
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
0d097b
index 80e329b3b..aaa0b2345 100644
0d097b
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
0d097b
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
0d097b
@@ -58,6 +58,7 @@ ldap_deref = str, None, false
0d097b
 ldap_page_size = int, None, false
0d097b
 ldap_deref_threshold = int, None, false
0d097b
 ldap_connection_expire_timeout = int, None, false
0d097b
+ldap_connection_expire_offset = int, None, false
0d097b
 ldap_disable_paging = bool, None, false
0d097b
 krb5_confd_path = str, None, false
0d097b
 wildcard_limit = int, None, false
0d097b
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
0d097b
index e2d46db75..7ed153d36 100644
0d097b
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
0d097b
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
0d097b
@@ -52,6 +52,7 @@ ldap_deref = str, None, false
0d097b
 ldap_page_size = int, None, false
0d097b
 ldap_deref_threshold = int, None, false
0d097b
 ldap_connection_expire_timeout = int, None, false
0d097b
+ldap_connection_expire_offset = int, None, false
0d097b
 ldap_disable_paging = bool, None, false
0d097b
 krb5_confd_path = str, None, false
0d097b
 wildcard_limit = int, None, false
0d097b
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
0d097b
index 01c1d7f12..4f73e901e 100644
0d097b
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
0d097b
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
0d097b
@@ -36,6 +36,7 @@ ldap_deref_threshold = int, None, false
0d097b
 ldap_sasl_canonicalize = bool, None, false
0d097b
 ldap_sasl_minssf = int, None, false
0d097b
 ldap_connection_expire_timeout = int, None, false
0d097b
+ldap_connection_expire_offset = int, None, false
0d097b
 ldap_disable_paging = bool, None, false
0d097b
 ldap_disable_range_retrieval = bool, None, false
0d097b
 wildcard_limit = int, None, false
0d097b
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
0d097b
index 6d1ae23ec..f8bb973c7 100644
0d097b
--- a/src/man/sssd-ldap.5.xml
0d097b
+++ b/src/man/sssd-ldap.5.xml
0d097b
@@ -509,12 +509,31 @@
0d097b
                             the two values (this value vs. the TGT lifetime)
0d097b
                             will be used.
0d097b
                         </para>
0d097b
+                        <para>
0d097b
+                            This timeout can be extended of a random
0d097b
+                            value specified by
0d097b
+                            <emphasis>ldap_connection_expire_offset</emphasis>
0d097b
+                        </para>
0d097b
                         <para>
0d097b
                             Default: 900 (15 minutes)
0d097b
                         </para>
0d097b
                     </listitem>
0d097b
                 </varlistentry>
0d097b
 
0d097b
+                <varlistentry>
0d097b
+                    <term>ldap_connection_expire_offset (integer)</term>
0d097b
+                    <listitem>
0d097b
+                        <para>
0d097b
+                            Random offset between 0 and configured value
0d097b
+                            is added to
0d097b
+                            <emphasis>ldap_connection_expire_timeout</emphasis>.
0d097b
+                        </para>
0d097b
+                        <para>
0d097b
+                            Default: 0
0d097b
+                        </para>
0d097b
+                    </listitem>
0d097b
+                </varlistentry>
0d097b
+
0d097b
                 <varlistentry>
0d097b
                     <term>ldap_page_size (integer)</term>
0d097b
                     <listitem>
0d097b
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
0d097b
index cd568e466..1293219ee 100644
0d097b
--- a/src/providers/ad/ad_opts.c
0d097b
+++ b/src/providers/ad/ad_opts.c
0d097b
@@ -137,6 +137,7 @@ struct dp_option ad_def_ldap_opts[] = {
0d097b
     { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
0d097b
     { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
0d097b
     { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER },
0d097b
+    { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER },
0d097b
     { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
0d097b
     { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER },
0d097b
     { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER },
0d097b
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
0d097b
index 7974cb8ea..4fafa073d 100644
0d097b
--- a/src/providers/ipa/ipa_opts.c
0d097b
+++ b/src/providers/ipa/ipa_opts.c
0d097b
@@ -147,6 +147,7 @@ struct dp_option ipa_def_ldap_opts[] = {
0d097b
     { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
0d097b
     { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
0d097b
     { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER },
0d097b
+    { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER },
0d097b
     { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
0d097b
     { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER },
0d097b
     { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER },
0d097b
diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c
0d097b
index a20ec0d86..ffd0c6baa 100644
0d097b
--- a/src/providers/ldap/ldap_opts.c
0d097b
+++ b/src/providers/ldap/ldap_opts.c
0d097b
@@ -107,6 +107,7 @@ struct dp_option default_basic_opts[] = {
0d097b
     { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
0d097b
     { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
0d097b
     { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER },
0d097b
+    { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER },
0d097b
     { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
0d097b
     { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER },
0d097b
     { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER },
0d097b
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
0d097b
index d0a19a660..f27b3c480 100644
0d097b
--- a/src/providers/ldap/sdap.h
0d097b
+++ b/src/providers/ldap/sdap.h
0d097b
@@ -221,6 +221,7 @@ enum sdap_basic_opt {
0d097b
     SDAP_DEREF_THRESHOLD,
0d097b
     SDAP_SASL_CANONICALIZE,
0d097b
     SDAP_EXPIRE_TIMEOUT,
0d097b
+    SDAP_EXPIRE_OFFSET,
0d097b
     SDAP_DISABLE_PAGING,
0d097b
     SDAP_IDMAP_LOWER,
0d097b
     SDAP_IDMAP_UPPER,
0d097b
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
0d097b
index 0260cba6f..7438d14a7 100644
0d097b
--- a/src/providers/ldap/sdap_async_connection.c
0d097b
+++ b/src/providers/ldap/sdap_async_connection.c
0d097b
@@ -1803,6 +1803,8 @@ static void sdap_cli_auth_step(struct tevent_req *req)
0d097b
     struct tevent_req *subreq;
0d097b
     time_t now;
0d097b
     int expire_timeout;
0d097b
+    int expire_offset;
0d097b
+
0d097b
     const char *sasl_mech = dp_opt_get_string(state->opts->basic,
0d097b
                                               SDAP_SASL_MECH);
0d097b
     const char *user_dn = dp_opt_get_string(state->opts->basic,
0d097b
@@ -1832,6 +1834,16 @@ static void sdap_cli_auth_step(struct tevent_req *req)
0d097b
      */
0d097b
     now = time(NULL);
0d097b
     expire_timeout = dp_opt_get_int(state->opts->basic, SDAP_EXPIRE_TIMEOUT);
0d097b
+    expire_offset = dp_opt_get_int(state->opts->basic, SDAP_EXPIRE_OFFSET);
0d097b
+    if (expire_offset > 0) {
0d097b
+        expire_timeout += sss_rand() % (expire_offset + 1);
0d097b
+    } else if (expire_offset < 0) {
0d097b
+        DEBUG(SSSDBG_MINOR_FAILURE,
0d097b
+              "Negative value [%d] of ldap_connection_expire_offset "
0d097b
+              "is not allowed.\n",
0d097b
+              expire_offset);
0d097b
+    }
0d097b
+
0d097b
     DEBUG(SSSDBG_CONF_SETTINGS, "expire timeout is %d\n", expire_timeout);
0d097b
     if (!state->sh->expire_time
0d097b
             || (state->sh->expire_time > (now + expire_timeout))) {
0d097b
-- 
0d097b
2.20.1
0d097b