summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorMeghana Madhusudhan <mmadhusu@redhat.com>2014-11-10 15:20:51 +0530
committerRaghavendra Bhat <raghavendra@redhat.com>2015-01-02 01:26:52 -0800
commit0111ab923dd4c8f0985dd566c172cda31492b0f7 (patch)
tree77eb1f1609ee4f50a48121745dc537032c154a9d /xlators
parent8df622789ff991eba1ea01c7f8aa50ac6e507b31 (diff)
gNFS: Allow reading ACLs even without read permissions on the file.
When root-squash is enabled or when no permissions are given to a file, NFS threw permission errors. According to the kernel-nfs behaviour, no permissions are required to read ACLs. When no ACLs are set, the system call sys_lgetxattr fails and returns a ENODATA error. This translates to ESERVERFAULT error in NFS. Fuse makes an exception to this error and returns a success case. Similar changes are made here to achieve the expected behaviour. Change-Id: I46b8f5911114eb087a3f8ca4e921b6b41e83f3b3 BUG: 1177899 Signed-off-by: Meghana Madhusudhan <mmadhusu@redhat.com> Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: http://review.gluster.org/9085 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-on: http://review.gluster.org/9369 Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/nfs/server/src/acl3.c86
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c2
2 files changed, 79 insertions, 9 deletions
diff --git a/xlators/nfs/server/src/acl3.c b/xlators/nfs/server/src/acl3.c
index 5cd8b8e7061..b00e8170ebd 100644
--- a/xlators/nfs/server/src/acl3.c
+++ b/xlators/nfs/server/src/acl3.c
@@ -29,6 +29,7 @@
#include "nfs-generics.h"
#include "acl3.h"
#include "byte-order.h"
+#include "compat-errno.h"
static int
acl3_nfs_acl_to_xattr (aclentry *ace, void *xattrbuf,
@@ -244,7 +245,10 @@ acl3_setacl_reply (rpcsvc_request_t *req, setaclreply *reply)
return 0;
}
-
+/* acl3_getacl_cbk: fetch and decode the ACL in the POSIX_ACL_ACCESS_XATTR
+ *
+ * The POSIX_ACL_ACCESS_XATTR can be set on files and directories.
+ */
int
acl3_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, dict_t *dict,
@@ -260,17 +264,16 @@ acl3_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!frame->local) {
gf_log (GF_ACL, GF_LOG_ERROR, "Invalid argument,"
" frame->local NULL");
- return EINVAL;
+ return -EINVAL;
}
cs = frame->local;
getaclreply = &cs->args.getaclreply;
- if (op_ret < 0) {
+ if ((op_ret < 0) && (op_errno != ENODATA && op_errno != ENOATTR)) {
stat = nfs3_cbk_errno_status (op_ret, op_errno);
goto err;
}
getaclreply->aclentry.aclentry_val = cs->aclentry;
- getaclreply->daclentry.daclentry_val = cs->daclentry;
/* getfacl: NFS USER ACL */
data = dict_get (dict, POSIX_ACL_ACCESS_XATTR);
@@ -285,11 +288,59 @@ acl3_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = nfs3_errno_to_nfsstat3 (-aclcount);
goto err;
}
-
getaclreply->aclcount = aclcount;
getaclreply->aclentry.aclentry_len = aclcount;
}
+ acl3_getacl_reply (cs->req, getaclreply);
+ nfs3_call_state_wipe (cs);
+ return 0;
+
+err:
+ if (getaclreply)
+ getaclreply->status = stat;
+ acl3_getacl_reply (cs->req, getaclreply);
+ nfs3_call_state_wipe (cs);
+ return 0;
+}
+
+/* acl3_default_getacl_cbk: fetch and decode the ACL set in the
+ * POSIX_ACL_DEFAULT_XATTR xattr.
+ *
+ * The POSIX_ACL_DEFAULT_XATTR xattr is only set on directories, not on files.
+ *
+ * When done with POSIX_ACL_DEFAULT_XATTR, we also need to get and decode the
+ * ACL that can be set in POSIX_ACL_DEFAULT_XATTR.
+ */
+int
+acl3_default_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
+{
+ nfsstat3 stat = NFS3ERR_SERVERFAULT;
+ nfs3_call_state_t *cs = NULL;
+ data_t *data = NULL;
+ getaclreply *getaclreply = NULL;
+ int aclcount = 0;
+ int defacl = 1; /* DEFAULT ACL */
+ nfs_user_t nfu = {0, };
+ int ret = -1;
+
+ if (!frame->local) {
+ gf_log (GF_ACL, GF_LOG_ERROR, "Invalid argument,"
+ " frame->local NULL");
+ return -EINVAL;
+ }
+ cs = frame->local;
+ getaclreply = &cs->args.getaclreply;
+ if ((op_ret < 0) && (op_errno != ENODATA && op_errno != ENOATTR)) {
+ stat = nfs3_cbk_errno_status (op_ret, op_errno);
+ goto err;
+ }
+
+
+ getaclreply->daclentry.daclentry_val = cs->daclentry;
+
/* getfacl: NFS DEFAULT ACL */
data = dict_get (dict, POSIX_ACL_DEFAULT_XATTR);
if (data && data->data) {
@@ -308,8 +359,15 @@ acl3_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
getaclreply->daclentry.daclentry_len = aclcount;
}
- acl3_getacl_reply (cs->req, getaclreply);
- nfs3_call_state_wipe (cs);
+ getaclreply->attr_follows = TRUE;
+ nfs_request_user_init (&nfu, cs->req);
+ ret = nfs_getxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ POSIX_ACL_ACCESS_XATTR, NULL, acl3_getacl_cbk, cs);
+ if (ret < 0) {
+ stat = nfs3_errno_to_nfsstat3 (-ret);
+ goto err;
+ }
+
return 0;
err:
@@ -320,6 +378,7 @@ err:
return 0;
}
+
int
acl3_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
@@ -353,12 +412,21 @@ acl3_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
getaclreply->attr = nfs3_stat_to_fattr3 (buf);
nfs_request_user_init (&nfu, cs->req);
- ret = nfs_getxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- NULL, NULL, acl3_getacl_cbk, cs);
+ if (buf->ia_type == IA_IFDIR) {
+ ret = nfs_getxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ POSIX_ACL_DEFAULT_XATTR, NULL,
+ acl3_default_getacl_cbk, cs);
+ } else {
+ ret = nfs_getxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ POSIX_ACL_ACCESS_XATTR, NULL,
+ acl3_getacl_cbk, cs);
+ }
+
if (ret < 0) {
stat = nfs3_errno_to_nfsstat3 (-ret);
goto err;
}
+
return 0;
err:
getaclreply->status = stat;
diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c
index 947c71c7707..87d1e75ef9b 100644
--- a/xlators/system/posix-acl/src/posix-acl.c
+++ b/xlators/system/posix-acl/src/posix-acl.c
@@ -1962,11 +1962,13 @@ posix_acl_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto green;
else
goto red;
+
green:
STACK_WIND (frame, posix_acl_getxattr_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr,
loc, name, xdata);
return 0;
+
red:
STACK_UNWIND_STRICT (getxattr, frame, -1, EACCES, NULL, xdata);