From 1b8858b1611db5048592f477059ca5ad66d7ceb1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Mon, 18 Jan 2016 22:02:55 +0100
Subject: [PATCH] NSS: do not skip cache check for netgoups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When refresh_expired_interval was not zero,
the NSS responder only refreshed netgroup cache
using background periodic task and ignored
SYSDB_CACHE_EXPIRE attribute.

With this behaviour it was impossible to
get new netgroup from remote server even
after sss_cache tool was used to expire
existing entry in the cache.

Resolves:
https://fedorahosted.org/sssd/ticket/2912

Reviewed-by: Pavel Březina <pbrezina@redhat.com>

diff -rupN sssd-1.11.5.1-original/src/responder/nss/nsssrv_cmd.c sssd-1.11.5.1-patched/src/responder/nss/nsssrv_cmd.c
--- sssd-1.11.5.1-original/src/responder/nss/nsssrv_cmd.c	2017-01-31 17:06:08.757779081 +0100
+++ sssd-1.11.5.1-patched/src/responder/nss/nsssrv_cmd.c	2017-01-31 17:09:11.343746682 +0100
@@ -502,10 +502,9 @@ static int nss_cmd_getpw_send_reply(stru
     return EOK;
 }
 
-/* Currently only refreshing expired netgroups is supported. */
 static bool
 is_refreshed_on_bg(int req_type,
-                   enum sss_dp_acct_type refresh_expired_interval)
+                   uint32_t refresh_expired_interval)
 {
     if (refresh_expired_interval == 0) {
         return false;
@@ -513,6 +512,8 @@ is_refreshed_on_bg(int req_type,
 
     switch (req_type) {
     case SSS_DP_NETGR:
+    case SSS_DP_USER:
+    case SSS_DP_GROUP:
         return true;
     default:
         return false;
@@ -550,33 +551,29 @@ errno_t check_cache(struct nss_dom_ctx *
         return ENOENT;
     }
 
-    /* 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 we have any reply let's check cache validity */
     if (res->count > 0) {
-        if (is_refreshed_on_bg(req_type,
-                               dctx->domain->refresh_expired_interval)) {
-            ret = EOK;
+        bool refreshed_on_bg;
+        uint32_t bg_refresh_interval = dctx->domain->refresh_expired_interval;
+
+        if (req_type == SSS_DP_INITGROUPS) {
+            cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+                                                      SYSDB_INITGR_EXPIRE,
+                                                      0);
         } 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);
+            cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+                                                      SYSDB_CACHE_EXPIRE,
+                                                      0);
         }
 
-        if (ret == EOK) {
+        /* Check if background refresh is enabled for this entry */
+        refreshed_on_bg = is_refreshed_on_bg(req_type, bg_refresh_interval);
+
+        /* 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 || (ret == EAGAIN && refreshed_on_bg))  {
             DEBUG(SSSDBG_TRACE_FUNC, ("Cached entry is valid, returning..\n"));
             return EOK;
         } else if (ret != EAGAIN && ret != ENOENT) {
