Blob Blame History Raw
From 32f913dd143d45aee7f3d91785a86d8e2a85bb22 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 12 Oct 2017 10:42:41 +0200
Subject: [PATCH 28/79] NSS: add support for SSS_NSS_EX_FLAG_NO_CACHE

If SSS_NSS_EX_FLAG_NO_CACHE is set the object is refresh by directly
looking it up in the backend.

Related to https://pagure.io/SSSD/sssd/issue/2478

Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
 src/responder/nss/nss_cmd.c          |  8 ++++
 src/sss_client/idmap/sss_nss_ex.c    | 71 ++++++++++++++++++++----------------
 src/sss_client/idmap/sss_nss_idmap.h |  4 ++
 3 files changed, 52 insertions(+), 31 deletions(-)

diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c
index 974eaccc93cea3a330007735676da69eb9b84141..c5ddd2f2cc2122cd169ea991b94a14eb5bad095f 100644
--- a/src/responder/nss/nss_cmd.c
+++ b/src/responder/nss/nss_cmd.c
@@ -92,6 +92,10 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
         goto done;
     }
 
+    if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
+        cache_req_data_set_bypass_cache(data, true);
+    }
+
     subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx,
                                  data, memcache, rawname, 0);
     if (subreq == NULL) {
@@ -152,6 +156,10 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
         goto done;
     }
 
+    if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
+        cache_req_data_set_bypass_cache(data, true);
+    }
+
     subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx,
                                  data, memcache, NULL, id);
     if (subreq == NULL) {
diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c
index dc7610a4e528b5126f0d25d84cd3c1a22f683b75..edb3ea652ef7032b76c8f815b9f83fe185a669ea 100644
--- a/src/sss_client/idmap/sss_nss_ex.c
+++ b/src/sss_client/idmap/sss_nss_ex.c
@@ -115,42 +115,51 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
     size_t c;
     gid_t *new_groups;
     size_t idx;
+    bool skip_mc = false;
 
-    ret = sss_nss_mc_get(inp);
-    switch (ret) {
-    case 0:
-        return 0;
-    case ERANGE:
-        return ERANGE;
-    case ENOENT:
-        /* fall through, we need to actively ask the parent
-         * if no entry is found */
-        break;
-    default:
-        /* if using the mmaped cache failed,
-         * fall back to socket based comms */
-        break;
+    if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
+        skip_mc = true;
+    }
+
+    if (!skip_mc) {
+        ret = sss_nss_mc_get(inp);
+        switch (ret) {
+        case 0:
+            return 0;
+        case ERANGE:
+            return ERANGE;
+        case ENOENT:
+            /* fall through, we need to actively ask the parent
+             * if no entry is found */
+            break;
+        default:
+            /* if using the mmaped cache failed,
+             * fall back to socket based comms */
+            break;
+        }
     }
 
     sss_nss_timedlock(timeout, &time_left);
 
-    /* previous thread might already initialize entry in mmap cache */
-    ret = sss_nss_mc_get(inp);
-    switch (ret) {
-    case 0:
-        ret = 0;
-        goto out;
-    case ERANGE:
-        ret = ERANGE;
-        goto out;
-    case ENOENT:
-        /* fall through, we need to actively ask the parent
-         * if no entry is found */
-        break;
-    default:
-        /* if using the mmaped cache failed,
-         * fall back to socket based comms */
-        break;
+    if (!skip_mc) {
+        /* previous thread might already initialize entry in mmap cache */
+        ret = sss_nss_mc_get(inp);
+        switch (ret) {
+        case 0:
+            ret = 0;
+            goto out;
+        case ERANGE:
+            ret = ERANGE;
+            goto out;
+        case ENOENT:
+            /* fall through, we need to actively ask the parent
+             * if no entry is found */
+            break;
+        default:
+            /* if using the mmaped cache failed,
+             * fall back to socket based comms */
+            break;
+        }
     }
 
     ret = sss_nss_make_request_timeout(inp->cmd, &inp->rd, time_left,
diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h
index 2334b6cb3fb8ef62e4ce3a7187c7affaeaa034e7..1649830afbb80c617fd339f054aef8bc8e585fb9 100644
--- a/src/sss_client/idmap/sss_nss_idmap.h
+++ b/src/sss_client/idmap/sss_nss_idmap.h
@@ -169,6 +169,10 @@ void sss_nss_free_kv(struct sss_nss_kv *kv_list);
 
 #define SSS_NSS_EX_FLAG_NO_FLAGS 0
 
+/** Always request data from the server side, client must be privileged to do
+ *  so, see nss_trusted_users option in man sssd.conf for details */
+#define SSS_NSS_EX_FLAG_NO_CACHE (1 << 0)
+
 #ifdef IPA_389DS_PLUGIN_HELPER_CALLS
 
 /**
-- 
2.15.1