Skip to content

Commit

Permalink
Merge 6604: hammer: client: added permission check based on getgrouplist
Browse files Browse the repository at this point in the history
Reviewed-by: Xiaoxi Chen <xiaoxchen@ebay.com>
  • Loading branch information
Chen committed Feb 26, 2016
2 parents 830c05d + 589606b commit 500c2b7
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 59 deletions.
3 changes: 3 additions & 0 deletions configure.ac
Expand Up @@ -932,6 +932,9 @@ AC_CHECK_FUNC([fallocate],
[AC_DEFINE([CEPH_HAVE_FALLOCATE], [], [fallocate(2) is supported])],
[])

# getgrouplist
AC_CHECK_FUNCS([getgrouplist])

#
# Test for time-related `struct stat` members.
#
Expand Down
52 changes: 47 additions & 5 deletions src/client/Client.cc
Expand Up @@ -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 << " "

Expand Down Expand Up @@ -4386,17 +4391,54 @@ int Client::check_permissions(Inode *in, int flags, int uid, int gid)
gid_t *sgids = NULL;
int sgid_count = 0;
if (getgroups_cb) {
sgid_count = getgroups_cb(callback_handle, uid, &sgids);
if (sgid_count < 0) {
sgid_count = getgroups_cb(callback_handle, &sgids);
if (sgid_count > 0) {
ldout(cct, 3) << "getgroups failed!" << dendl;
return sgid_count;
}
}
#if HAVE_GETGROUPLIST
if (sgid_count <= 0) {
// use PAM to get the group list
// initial number of group entries, defaults to posix standard of 16
// PAM implementations may provide more than 16 groups....
sgid_count = 16;
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
void *_realloc = NULL;
if ((_realloc = realloc(sgids, sgid_count * sizeof(gid_t))) == NULL) {
ldout(cct, 3) << "allocating group memory failed" << dendl;
free(sgids);
return -EACCES;
}
sgids = (gid_t*)_realloc;
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)
Expand Down
2 changes: 1 addition & 1 deletion src/client/Client.h
Expand Up @@ -138,7 +138,7 @@ typedef void (*client_dentry_callback_t)(void *handle, vinodeno_t dirino,
vinodeno_t ino, string& name);
typedef int (*client_remount_callback_t)(void *handle);

typedef int (*client_getgroups_callback_t)(void *handle, uid_t uid, gid_t **sgids);
typedef int (*client_getgroups_callback_t)(void *handle, gid_t **sgids);
typedef void(*client_switch_interrupt_callback_t)(void *req, void *data);

struct client_callback_args {
Expand Down

0 comments on commit 500c2b7

Please sign in to comment.