diff options
Diffstat (limited to 'xlators/system/posix-acl/src/posix-acl.c')
| -rw-r--r-- | xlators/system/posix-acl/src/posix-acl.c | 511 |
1 files changed, 353 insertions, 158 deletions
diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c index 7a80d1195..4658cad49 100644 --- a/xlators/system/posix-acl/src/posix-acl.c +++ b/xlators/system/posix-acl/src/posix-acl.c @@ -1,23 +1,13 @@ /* - Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2011-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ - #include <errno.h> #include "xlator.h" @@ -171,7 +161,6 @@ static int acl_permits (call_frame_t *frame, inode_t *inode, int want) { int verdict = 0; - int ret = 0; struct posix_acl *acl = NULL; struct posix_ace *ace = NULL; struct posix_acl_ctx *ctx = NULL; @@ -190,15 +179,14 @@ acl_permits (call_frame_t *frame, inode_t *inode, int want) if (frame_is_super_user (frame)) goto green; - ret = posix_acl_get (inode, frame->this, &acl, NULL); - + posix_acl_get (inode, frame->this, &acl, NULL); if (!acl) { acl = posix_acl_ref (frame->this, conf->minimal_acl); } ace = acl->entries; - if (acl->count > 3) + if (acl->count > POSIX_ACL_MINIMAL_ACE_COUNT) acl_present = 1; for (i = 0; i < acl->count; i++) { @@ -528,7 +516,7 @@ posix_acl_inherit_mode (struct posix_acl *acl, mode_t modein) if (mask_ce) { mask_ce->perm &= (mode >> 3) | ~S_IRWXO; mode &= (mask_ce->perm << 3) | ~S_IRWXG; - } else { + } else if (group_ce) { group_ce->perm &= (mode >> 3) | ~S_IRWXO; mode &= (group_ce->perm << 3) | ~S_IRWXG; } @@ -542,7 +530,7 @@ posix_acl_inherit_mode (struct posix_acl *acl, mode_t modein) mode_t posix_acl_inherit (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode, - int is_dir) + int32_t umask, int is_dir) { int ret = 0; struct posix_acl *par_default = NULL; @@ -554,8 +542,24 @@ posix_acl_inherit (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode, int size_default = 0; int size_access = 0; mode_t retmode = 0; + int16_t tmp_mode = 0; + mode_t client_umask = 0; retmode = mode; + client_umask = umask; + ret = dict_get_int16 (params, "umask", &tmp_mode); + if (ret == 0) { + client_umask = (mode_t)tmp_mode; + dict_del (params, "umask"); + ret = dict_get_int16 (params, "mode", &tmp_mode); + if (ret == 0) { + retmode = (mode_t)tmp_mode; + dict_del (params, "mode"); + } else { + gf_log (this->name, GF_LOG_ERROR, + "client sent umask, but not the original mode"); + } + } ret = posix_acl_get (loc->parent, this, NULL, &par_default); @@ -568,7 +572,8 @@ posix_acl_inherit (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode, if (!acl_access) goto out; - retmode = posix_acl_inherit_mode (acl_access, mode); + client_umask = 0; // No umask if we inherit an ACL + retmode = posix_acl_inherit_mode (acl_access, retmode); ctx->perm = retmode; size_access = posix_acl_to_xattr (this, acl_access, NULL, 0); @@ -617,6 +622,8 @@ set: goto out; out: + retmode &= ~client_umask; + if (par_default) posix_acl_unref (this, par_default); if (acl_access) @@ -629,22 +636,24 @@ out: mode_t -posix_acl_inherit_dir (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode) +posix_acl_inherit_dir (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode, + int32_t umask) { mode_t retmode = 0; - retmode = posix_acl_inherit (this, loc, params, mode, 1); + retmode = posix_acl_inherit (this, loc, params, mode, umask, 1); return retmode; } mode_t -posix_acl_inherit_file (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode) +posix_acl_inherit_file (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode, + int32_t umask) { mode_t retmode = 0; - retmode = posix_acl_inherit (this, loc, params, mode, 0); + retmode = posix_acl_inherit (this, loc, params, mode, umask, 0); return retmode; } @@ -654,7 +663,12 @@ int posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf) { struct posix_acl_ctx *ctx = NULL; + struct posix_acl *acl = NULL; + struct posix_ace *ace = NULL; + struct posix_ace *mask_ce = NULL; + struct posix_ace *group_ce = NULL; int ret = 0; + int i = 0; ctx = posix_acl_ctx_get (inode, this); if (!ctx) { @@ -667,7 +681,46 @@ posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf) ctx->uid = buf->ia_uid; ctx->gid = buf->ia_gid; ctx->perm = st_mode_from_ia (buf->ia_prot, buf->ia_type); + + acl = ctx->acl_access; + if (!acl || !(acl->count > POSIX_ACL_MINIMAL_ACE_COUNT)) + goto unlock; + + /* This is an extended ACL (not minimal acl). In case we + are only refreshing from iatt and not ACL xattrs (for + e.g. from postattributes of setattr() call, we need to + update the corresponding ACEs as well. + */ + ace = acl->entries; + for (i = 0; i < acl->count; i++) { + switch (ace->tag) { + case POSIX_ACL_USER_OBJ: + ace->perm = (ctx->perm & S_IRWXU) >> 6; + break; + case POSIX_ACL_USER: + case POSIX_ACL_GROUP: + break; + case POSIX_ACL_GROUP_OBJ: + group_ce = ace; + break; + case POSIX_ACL_MASK: + mask_ce = ace; + break; + case POSIX_ACL_OTHER: + ace->perm = (ctx->perm & S_IRWXO); + break; + } + ace++; + } + + if (mask_ce) + mask_ce->perm = (ctx->perm & S_IRWXG) >> 3; + else if (group_ce) + group_ce->perm = (ctx->perm & S_IRWXG) >> 3; + else + ret = -1; } +unlock: UNLOCK(&inode->lock); out: return ret; @@ -723,7 +776,9 @@ acl_set: posix_acl_ctx_update (inode, this, buf); ret = posix_acl_set (inode, this, acl_access, acl_default); - + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "failed to set ACL in context"); unwind: my_xattr = frame->local; frame->local = NULL; @@ -769,7 +824,14 @@ green: } ret = dict_set_int8 (my_xattr, POSIX_ACL_ACCESS_XATTR, 0); + if (ret) + gf_log (this->name, GF_LOG_WARNING, "failed to set key %s", + POSIX_ACL_ACCESS_XATTR); + ret = dict_set_int8 (my_xattr, POSIX_ACL_DEFAULT_XATTR, 0); + if (ret) + gf_log (this->name, GF_LOG_WARNING, "failed to set key %s", + POSIX_ACL_DEFAULT_XATTR); frame->local = my_xattr; STACK_WIND (frame, posix_acl_lookup_cbk, @@ -785,7 +847,8 @@ red: int -posix_acl_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int mask) +posix_acl_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int mask, + dict_t *xdata) { int op_ret = 0; int op_errno = 0; @@ -838,9 +901,9 @@ posix_acl_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int mask) unwind: if (is_fuse_call) - STACK_UNWIND_STRICT (access, frame, op_ret, op_errno); + STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, NULL); else - STACK_UNWIND_STRICT (access, frame, 0, mode); + STACK_UNWIND_STRICT (access, frame, 0, mode, NULL); return 0; } @@ -848,16 +911,18 @@ unwind: int posix_acl_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, - struct iatt *postbuf) + struct iatt *postbuf, dict_t *xdata) { - STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf, postbuf); + STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf, + postbuf, xdata); return 0; } int -posix_acl_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t off) +posix_acl_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t off, + dict_t *xdata) { if (acl_permits (frame, loc->inode, POSIX_ACL_WRITE)) goto green; @@ -866,19 +931,19 @@ posix_acl_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t off) green: STACK_WIND (frame, posix_acl_truncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, - loc, off); + loc, off, xdata); return 0; red: - STACK_UNWIND_STRICT (truncate, frame, -1, EACCES, NULL, NULL); + STACK_UNWIND_STRICT (truncate, frame, -1, EACCES, NULL, NULL, NULL); return 0; } int posix_acl_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, fd_t *fd) + int op_ret, int op_errno, fd_t *fd, dict_t *xdata) { - STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd); + STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata); return 0; } @@ -886,13 +951,20 @@ posix_acl_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int posix_acl_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, - fd_t *fd, int wbflags) + fd_t *fd, dict_t *xdata) { int perm = 0; switch (flags & O_ACCMODE) { case O_RDONLY: perm = POSIX_ACL_READ; + + /* If O_FMODE_EXEC is present, its good enough + to have '--x' perm, and its not covered in + O_ACCMODE bits */ + if (flags & O_FMODE_EXEC) + perm = POSIX_ACL_EXECUTE; + break; case O_WRONLY: case O_APPEND: @@ -911,10 +983,10 @@ posix_acl_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, green: STACK_WIND (frame, posix_acl_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, - loc, flags, fd, wbflags); + loc, flags, fd, xdata); return 0; red: - STACK_UNWIND_STRICT (open, frame, -1, EACCES, NULL); + STACK_UNWIND_STRICT (open, frame, -1, EACCES, NULL, xdata); return 0; } @@ -922,17 +994,18 @@ red: int posix_acl_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iovec *vector, - int count, struct iatt *stbuf, struct iobref *iobref) + int count, struct iatt *stbuf, struct iobref *iobref, + dict_t *xdata) { STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count, - stbuf, iobref); + stbuf, iobref, xdata); return 0; } int posix_acl_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t offset) + size_t size, off_t offset, uint32_t flags, dict_t *xdata) { if (__is_fuse_call (frame)) goto green; @@ -945,10 +1018,10 @@ posix_acl_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, green: STACK_WIND (frame, posix_acl_readv_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, - fd, size, offset); + fd, size, offset, flags, xdata); return 0; red: - STACK_UNWIND_STRICT (readv, frame, -1, EACCES, NULL, 0, NULL, NULL); + STACK_UNWIND_STRICT (readv, frame, -1, EACCES, NULL, 0, NULL, NULL, xdata); return 0; } @@ -956,10 +1029,10 @@ red: int posix_acl_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, - prebuf, postbuf); + prebuf, postbuf, xdata); return 0; } @@ -967,7 +1040,7 @@ posix_acl_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int posix_acl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, int count, off_t offset, - struct iobref *iobref) + uint32_t flags, struct iobref *iobref, dict_t *xdata) { if (__is_fuse_call (frame)) goto green; @@ -980,10 +1053,10 @@ posix_acl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, green: STACK_WIND (frame, posix_acl_writev_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, - fd, vector, count, offset, iobref); + fd, vector, count, offset, flags, iobref, xdata); return 0; red: - STACK_UNWIND_STRICT (writev, frame, -1, EACCES, NULL, NULL); + STACK_UNWIND_STRICT (writev, frame, -1, EACCES, NULL, NULL, xdata); return 0; } @@ -991,18 +1064,18 @@ red: int posix_acl_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, - struct iatt *prebuf, struct iatt *postbuf) + int op_ret, int op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) { STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, - prebuf, postbuf); + prebuf, postbuf, xdata); return 0; } int posix_acl_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, - off_t offset) + off_t offset, dict_t *xdata) { if (__is_fuse_call (frame)) goto green; @@ -1015,26 +1088,26 @@ posix_acl_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, green: STACK_WIND (frame, posix_acl_ftruncate_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, - fd, offset); + fd, offset, xdata); return 0; red: - STACK_UNWIND_STRICT (ftruncate, frame, -1, EACCES, NULL, NULL); + STACK_UNWIND_STRICT (ftruncate, frame, -1, EACCES, NULL, NULL, xdata); return 0; } int posix_acl_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, fd_t *fd) + int op_ret, int op_errno, fd_t *fd, dict_t *xdata) { - STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd); + STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata); return 0; } int -posix_acl_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) +posix_acl_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) { if (acl_permits (frame, loc->inode, POSIX_ACL_READ)) goto green; @@ -1043,10 +1116,10 @@ posix_acl_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) green: STACK_WIND (frame, posix_acl_opendir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, - loc, fd); + loc, fd, xdata); return 0; red: - STACK_UNWIND_STRICT (opendir, frame, -1, EACCES, NULL); + STACK_UNWIND_STRICT (opendir, frame, -1, EACCES, NULL, xdata); return 0; } @@ -1054,7 +1127,8 @@ red: int posix_acl_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, - struct iatt *preparent, struct iatt *postparent) + struct iatt *preparent, struct iatt *postparent, + dict_t *xdata) { if (op_ret != 0) goto unwind; @@ -1063,14 +1137,14 @@ posix_acl_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unwind: STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int posix_acl_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dict_t *params) + mode_t umask, dict_t *xdata) { mode_t newmode = 0; @@ -1080,14 +1154,15 @@ posix_acl_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, else goto red; green: - newmode = posix_acl_inherit_dir (this, loc, params, mode); + newmode = posix_acl_inherit_dir (this, loc, xdata, mode, umask); STACK_WIND (frame, posix_acl_mkdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, - loc, newmode, params); + loc, newmode, umask, xdata); return 0; red: - STACK_UNWIND_STRICT (mkdir, frame, -1, EACCES, NULL, NULL, NULL, NULL); + STACK_UNWIND_STRICT (mkdir, frame, -1, EACCES, NULL, NULL, NULL, NULL, + NULL); return 0; } @@ -1095,7 +1170,8 @@ red: int posix_acl_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, - struct iatt *preparent, struct iatt *postparent) + struct iatt *preparent, struct iatt *postparent, + dict_t *xdata) { if (op_ret != 0) goto unwind; @@ -1104,14 +1180,14 @@ posix_acl_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unwind: STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int posix_acl_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dev_t rdev, dict_t *params) + dev_t rdev, mode_t umask, dict_t *xdata) { mode_t newmode = 0; @@ -1121,14 +1197,15 @@ posix_acl_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, else goto red; green: - newmode = posix_acl_inherit_file (this, loc, params, mode); + newmode = posix_acl_inherit_file (this, loc, xdata, mode, umask); STACK_WIND (frame, posix_acl_mknod_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, - loc, newmode, rdev, params); + loc, newmode, rdev, umask, xdata); return 0; red: - STACK_UNWIND_STRICT (mknod, frame, -1, EACCES, NULL, NULL, NULL, NULL); + STACK_UNWIND_STRICT (mknod, frame, -1, EACCES, NULL, NULL, NULL, NULL, + NULL); return 0; } @@ -1137,7 +1214,7 @@ int posix_acl_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; @@ -1146,14 +1223,14 @@ posix_acl_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unwind: STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int posix_acl_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, - mode_t mode, fd_t *fd, dict_t *params) + mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { mode_t newmode = 0; @@ -1163,14 +1240,15 @@ posix_acl_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, else goto red; green: - newmode = posix_acl_inherit_file (this, loc, params, mode); + newmode = posix_acl_inherit_file (this, loc, xdata, mode, umask); STACK_WIND (frame, posix_acl_create_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, - loc, flags, newmode, fd, params); + loc, flags, newmode, umask, fd, xdata); return 0; red: - STACK_UNWIND_STRICT (create, frame, -1, EACCES, NULL, NULL, NULL, NULL, NULL); + STACK_UNWIND_STRICT (create, frame, -1, EACCES, NULL, NULL, NULL, + NULL, NULL, NULL); return 0; } @@ -1179,7 +1257,7 @@ int posix_acl_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; @@ -1188,14 +1266,14 @@ posix_acl_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unwind: STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int posix_acl_symlink (call_frame_t *frame, xlator_t *this, const char *linkname, - loc_t *loc, dict_t *params) + loc_t *loc, mode_t umask, dict_t *xdata) { if (acl_permits (frame, loc->parent, POSIX_ACL_WRITE|POSIX_ACL_EXECUTE)) goto green; @@ -1204,30 +1282,32 @@ posix_acl_symlink (call_frame_t *frame, xlator_t *this, const char *linkname, green: STACK_WIND (frame, posix_acl_symlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, - linkname, loc, params); + linkname, loc, umask, xdata); return 0; red: - STACK_UNWIND_STRICT (symlink, frame, -1, EACCES, NULL, NULL, NULL, NULL); + STACK_UNWIND_STRICT (symlink, frame, -1, EACCES, NULL, NULL, NULL, + NULL, xdata); return 0; } int posix_acl_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, - struct iatt *preparent, struct iatt *postparent) + int op_ret, int op_errno, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; unwind: STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, - preparent, postparent); + preparent, postparent, xdata); return 0; } int -posix_acl_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) +posix_acl_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, + dict_t *xdata) { if (!sticky_permits (frame, loc->parent, loc->inode)) goto red; @@ -1239,10 +1319,10 @@ posix_acl_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) green: STACK_WIND (frame, posix_acl_unlink_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, - loc); + loc, xflag, xdata); return 0; red: - STACK_UNWIND_STRICT (unlink, frame, -1, EACCES, NULL, NULL); + STACK_UNWIND_STRICT (unlink, frame, -1, EACCES, NULL, NULL, xdata); return 0; } @@ -1250,19 +1330,19 @@ red: int posix_acl_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, - struct iatt *preparent, struct iatt *postparent) + struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; unwind: STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, - preparent, postparent); + preparent, postparent, xdata); return 0; } int -posix_acl_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags) +posix_acl_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata) { if (!sticky_permits (frame, loc->parent, loc->inode)) goto red; @@ -1274,10 +1354,10 @@ posix_acl_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags) green: STACK_WIND (frame, posix_acl_rmdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, - loc, flags); + loc, flags, xdata); return 0; red: - STACK_UNWIND_STRICT (rmdir, frame, -1, EACCES, NULL, NULL); + STACK_UNWIND_STRICT (rmdir, frame, -1, EACCES, NULL, NULL, xdata); return 0; } @@ -1286,20 +1366,21 @@ int posix_acl_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, - struct iatt *prenewparent, struct iatt *postnewparent) + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t *xdata) { if (op_ret != 0) goto unwind; unwind: STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent, postoldparent, - prenewparent, postnewparent); + prenewparent, postnewparent, xdata); return 0; } int -posix_acl_rename (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new) +posix_acl_rename (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new, dict_t *xdata) { if (!acl_permits (frame, old->parent, POSIX_ACL_WRITE)) goto red; @@ -1317,11 +1398,11 @@ posix_acl_rename (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new) STACK_WIND (frame, posix_acl_rename_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, - old, new); + old, new, xdata); return 0; red: STACK_UNWIND_STRICT (rename, frame, -1, EACCES, NULL, NULL, NULL, NULL, - NULL); + NULL, NULL); return 0; } @@ -1329,19 +1410,19 @@ red: int posix_acl_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, struct iatt *buf, - struct iatt *preparent, struct iatt *postparent) + struct iatt *preparent, struct iatt *postparent, dict_t *xdata) { if (op_ret != 0) goto unwind; unwind: STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf, - preparent, postparent); + preparent, postparent, xdata); return 0; } int -posix_acl_link (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new) +posix_acl_link (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new, dict_t *xdata) { struct posix_acl_ctx *ctx = NULL; int op_errno = 0; @@ -1357,12 +1438,17 @@ posix_acl_link (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new) goto red; } + if (!sticky_permits (frame, new->parent, new->inode)) { + op_errno = EACCES; + goto red; + } + STACK_WIND (frame, posix_acl_link_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, - old, new); + old, new, xdata); return 0; red: - STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, NULL, NULL); + STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, xdata); return 0; } @@ -1370,19 +1456,20 @@ red: int posix_acl_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, gf_dirent_t *entries) + int op_ret, int op_errno, gf_dirent_t *entries, + dict_t *xdata) { if (op_ret != 0) goto unwind; unwind: - STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries); + STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata); return 0; } int posix_acl_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) + off_t offset, dict_t *xdata) { if (acl_permits (frame, fd->inode, POSIX_ACL_READ)) goto green; @@ -1391,10 +1478,10 @@ posix_acl_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, green: STACK_WIND (frame, posix_acl_readdir_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, - fd, size, offset); + fd, size, offset, xdata); return 0; red: - STACK_UNWIND_STRICT (readdir, frame, -1, EACCES, NULL); + STACK_UNWIND_STRICT (readdir, frame, -1, EACCES, NULL, xdata); return 0; } @@ -1402,31 +1489,116 @@ red: int posix_acl_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, gf_dirent_t *entries) + int op_ret, int op_errno, gf_dirent_t *entries, + dict_t *xdata) { - if (op_ret != 0) + gf_dirent_t *entry = NULL; + struct posix_acl *acl_access = NULL; + struct posix_acl *acl_default = NULL; + data_t *data = NULL; + int ret = 0; + + if (op_ret <= 0) goto unwind; + + list_for_each_entry (entry, &entries->list, list) { + /* Update the inode ctx */ + if (!entry->dict || !entry->inode) + continue; + + ret = posix_acl_get (entry->inode, this, + &acl_access, &acl_default); + + data = dict_get (entry->dict, POSIX_ACL_ACCESS_XATTR); + if (!data) + goto acl_default; + + if (acl_access && + posix_acl_matches_xattr (this, acl_access, data->data, + data->len)) + goto acl_default; + + if (acl_access) + posix_acl_unref(this, acl_access); + + acl_access = posix_acl_from_xattr (this, data->data, + data->len); + + acl_default: + data = dict_get (entry->dict, POSIX_ACL_DEFAULT_XATTR); + if (!data) + goto acl_set; + + if (acl_default && + posix_acl_matches_xattr (this, acl_default, data->data, + data->len)) + goto acl_set; + + if (acl_default) + posix_acl_unref(this, acl_default); + + acl_default = posix_acl_from_xattr (this, data->data, + data->len); + + acl_set: + posix_acl_ctx_update (entry->inode, this, &entry->d_stat); + + ret = posix_acl_set (entry->inode, this, + acl_access, acl_default); + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "failed to set ACL in context"); + + if (acl_access) + posix_acl_unref(this, acl_access); + if (acl_default) + posix_acl_unref(this, acl_default); + } + unwind: - STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries); + STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata); return 0; } int posix_acl_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) + off_t offset, dict_t *dict) { + int ret = 0; + dict_t *alloc_dict = NULL; + if (acl_permits (frame, fd->inode, POSIX_ACL_READ)) goto green; else goto red; green: + if (!dict) + dict = alloc_dict = dict_new (); + + if (dict) { + ret = dict_set_int8 (dict, POSIX_ACL_ACCESS_XATTR, 0); + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "failed to set key %s", + POSIX_ACL_ACCESS_XATTR); + + ret = dict_set_int8 (dict, POSIX_ACL_DEFAULT_XATTR, 0); + if (ret) + gf_log (this->name, GF_LOG_WARNING, + "failed to set key %s", + POSIX_ACL_DEFAULT_XATTR); + } + STACK_WIND (frame, posix_acl_readdirp_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, - fd, size, offset); + fd, size, offset, dict); + + if (alloc_dict) + dict_unref (alloc_dict); return 0; red: - STACK_UNWIND_STRICT (readdirp, frame, -1, EACCES, NULL); + STACK_UNWIND_STRICT (readdirp, frame, -1, EACCES, NULL, NULL); return 0; } @@ -1496,7 +1668,7 @@ setattr_scrutiny (call_frame_t *frame, inode_t *inode, struct iatt *buf, int posix_acl_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *inode = NULL; @@ -1509,14 +1681,15 @@ posix_acl_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, posix_acl_ctx_update (inode, this, postbuf); unwind: - STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, prebuf, postbuf); + STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, prebuf, + postbuf, xdata); return 0; } int posix_acl_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - struct iatt *buf, int valid) + struct iatt *buf, int valid, dict_t *xdata) { int op_errno = 0; @@ -1529,10 +1702,10 @@ posix_acl_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, STACK_WIND (frame, posix_acl_setattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, - loc, buf, valid); + loc, buf, valid, xdata); return 0; red: - STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL); + STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL, xdata); return 0; } @@ -1541,7 +1714,7 @@ red: int posix_acl_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { inode_t *inode = NULL; @@ -1554,14 +1727,15 @@ posix_acl_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, posix_acl_ctx_update (inode, this, postbuf); unwind: - STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, prebuf, postbuf); + STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, prebuf, + postbuf, xdata); return 0; } int posix_acl_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iatt *buf, int valid) + struct iatt *buf, int valid, dict_t *xdata) { int op_errno = 0; @@ -1574,10 +1748,10 @@ posix_acl_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, STACK_WIND (frame, posix_acl_fsetattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, - fd, buf, valid); + fd, buf, valid, xdata); return 0; red: - STACK_UNWIND_STRICT (fsetattr, frame, -1, EACCES, NULL, NULL); + STACK_UNWIND_STRICT (fsetattr, frame, -1, EACCES, NULL, NULL, xdata); return 0; } @@ -1644,7 +1818,6 @@ posix_acl_setxattr_update (xlator_t *this, inode_t *inode, dict_t *xattr) struct posix_acl *old_default = NULL; struct posix_acl_ctx *ctx = NULL; int ret = 0; - mode_t mode = 0; ctx = posix_acl_ctx_get (inode, this); if (!ctx) @@ -1663,7 +1836,7 @@ posix_acl_setxattr_update (xlator_t *this, inode_t *inode, dict_t *xattr) ret = posix_acl_set (inode, this, acl_access, acl_default); if (acl_access && acl_access != old_access) { - mode = posix_acl_access_set_mode (acl_access, ctx); + posix_acl_access_set_mode (acl_access, ctx); } if (acl_access) @@ -1675,15 +1848,15 @@ posix_acl_setxattr_update (xlator_t *this, inode_t *inode, dict_t *xattr) if (old_default) posix_acl_unref (this, old_default); - return 0; + return ret; } int posix_acl_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno) + int op_ret, int op_errno, dict_t *xdata) { - STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno); + STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata); return 0; } @@ -1691,7 +1864,7 @@ posix_acl_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int posix_acl_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *xattr, int flags) + dict_t *xattr, int flags, dict_t *xdata) { int op_errno = 0; @@ -1704,10 +1877,10 @@ posix_acl_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, STACK_WIND (frame, posix_acl_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, - loc, xattr, flags); + loc, xattr, flags, xdata); return 0; red: - STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno); + STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno, xdata); return 0; } @@ -1715,9 +1888,9 @@ red: int posix_acl_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno) + int op_ret, int op_errno, dict_t *xdata) { - STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno); + STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata); return 0; } @@ -1725,7 +1898,7 @@ posix_acl_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int posix_acl_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - dict_t *xattr, int flags) + dict_t *xattr, int flags, dict_t *xdata) { int op_errno = 0; @@ -1738,10 +1911,10 @@ posix_acl_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, STACK_WIND (frame, posix_acl_fsetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, - fd, xattr, flags); + fd, xattr, flags, xdata); return 0; red: - STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno); + STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno, xdata); return 0; } @@ -1749,9 +1922,9 @@ red: int posix_acl_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, dict_t *xattr) + int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, xattr); + STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, xattr, xdata); return 0; } @@ -1759,7 +1932,7 @@ posix_acl_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int posix_acl_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name) + const char *name, dict_t *xdata) { if (whitelisted_xattr (name)) goto green; @@ -1771,10 +1944,10 @@ posix_acl_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, green: STACK_WIND (frame, posix_acl_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, - loc, name); + loc, name, xdata); return 0; red: - STACK_UNWIND_STRICT (getxattr, frame, -1, EACCES, NULL); + STACK_UNWIND_STRICT (getxattr, frame, -1, EACCES, NULL, xdata); return 0; } @@ -1782,9 +1955,9 @@ red: int posix_acl_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, dict_t *xattr) + int op_ret, int op_errno, dict_t *xattr, dict_t *xdata) { - STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, xattr); + STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, xattr, xdata); return 0; } @@ -1792,7 +1965,7 @@ posix_acl_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int posix_acl_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - const char *name) + const char *name, dict_t *xdata) { if (whitelisted_xattr (name)) goto green; @@ -1804,10 +1977,10 @@ posix_acl_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, green: STACK_WIND (frame, posix_acl_fgetxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, - fd, name); + fd, name, xdata); return 0; red: - STACK_UNWIND_STRICT (fgetxattr, frame, -1, EACCES, NULL); + STACK_UNWIND_STRICT (fgetxattr, frame, -1, EACCES, NULL, xdata); return 0; } @@ -1815,9 +1988,9 @@ red: int posix_acl_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno) + int op_ret, int op_errno, dict_t *xdata) { - STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno); + STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata); return 0; } @@ -1825,7 +1998,7 @@ posix_acl_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int posix_acl_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name) + const char *name, dict_t *xdata) { struct posix_acl_ctx *ctx = NULL; int op_errno = EACCES; @@ -1853,10 +2026,10 @@ posix_acl_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, green: STACK_WIND (frame, posix_acl_removexattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, - loc, name); + loc, name, xdata); return 0; red: - STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno); + STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno, xdata); return 0; } @@ -1938,6 +2111,28 @@ err: int fini (xlator_t *this) { + struct posix_acl_conf *conf = NULL; + struct posix_acl *minacl = NULL; + + conf = this->private; + if (!conf) + return 0; + this->private = NULL; + + minacl = conf->minimal_acl; + + LOCK (&conf->acl_lock); + { + conf->minimal_acl = NULL; + } + UNLOCK (&conf->acl_lock); + + LOCK_DESTROY (&conf->acl_lock); + + GF_FREE (minacl); + + GF_FREE (conf); + return 0; } @@ -1948,8 +2143,11 @@ struct xlator_fops fops = { #if FD_MODE_CHECK_IS_IMPLEMENTED .readv = posix_acl_readv, .writev = posix_acl_writev, -#endif .ftruncate = posix_acl_ftruncate, + .fsetattr = posix_acl_fsetattr, + .fsetxattr = posix_acl_fsetxattr, + .fgetxattr = posix_acl_fgetxattr, +#endif .access = posix_acl_access, .truncate = posix_acl_truncate, .mkdir = posix_acl_mkdir, @@ -1964,11 +2162,8 @@ struct xlator_fops fops = { .readdir = posix_acl_readdir, .readdirp = posix_acl_readdirp, .setattr = posix_acl_setattr, - .fsetattr = posix_acl_fsetattr, .setxattr = posix_acl_setxattr, - .fsetxattr = posix_acl_fsetxattr, .getxattr = posix_acl_getxattr, - .fgetxattr = posix_acl_fgetxattr, .removexattr = posix_acl_removexattr, }; |
