diff options
| author | Mohammed Rafi KC <rkavunga@redhat.com> | 2018-08-03 15:23:45 +0530 | 
|---|---|---|
| committer | Amar Tumballi <amarts@redhat.com> | 2018-08-23 03:45:12 +0000 | 
| commit | a777df08ec8100a8d9067faf14b1058f09cf862a (patch) | |
| tree | 9befc3822b8cd66a96c44798f57211b64c65e041 | |
| parent | 9d2083f2ce37e1f04f5df6040ab493ab98a6f6aa (diff) | |
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 <rkavunga@redhat.com>
| -rw-r--r-- | xlators/features/snapview-server/src/snapview-server.c | 132 | 
1 files changed, 131 insertions, 1 deletions
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 <pthread.h> +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"  | 
