diff options
| author | Gaurav <gaurav@gluster.com> | 2011-05-09 23:23:21 +0000 | 
|---|---|---|
| committer | Anand Avati <avati@gluster.com> | 2011-05-19 20:14:32 -0700 | 
| commit | 5f1efbc32d69097a00b56eec3a2ca2aa26ae084c (patch) | |
| tree | a70f5575cbcdd093fa9acd6f4b1e3e7d3817de24 | |
| parent | 0492851b0264956bfc0a2d4b9f7793ff82241bd0 (diff) | |
Access-Control : Sticky bit validation for rename, unlink and rmdir.v3.1.5qa1
Signed-off-by: Gaurav <gaurav@gluster.com>
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 2886 (No sticky bit validation in access control)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2886
| -rw-r--r-- | xlators/features/access-control/src/access-control.c | 220 | 
1 files changed, 197 insertions, 23 deletions
diff --git a/xlators/features/access-control/src/access-control.c b/xlators/features/access-control/src/access-control.c index a4b40159e..dc02b1615 100644 --- a/xlators/features/access-control/src/access-control.c +++ b/xlators/features/access-control/src/access-control.c @@ -753,10 +753,8 @@ ac_unlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          if (op_ret == -1)                  goto out; -        op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid, -                                 frame->root->groups, frame->root->ngrps, -                                 ACCTEST_WRITE, ACCTEST_ANY, &op_errno); -        if (op_ret == -1) { +        if (frame->root->uid != buf->ia_uid) { +                op_ret = -1;                  op_errno = EACCES;                  goto out;          } @@ -772,6 +770,48 @@ out:          return 0;  } +int32_t +ac_unlink_parent_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                    int32_t op_ret, int32_t op_errno, struct iatt *buf) +{ +        call_stub_t     *stub = NULL; + +        stub = frame->local; +        if (op_ret == -1) +                goto out; + +        if (buf->ia_prot.sticky == 0) { +                op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid, +                                         frame->root->groups, frame->root->ngrps, +                                         ACCTEST_WRITE, ACCTEST_ANY, &op_errno); +                if (op_ret == -1) { +                        op_errno = EACCES; +                        goto out; +                } +        } else { +                if ((frame->root->uid == 0) || +                    (frame->root->uid == buf->ia_uid)) +                        goto access; + +                STACK_WIND (frame, ac_unlink_stat_cbk, FIRST_CHILD (this), +                            FIRST_CHILD (this)->fops->stat, &stub->args.unlink.loc); +                goto out; +        } + +access: +        stub = __get_frame_stub (frame); +        call_resume (stub); +out: +        if (op_ret < 0) { +                stub = __get_frame_stub (frame); +                STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL); +                if (stub) +                        call_stub_destroy (stub); +        } + +        return 0; +} +  int32_t  ac_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) @@ -797,7 +837,7 @@ ac_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)          if (ret < 0)                  goto out; -        STACK_WIND (frame, ac_unlink_stat_cbk, FIRST_CHILD (this), +        STACK_WIND (frame, ac_unlink_parent_stat_cbk, FIRST_CHILD (this),                      FIRST_CHILD (this)->fops->stat, &parentloc);          loc_wipe (&parentloc);          ret = 0; @@ -834,10 +874,8 @@ ac_rmdir_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          if (op_ret == -1)                  goto out; -        op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid, -                                 frame->root->groups, frame->root->ngrps, -                                 ACCTEST_WRITE, ACCTEST_ANY, &op_errno); -        if (op_ret == -1) { +        if (frame->root->uid != buf->ia_uid) { +                op_ret = -1;                  op_errno = EACCES;                  goto out;          } @@ -853,6 +891,48 @@ out:          return 0;  } +int32_t +ac_rmdir_parent_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                   int32_t op_ret, int32_t op_errno, struct iatt *buf) +{ +        call_stub_t     *stub = NULL; + +        stub = frame->local; +        if (op_ret == -1) +                goto out; + +        if (buf->ia_prot.sticky == 0) { +                op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid, +                                         frame->root->groups, frame->root->ngrps, +                                         ACCTEST_WRITE, ACCTEST_ANY, &op_errno); +                if (op_ret == -1) { +                        op_errno = EACCES; +                        goto out; +                } +        } else { +                if ((frame->root->uid == 0) || +                    (frame->root->uid == buf->ia_uid)) +                        goto access; + +                STACK_WIND (frame, ac_rmdir_stat_cbk, FIRST_CHILD (this), +                            FIRST_CHILD (this)->fops->stat, &stub->args.rmdir.loc); +                goto out; +        } + +access: +        stub = __get_frame_stub (frame); +        call_resume (stub); +out: +        if (op_ret < 0) { +                stub = __get_frame_stub (frame); +                STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL); +                if (stub) +                        call_stub_destroy (stub); +        } + +        return 0; +} +  int  ac_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags) @@ -878,7 +958,7 @@ ac_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)          if (ret < 0)                  goto out; -        STACK_WIND (frame, ac_rmdir_stat_cbk, FIRST_CHILD (this), +        STACK_WIND (frame, ac_rmdir_parent_stat_cbk, FIRST_CHILD (this),                      FIRST_CHILD (this)->fops->stat, &parentloc);          loc_wipe (&parentloc);          ret = 0; @@ -999,21 +1079,66 @@ ac_rename_dst_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          call_stub_t     *stub = NULL;          stub = __get_frame_stub (frame); + +        if ((op_ret == -1) && (op_errno == ENOENT)) +                goto access; +          if (op_ret == -1)                  goto out; -        op_ret = ac_test_access (buf, frame->root->uid, -                                 frame->root->gid, frame->root->groups, -                                 frame->root->ngrps, ACCTEST_WRITE, -                                 ACCTEST_ANY, &op_errno); -        if (op_ret == -1) { +        if (frame->root->uid == buf->ia_uid) +                goto access; +        else { +                op_ret = -1;                  op_errno = EACCES; -               goto out; +                goto out; +        } +access: +        call_resume (stub); +out: +        if (op_ret < 0) { +                STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL, +                                     NULL, NULL, NULL); +                if (stub) +                        call_stub_destroy (stub); +        } + +        return 0; +} +int32_t +ac_rename_dst_parent_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                        int32_t op_ret, int32_t op_errno, struct iatt *buf) +{ +        call_stub_t     *stub = NULL; + +        stub = frame->local; +        if (op_ret == -1) +                goto out; + +        if (buf->ia_prot.sticky == 0) { +                op_ret = ac_test_access (buf, frame->root->uid, +                                         frame->root->gid, frame->root->groups, +                                         frame->root->ngrps, ACCTEST_WRITE, +                                         ACCTEST_ANY, &op_errno); +                if (op_ret == -1) { +                        op_errno = EACCES; +                        goto out; +                } +        } else { +                if ((frame->root->uid == 0) || +                    (frame->root->uid == buf->ia_uid)) +                        goto access; +                STACK_WIND (frame, ac_rename_dst_stat_cbk, FIRST_CHILD (this), +                             FIRST_CHILD (this)->fops->stat, &stub->args.rename.new); +                goto out;          } +access: +        stub = __get_frame_stub (frame);          call_resume (stub);  out:          if (op_ret < 0) { +                stub = __get_frame_stub (frame);                  STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL,                                       NULL, NULL, NULL);                  if (stub) @@ -1035,11 +1160,8 @@ ac_rename_src_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          if (op_ret == -1)                  goto out; -        op_ret = ac_test_access (buf, frame->root->uid, -                                 frame->root->gid, frame->root->groups, -                                 frame->root->ngrps, ACCTEST_WRITE, -                                 ACCTEST_ANY, &op_errno); -        if (op_ret == -1) { +        if (buf->ia_uid != frame->root->uid) { +                op_ret = -1;                  op_errno = EACCES;                  goto out;          } @@ -1050,7 +1172,59 @@ ac_rename_src_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  goto out;          } -        STACK_WIND (frame, ac_rename_dst_stat_cbk, FIRST_CHILD (this), +        STACK_WIND (frame, ac_rename_dst_parent_stat_cbk, FIRST_CHILD (this), +                    FIRST_CHILD (this)->fops->stat, &parentloc); +        loc_wipe (&parentloc); + +out: +        if (op_ret < 0) { +                /* Erase the stored stub before unwinding. */ +                stub = __get_frame_stub (frame); +                if (stub) +                        call_stub_destroy (stub); +                STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL, +                                     NULL, NULL, NULL); +        } +        return 0; +} + +int32_t +ac_rename_src_parent_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                        int32_t op_ret, int32_t op_errno, struct iatt *buf) +{ +        call_stub_t     *stub = NULL; +        loc_t           parentloc = {0, }; + +        stub = frame->local; +        if (op_ret == -1) +                goto out; + +        if (buf->ia_prot.sticky == 0) { +                op_ret = ac_test_access (buf, frame->root->uid, +                                         frame->root->gid, frame->root->groups, +                                         frame->root->ngrps, ACCTEST_WRITE, +                                         ACCTEST_ANY, &op_errno); +                if (op_ret == -1) { +                        op_errno = EACCES; +                        goto out; +                } +        } else { +                if ((buf->ia_uid == frame->root->uid) || +                    (frame->root->uid ==0)) +                        goto access; +                STACK_WIND (frame, ac_rename_src_stat_cbk, FIRST_CHILD (this), +                             FIRST_CHILD (this)->fops->stat, &stub->args.rename.old); +                goto out; +        } + +access: +        op_ret = ac_parent_loc_fill (&parentloc, &stub->args.rename.new); +        if (op_ret < 0) { +                op_errno = -EFAULT; +                goto out; +        } + +        STACK_WIND (frame, ac_rename_dst_parent_stat_cbk, FIRST_CHILD (this),                      FIRST_CHILD (this)->fops->stat, &parentloc);          loc_wipe (&parentloc); @@ -1092,7 +1266,7 @@ ac_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)          if (ret < 0)                  goto out; -        STACK_WIND (frame, ac_rename_src_stat_cbk, FIRST_CHILD (this), +        STACK_WIND (frame, ac_rename_src_parent_stat_cbk, FIRST_CHILD (this),                      FIRST_CHILD (this)->fops->stat, &parentloc);          loc_wipe (&parentloc);          ret = 0;  | 
