From b13ddc0690742b11802e59f34b539987d632ac58 Mon Sep 17 00:00:00 2001 From: blinke Date: Mon, 10 Aug 2015 17:43:10 +0200 Subject: [PATCH] client: added permission check based on getgrouplist Fixes: #13268 Signed-off-by: Yan, Zheng (cherry picked from commit f04c8da5432174874ca97d11a5b2fef56f95d73d) --- src/client/Client.cc | 47 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 0d85db29ce8c0..9862f9b8d1423 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -90,6 +90,11 @@ using namespace std; #include "include/assert.h" #include "include/stat.h" +#if HAVE_GETGROUPLIST +#include +#include +#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) -- 2.39.5