diff options
Diffstat (limited to 'xlators/system/posix-acl/src/posix-acl.c')
| -rw-r--r-- | xlators/system/posix-acl/src/posix-acl.c | 709 |
1 files changed, 550 insertions, 159 deletions
diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c index f05ed3f95..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 Affero 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 - Affero General Public License for more details. - - You should have received a copy of the GNU Affero 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" @@ -31,6 +21,17 @@ #define PTR(num) ((void *)((long)(num))) +static uid_t +r00t () +{ + struct posix_acl_conf *conf = NULL; + + conf = THIS->private; + + return conf->super_uid; +} + + int whitelisted_xattr (const char *key) { @@ -53,6 +54,19 @@ frame_is_user (call_frame_t *frame, uid_t uid) int +frame_is_super_user (call_frame_t *frame) +{ + int ret; + + ret = frame_is_user (frame, r00t()); + if (!ret) + ret = frame_is_user (frame, 0); + + return ret; +} + + +int frame_in_group (call_frame_t *frame, gid_t gid) { int i = 0; @@ -127,7 +141,7 @@ sticky_permits (call_frame_t *frame, inode_t *parent, inode_t *inode) par = posix_acl_ctx_get (parent, frame->this); ctx = posix_acl_ctx_get (inode, frame->this); - if (frame_is_user (frame, 0)) + if (frame_is_super_user (frame)) return 1; if (!(par->perm & S_ISVTX)) @@ -147,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; @@ -155,6 +168,7 @@ acl_permits (call_frame_t *frame, inode_t *inode, int want) int i = 0; int perm = 0; int found = 0; + int acl_present = 0; conf = frame->this->private; @@ -162,17 +176,19 @@ acl_permits (call_frame_t *frame, inode_t *inode, int want) if (!ctx) goto red; - if (frame->root->uid == 0) + 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 > POSIX_ACL_MINIMAL_ACE_COUNT) + acl_present = 1; + for (i = 0; i < acl->count; i++) { switch (ace->tag) { case POSIX_ACL_USER_OBJ: @@ -186,7 +202,10 @@ acl_permits (call_frame_t *frame, inode_t *inode, int want) goto mask_check; break; case POSIX_ACL_GROUP_OBJ: - perm = ((ctx->perm & S_IRWXG) >> 3); + if (acl_present) + perm = ace->perm; + else + perm = ((ctx->perm & S_IRWXG) >> 3); if (frame_in_group (frame, ctx->gid)) { found = 1; if ((perm & want) == want) @@ -221,16 +240,18 @@ mask_check: for (i = 0; i < acl->count; i++, ace++) { if (ace->tag != POSIX_ACL_MASK) continue; - if ((ace->perm & perm & want) == want) + if ((ace->perm & perm & want) == want) { goto green; + } goto red; } perm_check: - if ((perm & want) == want) + if ((perm & want) == want) { goto green; - else + } else { goto red; + } green: verdict = 1; @@ -353,11 +374,8 @@ posix_acl_ref (xlator_t *this, struct posix_acl *acl) struct posix_acl * posix_acl_dup (xlator_t *this, struct posix_acl *acl) { - struct posix_acl_conf *conf = NULL; struct posix_acl *dup = NULL; - conf = this->private; - dup = posix_acl_new (this, acl->count); if (!dup) return NULL; @@ -498,12 +516,13 @@ 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; } - newmode = ((modein & S_IFMT) | (mode & (S_IRWXU|S_IRWXG|S_IRWXO))); + newmode = ((modein & (S_IFMT | S_ISUID | S_ISGID | S_ISVTX)) | + (mode & (S_IRWXU|S_IRWXG|S_IRWXO))); return newmode; } @@ -511,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; @@ -523,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); @@ -537,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); @@ -586,6 +622,8 @@ set: goto out; out: + retmode &= ~client_umask; + if (par_default) posix_acl_unref (this, par_default); if (acl_access) @@ -598,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; } @@ -623,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) { @@ -636,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; @@ -692,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; @@ -738,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, @@ -754,12 +847,16 @@ 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; int perm = 0; + int mode = 0; + int is_fuse_call = 0; + is_fuse_call = __is_fuse_call (frame); if (mask & R_OK) perm |= POSIX_ACL_READ; @@ -767,23 +864,46 @@ posix_acl_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int mask) perm |= POSIX_ACL_WRITE; if (mask & X_OK) perm |= POSIX_ACL_EXECUTE; + if (!mask) { + goto unwind; + } if (!perm) { op_ret = -1; op_errno = EINVAL; goto unwind; } - if (acl_permits (frame, loc->inode, perm)) { - op_ret = 0; - op_errno = 0; + if (is_fuse_call) { + mode = acl_permits (frame, loc->inode, perm); + if (mode) { + op_ret = 0; + op_errno = 0; + } else { + op_ret = -1; + op_errno = EACCES; + } } else { - op_ret = -1; - op_errno = EACCES; + if (perm & POSIX_ACL_READ) { + if (acl_permits (frame, loc->inode, POSIX_ACL_READ)) + mode |= POSIX_ACL_READ; + } + + if (perm & POSIX_ACL_WRITE) { + if (acl_permits (frame, loc->inode, POSIX_ACL_WRITE)) + mode |= POSIX_ACL_WRITE; + } + + if (perm & POSIX_ACL_EXECUTE) { + if (acl_permits (frame, loc->inode, POSIX_ACL_EXECUTE)) + mode |= POSIX_ACL_EXECUTE; + } } unwind: - STACK_UNWIND_STRICT (access, frame, op_ret, op_errno); - + if (is_fuse_call) + STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, NULL); + else + STACK_UNWIND_STRICT (access, frame, 0, mode, NULL); return 0; } @@ -791,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; @@ -809,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; } @@ -829,15 +951,24 @@ 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: + case O_TRUNC: perm = POSIX_ACL_WRITE; break; case O_RDWR: @@ -852,27 +983,131 @@ 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, xdata); + return 0; +} + + +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, + dict_t *xdata) +{ + STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count, + 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, uint32_t flags, dict_t *xdata) +{ + if (__is_fuse_call (frame)) + goto green; + + if (acl_permits (frame, fd->inode, POSIX_ACL_READ)) + goto green; + else + goto red; + +green: + STACK_WIND (frame, posix_acl_readv_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, + fd, size, offset, flags, xdata); return 0; red: - STACK_UNWIND_STRICT (open, frame, -1, EACCES, NULL); + STACK_UNWIND_STRICT (readv, frame, -1, EACCES, NULL, 0, NULL, NULL, xdata); return 0; } +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, dict_t *xdata) +{ + STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, + prebuf, postbuf, xdata); + return 0; +} + + +int +posix_acl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iovec *vector, int count, off_t offset, + uint32_t flags, struct iobref *iobref, dict_t *xdata) +{ + if (__is_fuse_call (frame)) + goto green; + + if (acl_permits (frame, fd->inode, POSIX_ACL_WRITE)) + goto green; + else + goto red; + +green: + STACK_WIND (frame, posix_acl_writev_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, + fd, vector, count, offset, flags, iobref, xdata); + return 0; +red: + STACK_UNWIND_STRICT (writev, frame, -1, EACCES, NULL, NULL, xdata); + return 0; +} + + + +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, dict_t *xdata) +{ + STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, + prebuf, postbuf, xdata); + return 0; +} + + +int +posix_acl_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, + off_t offset, dict_t *xdata) +{ + if (__is_fuse_call (frame)) + goto green; + + if (acl_permits (frame, fd->inode, POSIX_ACL_WRITE)) + goto green; + else + goto red; + +green: + STACK_WIND (frame, posix_acl_ftruncate_cbk, + FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate, + fd, offset, xdata); + return 0; +red: + 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; @@ -881,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; } @@ -892,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; @@ -901,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; @@ -918,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; } @@ -933,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; @@ -942,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; @@ -959,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; } @@ -975,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; @@ -984,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; @@ -1001,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; } @@ -1017,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; @@ -1026,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; @@ -1042,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; @@ -1077,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; } @@ -1088,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; @@ -1112,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; } @@ -1124,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; @@ -1155,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; } @@ -1167,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; @@ -1195,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; } @@ -1208,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; @@ -1229,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; } @@ -1240,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; } @@ -1276,7 +1610,7 @@ setattr_scrutiny (call_frame_t *frame, inode_t *inode, struct iatt *buf, { struct posix_acl_ctx *ctx = NULL; - if (frame->root->uid == 0) + if (frame_is_super_user (frame)) return 0; ctx = posix_acl_ctx_get (inode, frame->this); @@ -1315,7 +1649,7 @@ setattr_scrutiny (call_frame_t *frame, inode_t *inode, struct iatt *buf, } if (valid & GF_SET_ATTR_UID) { - if ((frame->root->uid != 0) && + if ((!frame_is_super_user (frame)) && (buf->ia_uid != ctx->uid)) return EPERM; } @@ -1334,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; @@ -1347,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; @@ -1367,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; } @@ -1379,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; @@ -1392,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; @@ -1412,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; } @@ -1427,7 +1763,7 @@ setxattr_scrutiny (call_frame_t *frame, inode_t *inode, dict_t *xattr) struct posix_acl_ctx *ctx = NULL; int found = 0; - if (frame->root->uid == 0) + if (frame_is_super_user (frame)) return 0; ctx = posix_acl_ctx_get (inode, frame->this); @@ -1482,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) @@ -1501,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) @@ -1513,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; } @@ -1529,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; @@ -1542,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; } @@ -1553,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; } @@ -1563,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; @@ -1576,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; } @@ -1587,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; } @@ -1597,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; @@ -1609,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; } @@ -1620,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; } @@ -1630,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; @@ -1642,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; } @@ -1653,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; } @@ -1663,12 +1998,12 @@ 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; - if (frame_is_user (frame, 0)) + if (frame_is_super_user (frame)) goto green; ctx = posix_acl_ctx_get (loc->inode, this); @@ -1691,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; } @@ -1722,6 +2057,21 @@ out: int +reconfigure (xlator_t *this, dict_t *options) +{ + struct posix_acl_conf *conf = NULL; + + conf = this->private; + + GF_OPTION_RECONF ("super-uid", conf->super_uid, options, uint32, err); + + return 0; +err: + return -1; +} + + +int init (xlator_t *this) { struct posix_acl_conf *conf = NULL; @@ -1750,13 +2100,39 @@ init (xlator_t *this) conf->minimal_acl = minacl; + GF_OPTION_INIT ("super-uid", conf->super_uid, uint32, err); + return 0; +err: + return -1; } 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; } @@ -1764,6 +2140,14 @@ fini (xlator_t *this) struct xlator_fops fops = { .lookup = posix_acl_lookup, .open = posix_acl_open, +#if FD_MODE_CHECK_IS_IMPLEMENTED + .readv = posix_acl_readv, + .writev = posix_acl_writev, + .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, @@ -1778,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, }; @@ -1790,3 +2171,13 @@ struct xlator_fops fops = { struct xlator_cbks cbks = { .forget = posix_acl_forget }; + + +struct volume_options options[] = { + { .key = {"super-uid"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "0", + .description = "UID to be treated as super user's id instead of 0", + }, + { .key = {NULL} }, +}; |
