]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
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)
committerblinke <Burkhard.Linke@computational.bio.uni-giessen.de>
Mon, 10 Aug 2015 15:43:10 +0000 (17:43 +0200)
src/client/Client.cc

index 280d0d3dfc378ab1d096a6e0cbbd4f5aba646701..ce0d3338649603415a3f888ecea0b84b5e1302a6 100644 (file)
@@ -91,6 +91,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 << " "
 
@@ -4545,6 +4550,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) {
@@ -4554,11 +4563,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)