Blame SOURCES/0031-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch

ced1f5
From 464a19ecef7c4a0aad22cd9d2c7b2364e3680351 Mon Sep 17 00:00:00 2001
ced1f5
From: Sumit Bose <sbose@redhat.com>
ced1f5
Date: Thu, 2 Nov 2017 11:09:20 +0100
ced1f5
Subject: [PATCH 31/31] nss-idmap: allow empty buffer with
ced1f5
 SSS_NSS_EX_FLAG_INVALIDATE_CACHE
ced1f5
ced1f5
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
ced1f5
(cherry picked from commit 859bddc2bf51dc426a3dc56bd9f365e9c5722b65)
ced1f5
---
ced1f5
 src/sss_client/idmap/sss_nss_ex.c | 89 ++++++++++++++++++++++++++-------------
ced1f5
 1 file changed, 60 insertions(+), 29 deletions(-)
ced1f5
ced1f5
diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c
ced1f5
index 148eb7b35ec236b6272dd203a0035399cfdef73d..dcd9619a8b07ced7498f61b7e809fa46ebffe09e 100644
ced1f5
--- a/src/sss_client/idmap/sss_nss_ex.c
ced1f5
+++ b/src/sss_client/idmap/sss_nss_ex.c
ced1f5
@@ -103,8 +103,11 @@ errno_t sss_nss_mc_get(struct nss_input *inp)
ced1f5
     }
ced1f5
 }
ced1f5
 
ced1f5
-static int check_flags(uint32_t flags)
ced1f5
+static int check_flags(struct nss_input *inp, uint32_t flags,
ced1f5
+                       bool *skip_mc, bool *skip_data)
ced1f5
 {
ced1f5
+    bool no_data = false;
ced1f5
+
ced1f5
     /* SSS_NSS_EX_FLAG_NO_CACHE and SSS_NSS_EX_FLAG_INVALIDATE_CACHE are
ced1f5
      * mutually exclusive */
ced1f5
     if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
ced1f5
@@ -112,6 +115,52 @@ static int check_flags(uint32_t flags)
ced1f5
         return EINVAL;
ced1f5
     }
ced1f5
 
ced1f5
+    *skip_mc = false;
ced1f5
+    if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
ced1f5
+            || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
ced1f5
+        *skip_mc = true;
ced1f5
+    }
ced1f5
+
ced1f5
+    switch(inp->cmd) {
ced1f5
+    case SSS_NSS_GETPWNAM:
ced1f5
+    case SSS_NSS_GETPWNAM_EX:
ced1f5
+    case SSS_NSS_GETPWUID:
ced1f5
+    case SSS_NSS_GETPWUID_EX:
ced1f5
+        if (inp->result.pwrep.buffer == NULL
ced1f5
+                || inp->result.pwrep.buflen == 0) {
ced1f5
+            no_data = true;
ced1f5
+        }
ced1f5
+        break;
ced1f5
+    case SSS_NSS_GETGRNAM:
ced1f5
+    case SSS_NSS_GETGRNAM_EX:
ced1f5
+    case SSS_NSS_GETGRGID:
ced1f5
+    case SSS_NSS_GETGRGID_EX:
ced1f5
+        if (inp->result.grrep.buffer == NULL
ced1f5
+                || inp->result.grrep.buflen == 0) {
ced1f5
+            no_data = true;
ced1f5
+        }
ced1f5
+        break;
ced1f5
+    case SSS_NSS_INITGR:
ced1f5
+    case SSS_NSS_INITGR_EX:
ced1f5
+        if (inp->result.initgrrep.ngroups == 0
ced1f5
+                || inp->result.initgrrep.groups == NULL) {
ced1f5
+            return EINVAL;
ced1f5
+        }
ced1f5
+        break;
ced1f5
+    default:
ced1f5
+        return EINVAL;
ced1f5
+    }
ced1f5
+
ced1f5
+    *skip_data = false;
ced1f5
+    /* Allow empty buffer with SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
ced1f5
+    if (no_data) {
ced1f5
+        if ((flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
ced1f5
+            *skip_data = true;
ced1f5
+        } else {
ced1f5
+            return ERANGE;
ced1f5
+        }
ced1f5
+    }
ced1f5
+
ced1f5
     return 0;
ced1f5
 }
ced1f5
 
ced1f5
@@ -128,18 +177,14 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
ced1f5
     gid_t *new_groups;
ced1f5
     size_t idx;
ced1f5
     bool skip_mc = false;
ced1f5
+    bool skip_data = false;
ced1f5
 
ced1f5
-    ret = check_flags(flags);
ced1f5
+    ret = check_flags(inp, flags, &skip_mc, &skip_data);
ced1f5
     if (ret != 0) {
ced1f5
         return ret;
ced1f5
     }
ced1f5
 
ced1f5
-    if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
ced1f5
-            || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
ced1f5
-        skip_mc = true;
ced1f5
-    }
ced1f5
-
ced1f5
-    if (!skip_mc) {
ced1f5
+    if (!skip_mc && !skip_data) {
ced1f5
         ret = sss_nss_mc_get(inp);
ced1f5
         switch (ret) {
ced1f5
         case 0:
ced1f5
@@ -159,7 +204,7 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
ced1f5
 
ced1f5
     sss_nss_timedlock(timeout, &time_left);
ced1f5
 
ced1f5
-    if (!skip_mc) {
ced1f5
+    if (!skip_mc && !skip_data) {
ced1f5
         /* previous thread might already initialize entry in mmap cache */
