Merge PR #21132 into master

* refs/pull/21132/head:
	client: remove getgroups_cb
	client: remove _getgrouplist
	client: have init_gids just set alloced_gids to true
	client: remove init_groups
	fuse: handle errors appropriately when getting group list

Reviewed-by: Jos Collin <jcollin@redhat.com>
Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>
Reviewed-by: Zheng Yan <zyan@redhat.com>
This commit is contained in:
Patrick Donnelly 2018-04-09 21:33:06 -07:00
commit acc6f2eddb
No known key found for this signature in database
GPG Key ID: 3A2A7E25BEA8AADB
4 changed files with 32 additions and 106 deletions

View File

@ -236,7 +236,6 @@ Client::Client(Messenger *m, MonClient *mc, Objecter *objecter_)
remount_cb(NULL),
ino_invalidate_cb(NULL),
dentry_invalidate_cb(NULL),
getgroups_cb(NULL),
umask_cb(NULL),
can_invalidate_dentries(false),
async_ino_invalidator(m->cct),
@ -5135,63 +5134,6 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient
m->put();
}
int Client::_getgrouplist(gid_t** sgids, uid_t uid, gid_t gid)
{
// cppcheck-suppress variableScope
int sgid_count;
gid_t *sgid_buf;
if (getgroups_cb) {
sgid_count = getgroups_cb(callback_handle, &sgid_buf);
if (sgid_count > 0) {
*sgids = sgid_buf;
return sgid_count;
}
}
#if HAVE_GETGROUPLIST
struct passwd *pw;
pw = getpwuid(uid);
if (pw == NULL) {
ldout(cct, 3) << "getting user entry failed" << dendl;
return -errno;
}
//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;
sgid_buf = (gid_t*)malloc(sgid_count * sizeof(gid_t));
if (sgid_buf == NULL) {
ldout(cct, 3) << "allocating group memory failed" << dendl;
return -ENOMEM;
}
while (1) {
#if defined(__APPLE__)
if (getgrouplist(pw->pw_name, gid, (int*)sgid_buf, &sgid_count) == -1) {
#else
if (getgrouplist(pw->pw_name, gid, sgid_buf, &sgid_count) == -1) {
#endif
// we need to resize the group list and try again
void *_realloc = NULL;
if ((_realloc = realloc(sgid_buf, sgid_count * sizeof(gid_t))) == NULL) {
ldout(cct, 3) << "allocating group memory failed" << dendl;
free(sgid_buf);
return -ENOMEM;
}
sgid_buf = (gid_t*)_realloc;
continue;
}
// list was successfully retrieved
break;
}
*sgids = sgid_buf;
return sgid_count;
#else
return 0;
#endif
}
int Client::inode_permission(Inode *in, const UserPerm& perms, unsigned want)
{
if (perms.uid() == 0)
@ -10032,7 +9974,6 @@ void Client::ll_register_callbacks(struct client_callback_args *args)
ldout(cct, 10) << __func__ << " cb " << args->handle
<< " invalidate_ino_cb " << args->ino_cb
<< " invalidate_dentry_cb " << args->dentry_cb
<< " getgroups_cb" << args->getgroups_cb
<< " switch_interrupt_cb " << args->switch_intr_cb
<< " remount_cb " << args->remount_cb
<< dendl;
@ -10053,7 +9994,6 @@ void Client::ll_register_callbacks(struct client_callback_args *args)
remount_cb = args->remount_cb;
remount_finisher.start();
}
getgroups_cb = args->getgroups_cb;
umask_cb = args->umask_cb;
}
@ -13942,13 +13882,6 @@ void Client::handle_conf_change(const struct md_config_t *conf,
}
}
void Client::init_groups(UserPerm *perms)
{
gid_t *sgids;
int count = _getgrouplist(&sgids, perms->uid(), perms->gid());
perms->init_gids(sgids, count);
}
void intrusive_ptr_add_ref(Inode *in)
{
in->get();

View File

@ -131,7 +131,6 @@ 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, gid_t **sgids);
typedef void(*client_switch_interrupt_callback_t)(void *handle, void *data);
typedef mode_t (*client_umask_callback_t)(void *handle);
@ -144,7 +143,6 @@ struct client_callback_args {
client_dentry_callback_t dentry_cb;
client_switch_interrupt_callback_t switch_intr_cb;
client_remount_callback_t remount_cb;
client_getgroups_callback_t getgroups_cb;
client_umask_callback_t umask_cb;
};
@ -272,7 +270,6 @@ class Client : public Dispatcher, public md_config_obs_t {
client_remount_callback_t remount_cb;
client_ino_callback_t ino_invalidate_cb;
client_dentry_callback_t dentry_invalidate_cb;
client_getgroups_callback_t getgroups_cb;
client_umask_callback_t umask_cb;
bool can_invalidate_dentries;
@ -863,8 +860,6 @@ private:
MAY_READ = 4,
};
void init_groups(UserPerm *groups);
int inode_permission(Inode *in, const UserPerm& perms, unsigned want);
int xattr_permission(Inode *in, const char *name, unsigned want,
const UserPerm& perms);
@ -877,7 +872,6 @@ private:
int may_hardlink(Inode *in, const UserPerm& perms);
int _getattr_for_perm(Inode *in, const UserPerm& perms);
int _getgrouplist(gid_t **sgids, uid_t uid, gid_t gid);
vinodeno_t _get_vino(Inode *in);
inodeno_t _get_inodeno(Inode *in);

