From 0492851b0264956bfc0a2d4b9f7793ff82241bd0 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Tue, 3 May 2011 04:46:13 +0000 Subject: Access-Control : Changes in setattr for posix compliance. Signed-off-by: Gaurav Signed-off-by: Anand Avati BUG: 1337 (gnfs: posix compliance test fails) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1337 --- .../features/access-control/src/access-control.c | 141 +++++++++++++++++---- 1 file changed, 116 insertions(+), 25 deletions(-) (limited to 'xlators') diff --git a/xlators/features/access-control/src/access-control.c b/xlators/features/access-control/src/access-control.c index 78a0629a8..a4b40159e 100644 --- a/xlators/features/access-control/src/access-control.c +++ b/xlators/features/access-control/src/access-control.c @@ -114,6 +114,8 @@ ac_test_group_access (struct iatt *ia, gid_t gid, gid_t *auxgids, int auxcount, */ if ((ia->ia_gid != gid) && (auxcount == 0)) { + gf_log (ACTRL, GF_LOG_DEBUG, "GID mismatch (orig: %d, user: %d)", + ia->ia_gid, gid); ret = -1; goto out; } @@ -131,6 +133,8 @@ ac_test_group_access (struct iatt *ia, gid_t gid, gid_t *auxgids, int auxcount, /* None of the gids match with the gid in the stat. */ if (testgid == -1) { + gf_log (ACTRL, GF_LOG_DEBUG, "None of the gids match with gid " + "on the stat"); ret = -1; goto out; } @@ -1685,23 +1689,61 @@ ac_setattr_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) - goto out; + if ((frame->root->uid != buf->ia_uid) && (frame->root->uid != 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) { + gf_log (ACTRL, GF_LOG_DEBUG, "Don't have write permision"); + goto out; + } + } valid = stub->args.setattr.valid; setbuf = &stub->args.setattr.stbuf; - if (gf_attr_uid_set (valid) || gf_attr_gid_set (valid)) { - /* chown returns EPERM if the operation would change the - * ownership, but the effective user ID is not the + if (gf_attr_uid_set (valid) || gf_attr_gid_set (valid) + || gf_attr_mode_set(valid)) { + /* chown/chmod returns EPERM if the operation would change the + * ownership/permissions, but the effective user ID is not the * super-user and the process is not an owner of the file. * Ref: posix-testsuite/chown/07.t */ - if ((frame->root->uid != 0) && (gf_attr_uid_set (valid))) { - if (buf->ia_uid != setbuf->ia_uid) { + if ((frame->root->uid != 0) && gf_attr_mode_set(valid)) { + if (frame->root->uid != buf->ia_uid) { + gf_log (ACTRL, GF_LOG_DEBUG, "Mismatch effective_uid %d file_uid %d", + frame->root->uid, buf->ia_uid); + op_ret = -1; + op_errno = EPERM; + goto out; + } + /* POSIX: If the calling process does not have appropriate privileges, and if + the group ID of the file does not match the effective group ID or one of the + supplementary group IDs and if the file is a regular file, bit S_ISGID + (set-group-ID on execution) in the file's mode shall be cleared upon + successful return from chmod().*/ + + if (setbuf->ia_prot.sgid == 1) { + op_ret = ac_test_access (buf, 0, frame->root->gid, + frame->root->groups, + frame->root->ngrps, + ACCTEST_DONTCARE, + ACCTEST_GROUP, &op_errno); + if (op_ret == -1) { + gf_log (ACTRL, GF_LOG_DEBUG, "Reseting set_gid bit"); + setbuf->ia_prot.sgid = 0; + op_ret = 0; + } + } + } + + if ((frame->root->uid != 0) && gf_attr_uid_set (valid)) { + /*Only super user can change the owner, + * for other users changing uid should match + * owner uid*/ + if (setbuf->ia_uid != buf->ia_uid) { + gf_log (ACTRL, GF_LOG_DEBUG, "Mismatch set_uid %d file_uid %d", + setbuf->ia_uid, buf->ia_uid); op_ret = -1; op_errno = EPERM; goto out; @@ -1714,6 +1756,8 @@ ac_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, */ if ((frame->root->uid != 0) && (gf_attr_gid_set (valid))) { if (frame->root->uid != buf->ia_uid) { + gf_log (ACTRL, GF_LOG_DEBUG, "Mismatch effective_uid %d file_uid %d", + frame->root->uid, buf->ia_uid); op_ret = -1; op_errno = EPERM; goto out; @@ -1724,8 +1768,11 @@ ac_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, frame->root->ngrps, ACCTEST_DONTCARE, ACCTEST_GROUP, &op_errno); - if (op_ret == -1) + if (op_ret == -1) { + gf_log (ACTRL, GF_LOG_DEBUG, "Set_gid %d is not in aux_gid_list", + setbuf->ia_gid); goto out; + } } } @@ -1795,23 +1842,62 @@ ac_fsetattr_fstat_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) - goto out; + + if ((frame->root->uid != buf->ia_uid) && (frame->root->uid != 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) { + gf_log (ACTRL, GF_LOG_DEBUG, "Don't have write permision"); + goto out; + } + } valid = stub->args.fsetattr.valid; setbuf = &stub->args.fsetattr.stbuf; - if (gf_attr_uid_set (valid) && gf_attr_gid_set (valid)) { - /* chown returns EPERM if the operation would change the - * ownership, but the effective user ID is not the + if (gf_attr_uid_set (valid) || gf_attr_gid_set (valid) + || gf_attr_mode_set(valid)) { + /* chown/chmod returns EPERM if the operation would change the + * ownership/permissions, but the effective user ID is not the * super-user and the process is not an owner of the file. * Ref: posix-testsuite/chown/07.t */ - if ((frame->root->uid != 0) && (gf_attr_uid_set (valid))) { - if (buf->ia_uid != setbuf->ia_uid) { + if ((frame->root->uid != 0) && gf_attr_mode_set(valid)) { + if (frame->root->uid != buf->ia_uid) { + gf_log (ACTRL, GF_LOG_DEBUG, "Mismatch effective_uid %d file_uid %d", + frame->root->uid, buf->ia_uid); + op_ret = -1; + op_errno = EPERM; + goto out; + } + /* POSIX: If the calling process does not have appropriate privileges, and if + the group ID of the file does not match the effective group ID or one of the + supplementary group IDs and if the file is a regular file, bit S_ISGID + (set-group-ID on execution) in the file's mode shall be cleared upon + successful return from chmod().*/ + + if (setbuf->ia_prot.sgid == 1) { + op_ret = ac_test_access (buf, 0, frame->root->gid, + frame->root->groups, + frame->root->ngrps, + ACCTEST_DONTCARE, + ACCTEST_GROUP, &op_errno); + if (op_ret == -1) { + gf_log (ACTRL, GF_LOG_DEBUG, "Reseting set_gid bit"); + setbuf->ia_prot.sgid = 0; + op_ret = 0; + } + } + } + + if ((frame->root->uid != 0) && gf_attr_uid_set (valid)) { + /*Only super user can change the owner, + * for other users changing uid should match + * owner uid*/ + if (setbuf->ia_uid != buf->ia_uid) { + gf_log (ACTRL, GF_LOG_DEBUG, "Mismatch set_uid %d file_uid %d", + setbuf->ia_uid, buf->ia_uid); op_ret = -1; op_errno = EPERM; goto out; @@ -1824,18 +1910,23 @@ ac_fsetattr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, */ if ((frame->root->uid != 0) && (gf_attr_gid_set (valid))) { if (frame->root->uid != buf->ia_uid) { + gf_log (ACTRL, GF_LOG_DEBUG, "Mismatch effective_uid %d file_uid %d", + frame->root->uid, buf->ia_uid); op_ret = -1; op_errno = EPERM; goto out; } - op_ret = ac_test_access (buf, 0, frame->root->gid, + op_ret = ac_test_access (setbuf, 0, frame->root->gid, frame->root->groups, frame->root->ngrps, ACCTEST_DONTCARE, ACCTEST_GROUP, &op_errno); - if (op_ret == -1) + if (op_ret == -1) { + gf_log (ACTRL, GF_LOG_DEBUG, "Set_gid %d is not in aux_gid_list", + setbuf->ia_gid); goto out; + } } } -- cgit