ced1f5
         ret = sss_nss_mc_get(inp);
ced1f5
         switch (ret) {
ced1f5
@@ -196,6 +241,12 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
ced1f5
         goto out;
ced1f5
     }
ced1f5
 
ced1f5
+    if (skip_data) {
ced1f5
+        /* No data requested, just return the return code */
ced1f5
+        ret = 0;
ced1f5
+        goto out;
ced1f5
+    }
ced1f5
+
ced1f5
     if (inp->cmd == SSS_NSS_INITGR || inp->cmd == SSS_NSS_INITGR_EX) {
ced1f5
         if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start))
ced1f5
                     < num_results) {
ced1f5
@@ -311,10 +362,6 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
ced1f5
         .result.pwrep.buffer = buffer,
ced1f5
         .result.pwrep.buflen = buflen};
ced1f5
 
ced1f5
-    if (buffer == NULL || buflen == 0) {
ced1f5
-        return ERANGE;
ced1f5
-    }
ced1f5
-
ced1f5
     ret = make_name_flag_req_data(name, flags, &inp.rd);
ced1f5
     if (ret != 0) {
ced1f5
         return ret;
ced1f5
@@ -346,10 +393,6 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
ced1f5
         .result.pwrep.buffer = buffer,
ced1f5
         .result.pwrep.buflen = buflen};
ced1f5
 
ced1f5
-    if (buffer == NULL || buflen == 0) {
ced1f5
-        return ERANGE;
ced1f5
-    }
ced1f5
-
ced1f5
     SAFEALIGN_COPY_UINT32(&req_data[0], &uid, NULL);
ced1f5
     SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
ced1f5
     *result = NULL;
ced1f5
@@ -373,10 +416,6 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
ced1f5
         .result.grrep.buffer = buffer,
ced1f5
         .result.grrep.buflen = buflen};
ced1f5
 
ced1f5
-    if (buffer == NULL || buflen == 0) {
ced1f5
-        return ERANGE;
ced1f5
-    }
ced1f5
-
ced1f5
     ret = make_name_flag_req_data(name, flags, &inp.rd);
ced1f5
     if (ret != 0) {
ced1f5
         return ret;
ced1f5
@@ -407,10 +446,6 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
ced1f5
         .result.grrep.buffer = buffer,
ced1f5
         .result.grrep.buflen = buflen};
ced1f5
 
ced1f5
-    if (buffer == NULL || buflen == 0) {
ced1f5
-        return ERANGE;
ced1f5
-    }
ced1f5
-
ced1f5
     SAFEALIGN_COPY_UINT32(&req_data[0], &gid, NULL);
ced1f5
     SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
ced1f5
     *result = NULL;
ced1f5
@@ -434,10 +469,6 @@ int sss_nss_getgrouplist_timeout(const char *name, gid_t group,
ced1f5
         .input.name = name,
ced1f5
         .cmd = SSS_NSS_INITGR_EX};
ced1f5
 
ced1f5
-    if (groups == NULL || ngroups == NULL || *ngroups == 0) {
ced1f5
-        return EINVAL;
ced1f5
-    }
ced1f5
-
ced1f5
     ret = make_name_flag_req_data(name, flags, &inp.rd);
ced1f5
     if (ret != 0) {
ced1f5
         return ret;
ced1f5
-- 
ced1f5
2.13.6
ced1f5