View File

@ -79,8 +79,8 @@ public:
void init_gids(gid_t* _gids, int count) {
gids = _gids;
gid_count = count;
alloced_gids = true;
}
void take_gids() { alloced_gids = true; }
void shallow_copy(const UserPerm& o) {
m_uid = o.m_uid;
m_gid = o.m_gid;

View File

@ -129,20 +129,20 @@ static int getgroups(fuse_req_t req, gid_t **sgids)
return -ENOSYS;
}
static int getgroups_cb(void *handle, gid_t **sgids)
static void get_fuse_groups(UserPerm& perms, fuse_req_t req)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *) handle;
fuse_req_t req = cfuse->get_fuse_req();
return getgroups(req, sgids);
}
if (g_conf->get_val<bool>("fuse_set_user_groups")) {
gid_t *gids = NULL;
int count = getgroups(req, &gids);
#define GET_GROUPS(perms, req) { \
if (g_conf->get_val<bool>("fuse_set_user_groups")) { \
gid_t *gids = NULL; \
int count = getgroups(req, &gids); \
perms.init_gids(gids, count); \
perms.take_gids(); \
} }
if (count > 0) {
perms.init_gids(gids, count);
} else if (count < 0) {
derr << __func__ << ": getgroups failed: " << cpp_strerror(-count)
<< dendl;
}
}
}
static CephFuse::Handle *fuse_ll_req_prepare(fuse_req_t req)
@ -160,7 +160,7 @@ static void fuse_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
Inode *i2, *i1 = cfuse->iget(parent); // see below
int r;
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
if (!i1)
{
@ -202,7 +202,7 @@ static void fuse_ll_getattr(fuse_req_t req, fuse_ino_t ino,
Inode *in = cfuse->iget(ino);
struct stat stbuf;
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
(void) fi; // XXX
@ -224,7 +224,7 @@ static void fuse_ll_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int mask = 0;
if (to_set & FUSE_SET_ATTR_MODE) mask |= CEPH_SETATTR_MODE;
@ -261,7 +261,7 @@ static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_setxattr(in, name, value, size, flags, perms);
fuse_reply_err(req, -r);
@ -276,7 +276,7 @@ static void fuse_ll_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
Inode *in = cfuse->iget(ino);
char buf[size];
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_listxattr(in, buf, size, perms);
if (size == 0 && r >= 0)
@ -301,7 +301,7 @@ static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
Inode *in = cfuse->iget(ino);
char buf[size];
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_getxattr(in, name, buf, size, perms);
if (size == 0 && r >= 0)
@ -321,7 +321,7 @@ static void fuse_ll_removexattr(fuse_req_t req, fuse_ino_t ino,
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_removexattr(in, name, perms);
fuse_reply_err(req, -r);
@ -338,7 +338,7 @@ static void fuse_ll_opendir(fuse_req_t req, fuse_ino_t ino,
void *dirp;
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_opendir(in, fi->flags, (dir_result_t **)&dirp,
perms);
@ -359,7 +359,7 @@ static void fuse_ll_readlink(fuse_req_t req, fuse_ino_t ino)
Inode *in = cfuse->iget(ino);
char buf[PATH_MAX + 1]; // leave room for a null terminator
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_readlink(in, buf, sizeof(buf) - 1, perms);
if (r >= 0) {
@ -380,7 +380,7 @@ static void fuse_ll_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
Inode *i2, *i1 = cfuse->iget(parent);
struct fuse_entry_param fe;
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
memset(&fe, 0, sizeof(fe));
@ -409,7 +409,7 @@ static void fuse_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
memset(&fe, 0, sizeof(fe));
UserPerm perm(ctx->uid, ctx->gid);
GET_GROUPS(perm, req);
get_fuse_groups(perm, req);
#ifdef HAVE_SYS_SYNCFS
auto fuse_multithreaded = cfuse->client->cct->_conf->get_val<bool>(
"fuse_multithreaded");
@ -455,7 +455,7 @@ static void fuse_ll_unlink(fuse_req_t req, fuse_ino_t parent, const char *name)
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(parent);
UserPerm perm(ctx->uid, ctx->gid);
GET_GROUPS(perm, req);
get_fuse_groups(perm, req);
int r = cfuse->client->ll_unlink(in, name, perm);
fuse_reply_err(req, -r);
@ -469,7 +469,7 @@ static void fuse_ll_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(parent);
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_rmdir(in, name, perms);
fuse_reply_err(req, -r);
@ -485,7 +485,7 @@ static void fuse_ll_symlink(fuse_req_t req, const char *existing,
Inode *i2, *i1 = cfuse->iget(parent);
struct fuse_entry_param fe;
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
memset(&fe, 0, sizeof(fe));
@ -511,7 +511,7 @@ static void fuse_ll_rename(fuse_req_t req, fuse_ino_t parent, const char *name,
Inode *in = cfuse->iget(parent);
Inode *nin = cfuse->iget(newparent);
UserPerm perm(ctx->uid, ctx->gid);
GET_GROUPS(perm, req);
get_fuse_groups(perm, req);
int r = cfuse->client->ll_rename(in, name, nin, newname, perm);
fuse_reply_err(req, -r);
@ -531,7 +531,7 @@ static void fuse_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
memset(&fe, 0, sizeof(fe));
UserPerm perm(ctx->uid, ctx->gid);
GET_GROUPS(perm, req);
get_fuse_groups(perm, req);
/*
* Note that we could successfully link, but then fail the subsequent
@ -570,7 +570,7 @@ static void fuse_ll_open(fuse_req_t req, fuse_ino_t ino,
Inode *in = cfuse->iget(ino);
Fh *fh = NULL;
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_open(in, fi->flags, &fh, perms);
if (r == 0) {
@ -778,7 +778,7 @@ static void fuse_ll_create(fuse_req_t req, fuse_ino_t parent, const char *name,
struct fuse_entry_param fe;
Fh *fh = NULL;
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
memset(&fe, 0, sizeof(fe));
@ -813,7 +813,7 @@ static void fuse_ll_statfs(fuse_req_t req, fuse_ino_t ino)
Inode *in = cfuse->iget(ino);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
UserPerm perms(ctx->uid, ctx->gid);
GET_GROUPS(perms, req);
get_fuse_groups(perms, req);
int r = cfuse->client->ll_statfs(in, &stbuf, perms);
if (r == 0)
@ -1178,7 +1178,6 @@ int CephFuse::Handle::start()
#if defined(__linux__)
remount_cb: remount_cb,
#endif
getgroups_cb: getgroups_cb,
#if !defined(__APPLE__)
umask_cb: umask_cb,
#endif