]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: added permission check based on getgrouplist
authorblinke <Burkhard.Linke@computational.bio.uni-giessen.de>
Mon, 10 Aug 2015 15:43:10 +0000 (17:43 +0200)
committerYan, Zheng <zyan@redhat.com>
Thu, 3 Mar 2016 12:30:07 +0000 (20:30 +0800)
Fixes: #13268
Signed-off-by: Yan, Zheng <zyan@redhat.com>
(cherry picked from commit f04c8da5432174874ca97d11a5b2fef56f95d73d)

src/client/Client.cc

index 0d85db29ce8c0de7f40622a9bcd939afea3734d7..9862f9b8d14239e8a2c9ce8adfb24a446e48af51 100644 (file)
@@ -90,6 +90,11 @@ using namespace std;
 #include "include/assert.h"
 #include "include/stat.h"
 
+#if HAVE_GETGROUPLIST
+#include <grp.h>
+#include <pwd.h>
+#endif
+
 #undef dout_prefix
 #define dout_prefix *_dout << "client." << whoami << " "
 
@@ -4383,6 +4388,10 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient
 
 int Client::check_permissions(Inode *in, int flags, int uid, int gid)
 {
+  // initial number of group entries, defaults to posix standard of 16
+  // PAM implementations may provide more than 16 groups....
+  int initial_group_count = 16;
+
   gid_t *sgids = NULL;
   int sgid_count = 0;
   if (getgroups_cb) {
@@ -4392,11 +4401,45 @@ int Client::check_permissions(Inode *in, int flags, int uid, int gid)
       return sgid_count;
     }
   }
+#if HAVE_GETGROUPLIST
+  else {
+    //use PAM to get the group list
+    sgid_count = initial_group_count;
+    sgids = (gid_t*)malloc(sgid_count * sizeof(gid_t));
+    if (sgids == NULL) {
+      ldout(cct, 3) << "allocating group memory failed" << dendl;
+      return -EACCES;
+    }
+    struct passwd *pw;
+    pw = getpwuid(uid);
+    if (pw == NULL) {
+      ldout(cct, 3) << "getting user entry failed" << dendl;
+      return -EACCES;
+    }
+    while (1) {
+      if (getgrouplist(pw->pw_name, gid, sgids, &sgid_count) == -1) {
+       // we need to resize the group list and try again
+       sgids = (gid_t*)realloc(sgids, sgid_count * sizeof(gid_t));
+       if (sgids == NULL) {
+         ldout(cct, 3) << "allocating group memory failed" << dendl;
+         return -EACCES;
+       }
+       continue;
+      }
+      // list was successfully retrieved
+      break;
+    }
+  }
+#endif
+
   // check permissions before doing anything else
+  int ret = 0;
   if (uid != 0 && !in->check_mode(uid, gid, sgids, sgid_count, flags)) {
-    return -EACCES;
+    ret = -EACCES;
   }
-  return 0;
+  if (sgids)
+    free(sgids);
+  return ret;
 }
 
 vinodeno_t Client::_get_vino(Inode *in)