#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 << " "
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) {
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)