>From 0141e4dfcabdd4f3a0fa6c39c932dc1dce6d0e6c Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Wed, 26 Feb 2014 16:24:20 +0000
Subject: [PATCH] NSS: disable midpoint refresh for netgroups

Disable midpoint refresh for netgroups if periodical refresh of expired
netgroups is enabled (refresh_expired_interval)

Resolves:
https://fedorahosted.org/sssd/ticket/2102
---
 src/confdb/confdb.c            | 15 ++++++++++++++
 src/responder/nss/nsssrv_cmd.c | 47 ++++++++++++++++++++++++++++++------------
 2 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 0adff2b081f7249ddfeefcbdbbcbe3e24fc901cd..1f1a84df793634d1f1d77630e3e33b83aee04127 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1058,6 +1058,21 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
         goto done;
     }
 
+    /* detect and fix misconfiguration */
+    if (domain->refresh_expired_interval > entry_cache_timeout) {
+        DEBUG(SSSDBG_CONF_SETTINGS,
+              "refresh_expired_interval (%d) cannot be greater then "
+              "entry_cache_timeout (%u)\n",
+              domain->refresh_expired_interval, entry_cache_timeout);
+
+        domain->refresh_expired_interval = 0.75 * entry_cache_timeout;
+
+        DEBUG(SSSDBG_CONF_SETTINGS,
+              "refresh_expired_interval is being set to recommended value "
+              "entry_cache_timeout * 0.75 (%u).\n",
+              domain->refresh_expired_interval);
+    }
+
     /* Set the PAM warning time, if specified. If not specified, pass on
      * the "not set" value of "-1" which means "use provider default". The
      * value 0 means "always display the warning if server sends one" */
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 3956e44632ec1e18c732d42031b92baee9b3b1cc..c8a59f9b4a72d391695acc9e0ea7eacc5f9c15aa 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -516,6 +516,16 @@ static int nss_cmd_getpw_send_reply(struct nss_dom_ctx *dctx, bool filter)
     return EOK;
 }
 
+/* Currently only refreshing expired netgroups is supported. */
+bool is_refreshed_on_bg(int req_type, uint32_t refresh_expired_interval)
+{
+    if (req_type == SSS_DP_NETGR && refresh_expired_interval != 0) {
+        return true;
+    }
+
+    return false;
+}
+
 static void nsssrv_dp_send_acct_req_done(struct tevent_req *req);
 
 /* FIXME: do not check res->count, but get in a msgs and check in parent */
@@ -543,24 +553,35 @@ errno_t check_cache(struct nss_dom_ctx *dctx,
             (res->count > 1)) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "getpwXXX call returned more than one result!"
-                  " DB Corrupted?\n");
+              " DB Corrupted?\n");
         return ENOENT;
     }
 
-    /* if we have any reply let's check cache validity */
+    /* if we have any reply let's check cache validity, but ignore netgroups
+     * if refresh_expired_interval is set (which implies that another method
+     * is used to refresh netgroups)
+     */
     if (res->count > 0) {
-        if (req_type == SSS_DP_INITGROUPS) {
-            cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
-                                                      SYSDB_INITGR_EXPIRE, 1);
-        }
-        if (cacheExpire == 0) {
-            cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
-                                                      SYSDB_CACHE_EXPIRE, 0);
-        }
+        if (is_refreshed_on_bg(req_type,
+                               dctx->domain->refresh_expired_interval)) {
+            ret = EOK;
+        } else {
+            if (req_type == SSS_DP_INITGROUPS) {
+                cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+                                                          SYSDB_INITGR_EXPIRE,
+                                                          1);
+            }
+            if (cacheExpire == 0) {
+                cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+                                                          SYSDB_CACHE_EXPIRE,
+                                                          0);
+            }
 
-        /* if we have any reply let's check cache validity */
-        ret = sss_cmd_check_cache(res->msgs[0], nctx->cache_refresh_percent,
-                                  cacheExpire);
+            /* if we have any reply let's check cache validity */
+            ret = sss_cmd_check_cache(res->msgs[0],
+                                      nctx->cache_refresh_percent,
+                                      cacheExpire);
+        }
         if (ret == EOK) {
             DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning..\n");
             return EOK;
-- 
1.9.3

