diff options
author | Anand Avati <avati@gluster.com> | 2011-07-01 17:19:15 +0000 |
---|---|---|
committer | Anand Avati <avati@gluster.com> | 2011-07-08 02:26:17 -0700 |
commit | 4b643cfa8847be71bb381b5a8a1a420837722e51 (patch) | |
tree | c9aa055c43c49cf653eb2a6b10569006645ea3a4 /xlators/features/access-control | |
parent | 04ed499a8eef1c77c491227941d187778fb5c2e4 (diff) |
access-control: superseded by posix-acl translator
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 2815 (Server-enforced ACLs)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2815
Diffstat (limited to 'xlators/features/access-control')
-rw-r--r-- | xlators/features/access-control/Makefile.am | 3 | ||||
-rw-r--r-- | xlators/features/access-control/src/Makefile.am | 13 | ||||
-rw-r--r-- | xlators/features/access-control/src/access-control.c | 2060 | ||||
-rw-r--r-- | xlators/features/access-control/src/access-control.h | 55 |
4 files changed, 0 insertions, 2131 deletions
diff --git a/xlators/features/access-control/Makefile.am b/xlators/features/access-control/Makefile.am deleted file mode 100644 index a985f42a877..00000000000 --- a/xlators/features/access-control/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src - -CLEANFILES = diff --git a/xlators/features/access-control/src/Makefile.am b/xlators/features/access-control/src/Makefile.am deleted file mode 100644 index 6ab8cc4ec4e..00000000000 --- a/xlators/features/access-control/src/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -xlator_LTLIBRARIES = access-control.la -xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features -access_control_la_LDFLAGS = -module -avoidversion -access_control_la_SOURCES = access-control.c -access_control_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la - -noinst_HEADERS = access-control.h - -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ - -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\ - -L$(xlatordir)/ - -CLEANFILES = diff --git a/xlators/features/access-control/src/access-control.c b/xlators/features/access-control/src/access-control.c deleted file mode 100644 index 1dca5ac2724..00000000000 --- a/xlators/features/access-control/src/access-control.c +++ /dev/null @@ -1,2060 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.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/>. -*/ - - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "access-control.h" -#include "xlator.h" -#include "call-stub.h" -#include "defaults.h" -#include "iatt.h" - -/* Careful, this function erases the stub from frame->local. Dont call this if - * a subsequent callback requires retaining access to the stub. This should be - * called at the end of all access-control related operations, i.e. once the - * frame will be handed off to the actual fop and the next callback that will - * be called is the default callback. IOW, the function where call_resume is - * called. - * NOTE: this is required because FRAME_DESTROY tries to free frame->local if - * it finds it to be non-NULL. - */ -call_stub_t * -__get_frame_stub (call_frame_t *fr) -{ - call_stub_t *st = NULL; - - GF_VALIDATE_OR_GOTO (ACTRL, fr, out); - - st = fr->local; - fr->local = NULL; -out: - gf_log (ACTRL, GF_LOG_TRACE, "Returning %p", st); - return st; -} - -void -ac_set_accesstype_str (int access, char *str, size_t len) -{ - char *read = "read "; - char *write = "write "; - char *exec = "exec "; - char *dontcare = "don'tcare "; - - GF_ASSERT (len > (strlen (read) + strlen (write) + - strlen (exec) + strlen (dontcare))); - GF_ASSERT (str); - if (access & ACCTEST_READ) { - snprintf (str, len, "%s", read); - len -= strlen (read); - } - if (access & ACCTEST_WRITE) { - snprintf (str, len, "%s", write); - len -= strlen (write); - } - if (access & ACCTEST_EXEC) { - snprintf (str, len, "%s", exec); - len -= strlen (exec); - } - if (access & ACCTEST_DONTCARE) { - snprintf (str, len, "%s", dontcare); - len -= strlen (dontcare); - } -} - -int -ac_test_owner_access (struct iatt *ia, uid_t uid, int accesstest) -{ - int ret = -1; - - GF_VALIDATE_OR_GOTO (ACTRL, ia, out); - - /* First test permissions using the uid. */ - if (ia->ia_uid != uid) { - ret = -1; - gf_log (ACTRL, GF_LOG_TRACE, "UID mismatch (orig: %d, user: %d)", - ia->ia_uid, uid); - goto out; - } - - /* At this point we know, the uid matches that of the stat structure, so - * if the caller does not care, we should return success. - */ - if (ac_test_dontcare (accesstest)) { - ret = 0; - gf_log (ACTRL, GF_LOG_TRACE, "Access test marked as don't care"); - goto out; - } - - if (ac_test_read (accesstest)) - ret = IA_PROT_RUSR (ia->ia_prot); - - if (ac_test_write (accesstest)) - ret = IA_PROT_WUSR (ia->ia_prot); - - if (ac_test_exec (accesstest)) - ret = IA_PROT_XUSR (ia->ia_prot); - - /* For failed access test for owner, we need to return EACCES */ - if (!ret) - ret = -1; - else - ret = 0; -out: - if (0 == ret) - gf_log (ACTRL, GF_LOG_TRACE, "Owner access allowed"); - else - gf_log (ACTRL, GF_LOG_TRACE, "Owner access not allowed"); - return ret; -} - - -int -ac_test_group_access (struct iatt *ia, gid_t gid, gid_t *auxgids, int auxcount, - int accesstest) -{ - int ret = -1; - int testgid = -1; - int x = 0; - - GF_VALIDATE_OR_GOTO (ACTRL, ia, out); - - /* First, determine which gid to test against. This will be determined - * by first checking which of the gids given to us match the gid in the - * stat. If none match, then we go to checking with others as the user. - */ - - /* If we are only given the primary gid. Dont depend on @auxgids - * being NULL since I know users of this function can pass statically - * allocated arrays which cant be NULL and yet contain no valid gids. - */ - - if ((ia->ia_gid != gid) && (auxcount == 0)) { - gf_log (ACTRL, GF_LOG_TRACE, "GID mismatch (orig: %d, user: %d)", - ia->ia_gid, gid); - ret = -1; - goto out; - } - - if (ia->ia_gid == gid) - testgid = gid; - else { - for (; x < auxcount; ++x) { - if (ia->ia_gid == auxgids[x]) { - testgid = ia->ia_gid; - break; - } - } - } - - /* None of the gids match with the gid in the stat. */ - if (testgid == -1) { - gf_log (ACTRL, GF_LOG_TRACE, "None of the gids match with gid " - "on the stat"); - ret = -1; - goto out; - } - - /* At this point, at least one gid matches that in the stat, now we must - * check whether the caller is interested in the access check at all. - */ - if (ac_test_dontcare (accesstest)) { - gf_log (ACTRL, GF_LOG_TRACE, "Access test marked as don't care"); - ret = 0; - goto out; - } - - if (ac_test_read (accesstest)) - ret = IA_PROT_RGRP (ia->ia_prot); - - if (ac_test_write (accesstest)) - ret = IA_PROT_WGRP (ia->ia_prot); - - if (ac_test_exec (accesstest)) - ret = IA_PROT_XGRP (ia->ia_prot); - - if (!ret) - ret = -1; - else - ret = 0; - -out: - if (0 == ret) - gf_log (ACTRL, GF_LOG_TRACE, "Group access allowed"); - else - gf_log (ACTRL, GF_LOG_TRACE, "Group access not allowed"); - return ret; -} - - -int -ac_test_other_access (struct iatt *ia, int accesstest) -{ - int ret = -1; - - GF_VALIDATE_OR_GOTO (ACTRL, ia, out); - ret = 0; - - if (ac_test_read (accesstest)) - ret = IA_PROT_ROTH (ia->ia_prot); - - if (ac_test_write (accesstest)) - ret = IA_PROT_WOTH (ia->ia_prot); - - if (ac_test_exec (accesstest)) - ret = IA_PROT_XOTH (ia->ia_prot); - - if (!ret) - ret = -1; - else - ret = 0; - -out: - if (0 == ret) - gf_log (ACTRL, GF_LOG_TRACE, "Other access allowed"); - else - gf_log (ACTRL, GF_LOG_TRACE, "Other access not allowed"); - return ret; -} - - -/* Returns -1 on a failed access test with @operrno set to the relevant error - * number. - */ -int -ac_test_access (struct iatt *ia, uid_t uid, gid_t gid, gid_t *auxgids, - int auxcount, int accesstest, int testwho, int *operrno) -{ - int ret = -1; - char accesstest_str[32] = {0}; - - GF_VALIDATE_OR_GOTO (ACTRL, ia, out); - GF_VALIDATE_OR_GOTO (ACTRL, operrno, out); - - ac_set_accesstype_str (accesstest, accesstest_str, - sizeof (accesstest_str)); - gf_log (ACTRL, GF_LOG_TRACE, "Testing for accesstypes %s", - accesstest_str); - if ((uid == 0) && (gid == 0)) { - gf_log (ACTRL, GF_LOG_TRACE, "Root has access"); - return 0; - } - - if (ac_test_owner (testwho)) { - gf_log (ACTRL, GF_LOG_TRACE, "Testing owner access"); - ret = ac_test_owner_access (ia, uid, accesstest); - } - - if (ret == 0) { - goto out; - } - - if (ac_test_group (testwho)) { - gf_log (ACTRL, GF_LOG_TRACE, "Testing group access"); - ret = ac_test_group_access (ia, gid, auxgids, auxcount, - accesstest); - } - - if (ret == 0) { - goto out; - } - - if (ac_test_other (testwho)) { - gf_log (ACTRL, GF_LOG_TRACE, "Testing other access"); - ret = ac_test_other_access (ia, accesstest); - } - -out: - if (ret == -1) { - gf_log (ACTRL, GF_LOG_TRACE, "No access allowed"); - *operrno = EPERM; - } - - return ret; -} - - -int -ac_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path) -{ - int ret = -EFAULT; - - GF_VALIDATE_OR_GOTO (ACTRL, loc, out); - - if (inode) { - loc->inode = inode_ref (inode); - loc->ino = inode->ino; - } - - if (parent) - loc->parent = inode_ref (parent); - - loc->path = gf_strdup (path); - if (!loc->path) { - goto loc_wipe; - } - - loc->name = strrchr (loc->path, '/'); - if (loc->name) { - loc->name++; - } else { - gf_log (ACTRL, GF_LOG_ERROR, "path: %s, doesn't have '/'", - loc->path); - goto loc_wipe; - } - - ret = 0; -loc_wipe: - if (ret < 0) { - if (inode) - gf_log (ACTRL, GF_LOG_ERROR, "location fill failed for " - "inode: %s", uuid_utoa (inode->gfid)); - loc_wipe (loc); - } -out: - gf_log (ACTRL, GF_LOG_TRACE, "Returning %d", ret); - return ret; -} - - -int -ac_inode_loc_fill (inode_t *inode, loc_t *loc) -{ - char *resolvedpath = NULL; - inode_t *parent = NULL; - int ret = -EFAULT; - - GF_VALIDATE_OR_GOTO (ACTRL, inode, out); - GF_VALIDATE_OR_GOTO (ACTRL, loc, out); - - if ((inode) && (inode->ino == 1)) { - goto ignore_parent; - } - - parent = inode_parent (inode, 0, NULL); - GF_VALIDATE_OR_GOTO (ACTRL, parent, err); - -ignore_parent: - ret = inode_path (inode, NULL, &resolvedpath); - if (ret < 0) { - gf_log (ACTRL, GF_LOG_ERROR, "Unable to get path for inode: %s", - uuid_utoa (inode->gfid)); - goto err; - } - - ret = ac_loc_fill (loc, inode, parent, resolvedpath); - if (ret < 0) - goto err; - -err: - if (parent) - inode_unref (parent); - - if (resolvedpath) - GF_FREE (resolvedpath); - -out: - gf_log (ACTRL, GF_LOG_TRACE, "Returning %d", ret); - return ret; -} - - -int -ac_parent_loc_fill (loc_t *parentloc, loc_t *childloc) -{ - int ret = -1; - - GF_VALIDATE_OR_GOTO (ACTRL, parentloc, out); - GF_VALIDATE_OR_GOTO (ACTRL, childloc, out); - - ret = ac_inode_loc_fill (childloc->parent, parentloc); -out: - gf_log (ACTRL, GF_LOG_TRACE, "Returning %d", ret); - return ret; -} - - -int32_t -ac_truncate_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, - off_t offset) -{ - STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->truncate, loc, offset); - return 0; -} - - -int32_t -ac_truncate_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 = __get_frame_stub (frame); - 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; - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "truncate failed with " - "error: %s", strerror (op_errno)); - STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int32_t -ac_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ac_truncate_resume (frame, this, loc, offset); - return 0; - } - stub = fop_truncate_stub (frame, ac_truncate_resume, loc, offset); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - STACK_WIND (frame, ac_truncate_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, loc); - - ret = 0; -out: - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "truncate failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (truncate, frame, -1, -ret, NULL, NULL); - } - - return 0; -} - - -int32_t -ac_access_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask) -{ - STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->access, loc, mask); - return 0; -} - - -int32_t -ac_access_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; - int32_t mask = 0; - int acctest = 0; - - stub = __get_frame_stub (frame); - mask = stub->args.access.mask; - - /* If mask requests test for file existence then do not - * return a failure with ENOENT, instead return a failed - * access test. - */ - if (op_ret == -1) { - if (mask & F_OK) - op_errno = EACCES; - else - op_errno = errno; - - goto out; - } - - if (R_OK & mask) - acctest |= ACCTEST_READ; - else if (W_OK & mask) - acctest |= ACCTEST_WRITE; - else if (X_OK & mask) - acctest |= ACCTEST_EXEC; - else - acctest = 0; - - op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid, - frame->root->groups, frame->root->ngrps, - acctest, ACCTEST_ANY, &op_errno); - if (op_ret == -1) - goto out; - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "access failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (access, frame, -1, op_errno); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int32_t -ac_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ac_access_resume (frame, this, loc, mask); - return 0; - } - stub = fop_access_stub (frame, ac_access_resume, loc, mask); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - STACK_WIND (frame, ac_access_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, loc); - ret = 0; - -out: - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "access failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (access, frame, -1, -ret); - } - - return 0; -} - - -int32_t -ac_readlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, - size_t size) -{ - STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readlink, loc, size); - return 0; -} - - -int32_t -ac_readlink_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 = __get_frame_stub (frame); - 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_READ, ACCTEST_ANY, &op_errno); - if (op_ret == -1) - goto out; - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "readlink failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int32_t -ac_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ac_readlink_resume (frame, this, loc, size); - return 0; - } - stub = fop_readlink_stub (frame, ac_readlink_resume, loc, size); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - STACK_WIND (frame, ac_readlink_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, loc); - ret = 0; - -out: - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "readlink failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (readlink, frame, -1, -ret, NULL, NULL); - } - - return 0; -} - - -int -ac_mknod_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dev_t rdev, dict_t *params) -{ - STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, params); - return 0; -} - - -int32_t -ac_mknod_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 = __get_frame_stub (frame); - 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) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "mknod failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL, - NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int -ac_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dev_t rdev, dict_t *params) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - loc_t parentloc = {0, }; - - if (__is_fuse_call (frame)) { - ac_mknod_resume (frame, this, loc, mode, rdev, params); - return 0; - } - stub = fop_mknod_stub (frame, ac_mknod_resume, loc, mode, rdev, params); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - ret = ac_parent_loc_fill (&parentloc, loc); - if (ret < 0) - goto out; - - STACK_WIND (frame, ac_mknod_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - if (ret < 0) { - /* Erase any stored frame before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "mknod failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (mknod, frame, -1, -ret, NULL, NULL, NULL, - NULL); - } - - return 0; -} - - -int -ac_mkdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dict_t *params) -{ - STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mkdir, loc, mode, params); - return 0; -} - - -int32_t -ac_mkdir_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 = __get_frame_stub (frame); - 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) { - /* On a failed write test on parent dir, we need to return - * EACCES, not EPERM that is returned by default by - * ac_test_access. - */ - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "mkdir failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL, - NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int -ac_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, - dict_t *params) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - loc_t parentloc = {0, }; - - if (__is_fuse_call (frame)) { - ac_mkdir_resume (frame, this, loc, mode, params); - return 0; - } - stub = fop_mkdir_stub (frame, ac_mkdir_resume, loc, mode, params); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - ret = ac_parent_loc_fill (&parentloc, loc); - if (ret < 0) - goto out; - - STACK_WIND (frame, ac_mkdir_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - if (ret < 0) { - /* Erase the stored stub before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "mkdir failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (mkdir, frame, -1, -ret, NULL, NULL, NULL, - NULL); - } - - return 0; -} - - -int32_t -ac_unlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->unlink, loc); - return 0; -} - - -int32_t -ac_unlink_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 = __get_frame_stub (frame); - 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) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "unlink failed with error: %s", - strerror (op_errno)); - 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) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - loc_t parentloc = {0, }; - - if (__is_fuse_call (frame)) { - ac_unlink_resume (frame, this, loc); - return 0; - } - stub = fop_unlink_stub (frame, ac_unlink_resume, loc); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - ret = ac_parent_loc_fill (&parentloc, loc); - if (ret < 0) - goto out; - - STACK_WIND (frame, ac_unlink_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - if (ret < 0) { - /* Erase the stored stub before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "unlink failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (unlink, frame, -1, -ret, NULL, NULL); - } - - return 0; -} - - -int -ac_rmdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags) -{ - STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rmdir, loc, flags); - return 0; -} - - -int32_t -ac_rmdir_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 = __get_frame_stub (frame); - 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) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "rmdir failed with error: %s", - strerror (op_errno)); - 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) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - loc_t parentloc = {0, }; - - if (__is_fuse_call (frame)) { - ac_rmdir_resume (frame, this, loc, flags); - return 0; - } - stub = fop_rmdir_stub (frame, ac_rmdir_resume, loc, flags); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - ret = ac_parent_loc_fill (&parentloc, loc); - if (ret < 0) - goto out; - - STACK_WIND (frame, ac_rmdir_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - if (ret < 0) { - /* Erase the stored stub before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "rmdir failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (rmdir, frame, -1, -ret, NULL, NULL); - } - - return 0; -} - - -int32_t -ac_symlink_resume (call_frame_t *frame, xlator_t *this, const char *linkname, - loc_t *loc, dict_t *params) -{ - STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->symlink, linkname, loc, params); - return 0; -} - - -int32_t -ac_symlink_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 = __get_frame_stub (frame); - 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) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "symlink failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL, - NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int -ac_symlink (call_frame_t *frame, xlator_t *this, const char *linkname, - loc_t *loc, dict_t *params) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - loc_t parentloc = {0, }; - - if (__is_fuse_call (frame)) { - ac_symlink_resume (frame, this, linkname, loc, params); - return 0; - } - stub = fop_symlink_stub (frame, ac_symlink_resume, linkname, loc, - params); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - ret = ac_parent_loc_fill (&parentloc, loc); - if (ret < 0) - goto out; - - STACK_WIND (frame, ac_symlink_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - if (ret < 0) { - /* Erase the stored stub before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "symlink failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (symlink, frame, -1, -ret, NULL, NULL, NULL, - NULL); - } - - return 0; -} - - -int32_t -ac_rename_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc, - loc_t *newloc) -{ - STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rename, oldloc, newloc); - return 0; -} - - -int32_t -ac_rename_dst_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 = __get_frame_stub (frame); - 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) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "rename failed with error: %s", - strerror (op_errno)); - 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_src_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; - - 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; - } - - 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_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); - gf_log (this->name, GF_LOG_ERROR, "rename failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL, - NULL, NULL, NULL); - } - - return 0; -} - - -int32_t -ac_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - loc_t parentloc = {0, }; - - if (__is_fuse_call (frame)) { - ac_rename_resume (frame, this, oldloc, newloc); - return 0; - } - stub = fop_rename_stub (frame, ac_rename_resume, oldloc, newloc); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - ret = ac_parent_loc_fill (&parentloc, oldloc); - if (ret < 0) - goto out; - - STACK_WIND (frame, ac_rename_src_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - if (ret < 0) { - /* Erase the stored stub before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "rename failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (rename, frame, -1, -ret, NULL, NULL, NULL, - NULL, NULL); - } - - return 0; -} - - -int32_t -ac_link_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc, - loc_t *newloc) -{ - STACK_WIND (frame, default_link_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->link, oldloc, newloc); - return 0; -} - - -int32_t -ac_link_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 = __get_frame_stub (frame); - 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) { - /* By default ac_test_access sets the op_errno to EPERM - * but in the case of link, we need to return EACCES to meet - * posix requirements when a write permission is not available - * for the new directory. - */ - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "link failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, - NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int32_t -ac_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - loc_t parentloc = {0, }; - - if (__is_fuse_call (frame)) { - ac_link_resume (frame, this, oldloc, newloc); - return 0; - } - stub = fop_link_stub (frame, ac_link_resume, oldloc, newloc); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - ret = ac_parent_loc_fill (&parentloc, newloc); - if (ret < 0) - goto out; - - STACK_WIND (frame, ac_link_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - if (ret < 0) { - /* Erase the stored stub before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "link failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (link, frame, -1, -ret, NULL, NULL, NULL, - NULL); - } - - return 0; -} - - -int32_t -ac_create_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, - int32_t flags, mode_t mode, fd_t *fd, dict_t *params) -{ - STACK_WIND (frame, default_create_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->create, loc, flags, mode, - fd, params); - return 0; -} - - -int32_t -ac_create_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 = __get_frame_stub (frame); - 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) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "create failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL, - NULL, NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int32_t -ac_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, - mode_t mode, fd_t *fd, dict_t *params) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - loc_t parentloc = {0, }; - - if (__is_fuse_call (frame)) { - ac_create_resume (frame, this, loc, flags, mode, fd, params); - return 0; - } - stub = fop_create_stub (frame, ac_create_resume, loc, flags, mode, - fd, params); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - ret = ac_parent_loc_fill (&parentloc, loc); - if (ret < 0) - goto out; - - STACK_WIND (frame, ac_create_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - if (ret < 0) { - /* Erase the stored stub before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "create failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (create, frame, -1, -ret, NULL, NULL, NULL, - NULL, NULL); - } - - return 0; -} - - -int32_t -ac_open_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, - fd_t *fd, int32_t wbflags) -{ - STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags); - return 0; -} - - -int32_t -ac_open_create_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 = __get_frame_stub (frame); - 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) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "open failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int -ac_open_create (call_stub_t *stub) -{ - int ret = -EFAULT; - loc_t parentloc = {0, }; - xlator_t *this = NULL; - - if (!stub) - return ret; - - ret = ac_parent_loc_fill (&parentloc, &stub->args.open.loc); - if (ret < 0) - goto out; - - this = stub->frame->this; - STACK_WIND (stub->frame, ac_open_create_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &parentloc); - loc_wipe (&parentloc); - ret = 0; - -out: - return ret; -} - - -int32_t -ac_open_only_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; - int acctest = 0; - int32_t flags = 0; - - stub = __get_frame_stub (frame); - if (op_ret == -1) - goto out; - - flags = stub->args.open.flags; - /* The permissions we test for depend on how the open needs to be - * performed. */ - if ((flags & O_ACCMODE) == O_RDONLY) - acctest = ACCTEST_READ; - else if (((flags & O_ACCMODE) == O_RDWR) || - ((flags & O_ACCMODE) == O_WRONLY)) - acctest = ACCTEST_WRITE; - - op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid, - frame->root->groups, frame->root->ngrps, - acctest, ACCTEST_ANY, &op_errno); - if (op_ret == -1) - goto out; - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "open failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int -ac_open_only (call_stub_t *stub) -{ - int ret = -EFAULT; - xlator_t *this = NULL; - - if (!stub) - return ret; - - this = stub->frame->this; - STACK_WIND (stub->frame, ac_open_only_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, &stub->args.open.loc); - return 0; -} - -int32_t -ac_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, - fd_t *fd, int32_t wbflags) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ret = ac_open_resume (frame, this, loc, flags, fd, wbflags); - return 0; - } - - stub = fop_open_stub (frame, ac_open_resume, loc, flags, fd, wbflags); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - /* If we are not supposed to create the file then there is no need to - * check the parent dir permissions. */ - if (flags & O_CREAT) - ret = ac_open_create (stub); - else - ret = ac_open_only (stub); - -out: - if (ret < 0) { - /* Erase the stored stub before unwinding. */ - stub = __get_frame_stub (frame); - if (stub) - call_stub_destroy (stub); - gf_log (this->name, GF_LOG_ERROR, "open failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (open, frame, -1, -ret, NULL); - } - - return 0; -} - - -int32_t -ac_readv_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) -{ - STACK_WIND (frame, default_readv_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->readv, fd, size, offset); - return 0; -} - - -int32_t -ac_readv_fstat_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 = __get_frame_stub (frame); - 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_READ, ACCTEST_ANY, &op_errno); - if (op_ret == -1) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "readv failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, - NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int32_t -ac_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ret = ac_readv_resume (frame, this, fd, size, offset); - return 0; - } - - stub = fop_readv_stub (frame, ac_readv_resume, fd, size, offset); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - STACK_WIND (frame, ac_readv_fstat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->fstat, fd); - ret = 0; - -out: - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "readv failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (readv, frame, -1, -ret, NULL, 0, NULL, - NULL); - } - - return 0; -} - - -int32_t -ac_writev_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iovec *vector, int32_t count, off_t offset, - struct iobref *iobref) -{ - STACK_WIND (frame, default_writev_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->writev, fd, vector, count, offset, - iobref); - return 0; -} - - -int32_t -ac_writev_fstat_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 = __get_frame_stub (frame); - 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) { - op_errno = EACCES; - goto out; - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "writev failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int32_t -ac_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, - int32_t count, off_t offset, struct iobref *iobref) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ret = ac_writev_resume (frame, this, fd, vector, count, - offset, iobref); - return 0; - } - - stub = fop_writev_stub (frame, ac_writev_resume, fd, vector, count, - offset, iobref); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - STACK_WIND (frame, ac_writev_fstat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->fstat, fd); - ret = 0; - -out: - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "writev failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (writev, frame, -1, -ret, NULL, NULL); - } - - return 0; -} - - -int32_t -ac_opendir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) -{ - STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->opendir, loc, fd); - return 0; -} - - -int32_t -ac_opendir_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 = __get_frame_stub (frame); - 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_READ, ACCTEST_ANY, &op_errno); - if (op_ret == -1) - goto out; - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "opendir failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - -int32_t -ac_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ret = ac_opendir_resume (frame, this, loc, fd); - return 0; - } - - stub = fop_opendir_stub (frame, ac_opendir_resume, loc, fd); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - STACK_WIND (frame, ac_opendir_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, loc); - ret = 0; - -out: - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "opendir failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (opendir, frame, -1, -ret, NULL); - } - - return 0; -} - - -int32_t -ac_setattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, - struct iatt *buf, int32_t valid) -{ - STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setattr, loc, buf, valid); - return 0; -} - - -int32_t -ac_setattr_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; - int32_t valid = 0; - struct iatt *setbuf = NULL; - - stub = __get_frame_stub (frame); - 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; - - 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 - * 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) { - op_ret = -1; - op_errno = EPERM; - goto out; - } - } - - /* non-super-user can modify file group if he is owner of a - * file and gid he is setting is in his groups list. - * Ref: posix-testsuite/chown/00.t - */ - if ((frame->root->uid != 0) && (gf_attr_gid_set (valid))) { - if (frame->root->uid != buf->ia_uid) { - op_ret = -1; - op_errno = EPERM; - goto out; - } - - 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) - goto out; - } - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "setattr failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - -int32_t -ac_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf, - int32_t valid) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ret = ac_setattr_resume (frame, this, loc, buf, valid); - return 0; - } - - stub = fop_setattr_stub (frame, ac_setattr_resume, loc, buf, valid); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - STACK_WIND (frame, ac_setattr_stat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->stat, loc); - ret = 0; - -out: - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "setattr failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (setattr, frame, -1, -ret, NULL, NULL); - } - - return 0; -} - - -int32_t -ac_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iatt *buf, int32_t valid) -{ - STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsetattr, fd, buf, valid); - return 0; -} - - -int32_t -ac_fsetattr_fstat_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; - int32_t valid = 0; - struct iatt *setbuf = NULL; - - stub = __get_frame_stub (frame); - 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; - - 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 - * 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) { - op_ret = -1; - op_errno = EPERM; - goto out; - } - } - - /* non-super-user can modify file group if he is owner of a - * file and gid he is setting is in his groups list. - * Ref: posix-testsuite/chown/00.t - */ - if ((frame->root->uid != 0) && (gf_attr_gid_set (valid))) { - if (frame->root->uid != buf->ia_uid) { - op_ret = -1; - op_errno = EPERM; - goto out; - } - - 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) - goto out; - } - } - - call_resume (stub); -out: - if (op_ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "fsetattr failed with error: %s", - strerror (op_errno)); - STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL); - if (stub) - call_stub_destroy (stub); - } - - return 0; -} - - -int32_t -ac_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *buf, - int32_t valid) -{ - call_stub_t *stub = NULL; - int ret = -EFAULT; - - if (__is_fuse_call (frame)) { - ret = ac_fsetattr_resume (frame, this, fd, buf, valid); - return 0; - } - - stub = fop_fsetattr_stub (frame, ac_fsetattr_resume, fd, buf, valid); - if (!stub) { - ret = -ENOMEM; - goto out; - } - - frame->local = stub; - STACK_WIND (frame, ac_fsetattr_fstat_cbk, FIRST_CHILD (this), - FIRST_CHILD (this)->fops->fstat, fd); - ret = 0; - -out: - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "fsetattr failed with error: %s", - strerror (-ret)); - STACK_UNWIND_STRICT (fsetattr, frame, -1, -ret, NULL, NULL); - } - - return 0; -} - - -struct xlator_fops fops = { - .truncate = ac_truncate, - .access = ac_access, - .readlink = ac_readlink, - .mknod = ac_mknod, - .mkdir = ac_mkdir, - .unlink = ac_unlink, - .rmdir = ac_rmdir, - .symlink = ac_symlink, - .rename = ac_rename, - .link = ac_link, - .create = ac_create, - .open = ac_open, -/* - * Allow Writes and Reads to proceed without permission checks because: - * a. We expect that when the fds are opened, thats when the perm checks happen - * depending on the read/write mode used. - * - * b. In case of nfs clients, we expect the nfs clients to perform the checks - * based on getattr/access nfs requests. - * - * Keep these functions around in case we ever run into a nfs client that - * depends on nfs server to perform these checks. Till then, just remove the - * references from here instead. - .readv = ac_readv, - .writev = ac_writev, -*/ - .opendir = ac_opendir, - .setattr = ac_setattr, - .fsetattr = ac_fsetattr, -}; - -int -init (xlator_t *this) -{ - int ret = -1; - - if (!this->children || this->children->next) { - gf_log (this->name, GF_LOG_ERROR, - "FATAL: access-control not configured with " - "exactly one child"); - goto out; - } - - if (!this->parents) { - gf_log (this->name, GF_LOG_WARNING, - "dangling volume. check volfile "); - } - - ret = 0; -out: - return ret; -} - -void -fini (xlator_t *this) -{ - return; -} - -struct xlator_cbks cbks = { -}; diff --git a/xlators/features/access-control/src/access-control.h b/xlators/features/access-control/src/access-control.h deleted file mode 100644 index 8e2d6b6b966..00000000000 --- a/xlators/features/access-control/src/access-control.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.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/>. -*/ - - -#ifndef __ACCESS_CONTROL_H_ -#define __ACCESS_CONTROL_H_ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#define ACTRL "access-control" -#define ACCTEST_READ 0x1 -#define ACCTEST_WRITE 0x2 -#define ACCTEST_EXEC 0x4 -#define ACCTEST_DONTCARE 0x8 - -/* Note if the caller is only interested in ownership test i.e. one of the below -+ * in combination with GF_ACCTEST_DONTCARE, then only one type of user's owner -+ * ship can be tested with one call to gf_test_access, i.e. we can only -+ * check of either owner and group, if both need to be tested for a specific -+ * (uid, gid) pair then two calls will be needed. -+ */ -#define ACCTEST_OWNER 0x1 -#define ACCTEST_GROUP 0x2 -#define ACCTEST_OTHER 0x4 - -/* Signifies any user, as long as we get access. */ -#define ACCTEST_ANY (ACCTEST_OWNER | ACCTEST_GROUP | ACCTEST_OTHER) - -#define ac_test_owner(acc) ((acc) & ACCTEST_OWNER) -#define ac_test_group(acc) ((acc) & ACCTEST_GROUP) -#define ac_test_other(acc) ((acc) & ACCTEST_OTHER) -#define ac_test_dontcare(acc) ((acc) & ACCTEST_DONTCARE) -#define ac_test_read(acc) ((acc) & ACCTEST_READ) -#define ac_test_write(acc) ((acc) & ACCTEST_WRITE) -#define ac_test_exec(acc) ((acc) & ACCTEST_EXEC) -#endif |