From a777df08ec8100a8d9067faf14b1058f09cf862a Mon Sep 17 00:00:00 2001 From: Mohammed Rafi KC Date: Fri, 3 Aug 2018 15:23:45 +0530 Subject: snapview/server: Set uid,gid,and groups for gfapi call Before calling gfapi from snapd, we need to set uid, gid and groups in the context. This is required to do the validation from posix acl xlator. Change-Id: I181bea2570a69554ff363bf5a52478ff0363ea47 fixes: bz#1614168 Signed-off-by: Mohammed Rafi KC --- .../features/snapview-server/src/snapview-server.c | 132 ++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) (limited to 'xlators/features') diff --git a/xlators/features/snapview-server/src/snapview-server.c b/xlators/features/snapview-server/src/snapview-server.c index 9b3f3a54ea7..9e109e213c9 100644 --- a/xlators/features/snapview-server/src/snapview-server.c +++ b/xlators/features/snapview-server/src/snapview-server.c @@ -18,6 +18,38 @@ #include "syscall.h" #include +int +gf_setcredentials (uid_t *uid, gid_t *gid, uint16_t ngrps, uint32_t *groups) +{ + int ret = 0; + + if (uid) { + ret = glfs_setfsuid(*uid); + if (ret != 0) { + gf_log ("snapview-server", GF_LOG_ERROR, "failed to set uid " + "%u in thread context", *uid); + return ret; + } + } + if (gid) { + ret = glfs_setfsgid(*gid); + if (ret != 0) { + gf_log ("snapview-server", GF_LOG_ERROR, "failed to set gid " + "%u in thread context", *gid); + return ret; + } + } + + if (ngrps != 0 && groups) { + ret = glfs_setfsgroups(ngrps, groups); + if (ret != 0) { + gf_log ("snapview-server", GF_LOG_ERROR, "failed to set " + "groups in thread context"); + return ret; + } + } + return 0; +} int32_t svs_lookup_entry_point (xlator_t *this, loc_t *loc, inode_t *parent, @@ -514,13 +546,22 @@ svs_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) snap_dirent_t *dirent = NULL; gf_boolean_t entry_point_key = _gf_false; gf_boolean_t entry_point = _gf_false; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("svs", this, out); GF_VALIDATE_OR_GOTO (this->name, this->private, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, loc, out); GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + + /* For lookups sent on inodes (i.e not parent inode + basename, but direct inode itself which usually is a nameless lookup or revalidate on the inode), loc->name will not be there. Get it from path if @@ -676,13 +717,21 @@ svs_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, glfs_fd_t *glfd = NULL; glfs_t *fs = NULL; glfs_object_t *object = NULL; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, fd, out); GF_VALIDATE_OR_GOTO (this->name, loc, out); GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + inode_ctx = svs_inode_ctx_get (this, loc->inode); if (!inode_ctx) { gf_log (this->name, GF_LOG_ERROR, "inode context not found " @@ -803,12 +852,20 @@ svs_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, char *value = 0; ssize_t size = 0; dict_t *dict = NULL; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO ("snap-view-daemon", frame, out); + GF_VALIDATE_OR_GOTO ("snap-view-daemon", frame->root, out); GF_VALIDATE_OR_GOTO ("snap-view-daemon", loc, out); GF_VALIDATE_OR_GOTO ("snap-view-daemon", loc->inode, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + inode_ctx = svs_inode_ctx_get (this, loc->inode); if (!inode_ctx) { gf_log (this->name, GF_LOG_ERROR, "inode context not found " @@ -1111,11 +1168,19 @@ svs_flush (call_frame_t *frame, xlator_t *this, int ret = -1; uint64_t value = 0; svs_inode_t *inode_ctx = NULL; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snapview-server", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, fd, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + inode_ctx = svs_inode_ctx_get (this, fd->inode); if (!inode_ctx) { gf_log (this->name, GF_LOG_ERROR, "inode context not found for" @@ -1464,14 +1529,22 @@ svs_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, int op_errno = EINVAL; svs_inode_t *parent_ctx = NULL; svs_fd_t *svs_fd = NULL; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, unwind); GF_VALIDATE_OR_GOTO (this->name, frame, unwind); + GF_VALIDATE_OR_GOTO (this->name, frame->root, unwind); GF_VALIDATE_OR_GOTO (this->name, fd, unwind); GF_VALIDATE_OR_GOTO (this->name, fd->inode, unwind); INIT_LIST_HEAD (&entries.list); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto unwind; + } + parent_ctx = svs_inode_ctx_get (this, fd->inode); if (!parent_ctx) { gf_log (this->name, GF_LOG_ERROR, "failed to get the inode " @@ -1720,12 +1793,20 @@ svs_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) glfs_object_t *object = NULL; struct stat stat = {0, }; int ret = -1; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, loc, out); GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + /* Instead of doing the check of whether it is a entry point directory or not by checking the name of the entry and then deciding what to do, just check the inode context and decide what to be done. @@ -1781,9 +1862,11 @@ svs_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) int ret = -1; glfs_fd_t *glfd = NULL; svs_fd_t *sfd = NULL; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, fd, out); GF_VALIDATE_OR_GOTO (this->name, fd->inode, out); @@ -1792,6 +1875,12 @@ svs_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) to do, just check the inode context and decide what to be done. */ + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + inode_ctx = svs_inode_ctx_get (this, fd->inode); if (!inode_ctx) { gf_log (this->name, GF_LOG_ERROR, "inode context not found for" @@ -1847,12 +1936,20 @@ svs_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) glfs_t *fs = NULL; glfs_object_t *object = NULL; int ret = -1; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, loc, out); GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + /* Instead of doing the check of whether it is a entry point directory or not by checking the name of the entry and then deciding what to do, just check the inode context and decide what to be done. @@ -1885,7 +1982,6 @@ out: return 0; } - int32_t svs_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) @@ -1897,14 +1993,18 @@ svs_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, glfs_fd_t *glfd = NULL; glfs_t *fs = NULL; glfs_object_t *object = NULL; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, fd, out); GF_VALIDATE_OR_GOTO (this->name, loc, out); GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + root = frame->root; + inode_ctx = svs_inode_ctx_get (this, loc->inode); if (!inode_ctx) { gf_log (this->name, GF_LOG_ERROR, "inode context for %s " @@ -1919,6 +2019,11 @@ svs_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, op_errno, out); + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + glfd = glfs_h_open (fs, object, flags); if (!glfd) { gf_log (this->name, GF_LOG_ERROR, "glfs_h_open on %s failed " @@ -1962,15 +2067,23 @@ svs_readv (call_frame_t *frame, xlator_t *this, struct stat fstatbuf = {0, }; glfs_fd_t *glfd = NULL; struct iatt stbuf = {0, }; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, fd, out); GF_VALIDATE_OR_GOTO (this->name, fd->inode, out); priv = this->private; VALIDATE_OR_GOTO (priv, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + sfd = svs_fd_ctx_get_or_new (this, fd); if (!sfd) { gf_log (this->name, GF_LOG_ERROR, "failed to get the fd " @@ -2040,12 +2153,20 @@ svs_readlink (call_frame_t *frame, xlator_t *this, struct iatt stbuf = {0, }; int ret = -1; struct stat stat = {0, }; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, loc, out); GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + inode_ctx = svs_inode_ctx_get (this, loc->inode); if (!inode_ctx) { gf_log (this->name, GF_LOG_ERROR, "failed to get inode context " @@ -2103,12 +2224,21 @@ svs_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int mask, svs_inode_t *inode_ctx = NULL; gf_boolean_t is_fuse_call = 0; int mode = 0; + call_stack_t *root = NULL; GF_VALIDATE_OR_GOTO ("svs", this, out); GF_VALIDATE_OR_GOTO (this->name, this->private, out); + GF_VALIDATE_OR_GOTO (this->name, frame, out); + GF_VALIDATE_OR_GOTO (this->name, frame->root, out); GF_VALIDATE_OR_GOTO (this->name, loc, out); GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + root = frame->root; + op_ret = gf_setcredentials (&root->uid, &root->gid, root->ngrps, root->groups); + if (op_ret != 0) { + goto out; + } + inode_ctx = svs_inode_ctx_get (this, loc->inode); if (!inode_ctx) { gf_log (this->name, GF_LOG_ERROR, "inode context not found for" -- cgit