diff options
author | Santosh Kumar Pradhan <spradhan@redhat.com> | 2013-09-19 12:01:38 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-09-29 16:54:37 -0700 |
commit | e9554f7792d893f0ea8afe368829f9944ef52bdf (patch) | |
tree | 465039c76a2c87e2029c93c2fa3f288e7795254b /xlators | |
parent | 84fa8af38d2eab0f72349abb8136811bd3e96570 (diff) |
gNFS: Incorrect NFS ACL encoding for XFS
Problem:
Incorrect NFS ACL encoding causes "system.posix_acl_default"
setxattr failure on bricks on XFS file system. XFS (potentially
others?) doesn't understand when the 0x10 prefix is added to the
ACL type field for default ACLs (which the Linux NFS client adds)
which causes setfacl()->setxattr() to fail silently. NFS client
adds NFS_ACL_DEFAULT(0x1000) for default ACL.
FIX:
Mask the prefix (added by NFS client) OFF, so the setfacl is not
rejected when it hits the FS.
Original patch by: "Richard Wareing"
Change-Id: I17ad27d84f030cdea8396eb667ee031f0d41b396
BUG: 1009210
Signed-off-by: Santosh Kumar Pradhan <spradhan@redhat.com>
Reviewed-on: http://review.gluster.org/5980
Reviewed-by: Amar Tumballi <amarts@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 1 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-selfheal.c | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 4 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 9 | ||||
-rw-r--r-- | xlators/nfs/server/src/acl3.c | 79 | ||||
-rw-r--r-- | xlators/nfs/server/src/acl3.h | 17 | ||||
-rw-r--r-- | xlators/performance/md-cache/src/md-cache.c | 5 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 13 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 3 | ||||
-rw-r--r-- | xlators/system/posix-acl/src/posix-acl-xattr.c | 4 | ||||
-rw-r--r-- | xlators/system/posix-acl/src/posix-acl-xattr.h | 16 | ||||
-rw-r--r-- | xlators/system/posix-acl/src/posix-acl.h | 50 |
12 files changed, 93 insertions, 109 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index e0146c167..6cb022699 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -22,6 +22,7 @@ #include "dht-common.h" #include "defaults.h" #include "byte-order.h" +#include "glusterfs-acl.h" #include <sys/time.h> #include <libgen.h> diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c index 76ed26e1a..3fe96b1c7 100644 --- a/xlators/cluster/dht/src/dht-selfheal.c +++ b/xlators/cluster/dht/src/dht-selfheal.c @@ -17,6 +17,7 @@ #include "glusterfs.h" #include "xlator.h" #include "dht-common.h" +#include "glusterfs-acl.h" #define DHT_SET_LAYOUT_RANGE(layout,i,srt,chunk,cnt,path) do { \ layout->list[i].start = srt; \ diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 8d81ca1af..0ddf6ca35 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -35,6 +35,7 @@ #include "glusterd-store.h" #include "glusterd-volgen.h" #include "glusterd-pmap.h" +#include "glusterfs-acl.h" #include "xdr-generic.h" #include <sys/resource.h> @@ -68,9 +69,6 @@ #define NLMV4_VERSION 4 #define NLMV1_VERSION 1 -#define ACL_PROGRAM 100227 -#define ACLV3_VERSION 3 - #define CEILING_POS(X) (((X)-(int)(X)) > 0 ? (int)((X)+1) : (int)(X)) static glusterd_lock_t lock; diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 6fd8623b7..c1812a9a1 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -12,6 +12,7 @@ #include "fuse-bridge.h" #include "mount-gluster-compat.h" #include "glusterfs.h" +#include "glusterfs-acl.h" #ifdef __NetBSD__ #undef open /* in perfuse.h, pulled from mount-gluster-compat.h */ @@ -3011,8 +3012,8 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) } if (!priv->acl) { - if ((strcmp (name, "system.posix_acl_access") == 0) || - (strcmp (name, "system.posix_acl_default") == 0)) { + if ((strcmp (name, POSIX_ACL_ACCESS_XATTR) == 0) || + (strcmp (name, POSIX_ACL_DEFAULT_XATTR) == 0)) { send_fuse_err (this, finh, EOPNOTSUPP); GF_FREE (finh); return; @@ -3347,8 +3348,8 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) #endif if (!priv->acl) { - if ((strcmp (name, "system.posix_acl_access") == 0) || - (strcmp (name, "system.posix_acl_default") == 0)) { + if ((strcmp (name, POSIX_ACL_ACCESS_XATTR) == 0) || + (strcmp (name, POSIX_ACL_DEFAULT_XATTR) == 0)) { op_errno = ENOTSUP; goto err; } diff --git a/xlators/nfs/server/src/acl3.c b/xlators/nfs/server/src/acl3.c index 9e98124fe..bb3b95216 100644 --- a/xlators/nfs/server/src/acl3.c +++ b/xlators/nfs/server/src/acl3.c @@ -246,9 +246,9 @@ acl3_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this, getaclreply->daclentry.daclentry_val = cs->daclentry; /* FIXME: use posix_acl_from_xattr() */ - data = dict_get (dict, "system.posix_acl_access"); + data = dict_get (dict, POSIX_ACL_ACCESS_XATTR); if (data && (p = data_to_bin (data))) { - /* POSIX_ACL_XATTR_VERSION */ + /* POSIX_ACL_VERSION */ p++; while ((char *)p < (data->data + data->len)) { getaclreply->aclentry.aclentry_val[i].type = *(*(short **)&p)++; @@ -260,9 +260,9 @@ acl3_getacl_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } i = 0; - data = dict_get (dict, "system.posix_acl_default"); + data = dict_get (dict, POSIX_ACL_DEFAULT_XATTR); if (data && (p = data_to_bin (data))) { - /* POSIX_ACL_XATTR_VERSION */ + /* POSIX_ACL_VERSION */ p++; while ((char *)p < (data->data + data->len)) { getaclreply->daclentry.daclentry_val[i].type = *(*(short **)&p)++; @@ -443,11 +443,11 @@ acl3_setacl_resume (void *carg) nfs_request_user_init (&nfu, cs->req); xattr = dict_new(); if (cs->aclcount) - ret = dict_set_static_bin (xattr, "system.posix_acl_access", cs->aclxattr, + ret = dict_set_static_bin (xattr, POSIX_ACL_ACCESS_XATTR, cs->aclxattr, cs->aclcount * 8 + 4); if (cs->daclcount) - ret = dict_set_static_bin (xattr, "system.posix_acl_default", cs->daclxattr, - cs->daclcount * 8 + 4); + ret = dict_set_static_bin (xattr, POSIX_ACL_DEFAULT_XATTR, + cs->daclxattr, cs->daclcount * 8 + 4); ret = nfs_setxattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, xattr, 0, NULL, acl3_setacl_cbk, cs); @@ -481,7 +481,9 @@ acl3svc_setacl (rpcsvc_request_t *req) setaclargs setaclargs; aclentry *aclentry = NULL; struct aclentry *daclentry = NULL; - int *p = NULL, i = 0; + int i = 0; + struct posix_acl_xattr_header *bufheader = NULL; + struct posix_acl_xattr_entry *bufentry = NULL; if (!req) return ret; @@ -525,19 +527,58 @@ acl3svc_setacl (rpcsvc_request_t *req) (cs->daclcount > NFS_ACL_MAX_ENTRIES)) goto acl3err; /* FIXME: use posix_acl_to_xattr() */ - p = (int *)cs->aclxattr; - *(*(int **)&p)++ = POSIX_ACL_XATTR_VERSION; + /* Populate xattr buffer for user ACL */ + bufheader = (struct posix_acl_xattr_header *)(cs->aclxattr); + bufheader->version = htole32(POSIX_ACL_VERSION); + bufentry = bufheader->entries; for (i = 0; i < cs->aclcount; i++) { - *(*(short **)&p)++ = aclentry[i].type; - *(*(short **)&p)++ = aclentry[i].perm; - *(*(int **)&p)++ = aclentry[i].uid; + int uaceuid; + const struct aclentry *uace = &aclentry[i]; + switch (uace->type) { + case POSIX_ACL_USER: + case POSIX_ACL_GROUP: + uaceuid = uace->uid; + break; + default: + uaceuid = POSIX_ACL_UNDEFINED_ID; + break; + } + bufentry->tag = htole16(uace->type); + bufentry->perm = htole16(uace->perm); + bufentry->id = htole32(uaceuid); + + bufentry++; } - p = (int *)cs->daclxattr; - *(*(int **)&p)++ = POSIX_ACL_XATTR_VERSION; + + /* Populate xattr buffer for Default ACL */ + bufheader = (struct posix_acl_xattr_header *)(cs->aclxattr); + bufheader->version = htole32(POSIX_ACL_VERSION); + bufentry = bufheader->entries; for (i = 0; i < cs->daclcount; i++) { - *(*(short **)&p)++ = daclentry[i].type; - *(*(short **)&p)++ = daclentry[i].perm; - *(*(int **)&p)++ = daclentry[i].uid; + int daceuid; + int dacetype; + const struct aclentry *dace = &daclentry[i]; + /* + * For "default ACL", NFSv3 handles the 'type' differently + * i.e. by logical OR'ing 'type' with NFS_ACL_DEFAULT. + * Which the backend File system does not understand and + * that needs to be masked OFF. + */ + dacetype = (dace->type & ~(NFS_ACL_DEFAULT)); + switch (dacetype) { + case POSIX_ACL_USER: + case POSIX_ACL_GROUP: + daceuid = dace->uid; + break; + default: + daceuid = POSIX_ACL_UNDEFINED_ID; + break; + } + bufentry->tag = htole16(dacetype); + bufentry->perm = htole16(dace->perm); + bufentry->id = htole32(daceuid); + + bufentry++; } @@ -577,7 +618,7 @@ rpcsvc_actor_t acl3svc_actors[ACL3_PROC_COUNT] = { rpcsvc_program_t acl3prog = { .progname = "ACL3", .prognum = ACL_PROGRAM, - .progver = ACL_V3, + .progver = ACLV3_VERSION, .progport = GF_NFS3_PORT, .actors = acl3svc_actors, .numactors = ACL3_PROC_COUNT, diff --git a/xlators/nfs/server/src/acl3.h b/xlators/nfs/server/src/acl3.h index b668723c8..e0e61281a 100644 --- a/xlators/nfs/server/src/acl3.h +++ b/xlators/nfs/server/src/acl3.h @@ -11,18 +11,19 @@ #ifndef _ACL3_H #define _ACL3_H +#include "glusterfs-acl.h" + #define GF_ACL3_PORT 38469 #define GF_ACL GF_NFS"-ACL" -#define ACL_PROGRAM 100227 -#define ACL_V3 3 - -#define ACL_USER_OBJ 0x1 -#define ACL_GROUP_OBJ 0x4 -#define ACL_OTHER_OBJ 0x20 +/* + * NFSv3, identifies the default ACL by NFS_ACL_DEFAULT. Gluster + * NFS needs to mask it OFF before sending it upto POSIX layer + * or File system layer. + */ +#define NFS_ACL_DEFAULT 0x1000 -#define POSIX_ACL_XATTR_VERSION 0x0002 -#define NFS_ACL_MAX_ENTRIES 1024 +#define NFS_ACL_MAX_ENTRIES 1024 rpcsvc_program_t * acl3svc_init(xlator_t *nfsx); diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c index 9e211da1c..36d81887c 100644 --- a/xlators/performance/md-cache/src/md-cache.c +++ b/xlators/performance/md-cache/src/md-cache.c @@ -18,6 +18,7 @@ #include "dict.h" #include "xlator.h" #include "md-cache-mem-types.h" +#include "glusterfs-acl.h" #include <assert.h> #include <sys/time.h> @@ -42,12 +43,12 @@ static struct mdc_key { int check; } mdc_keys[] = { { - .name = "system.posix_acl_access", + .name = POSIX_ACL_ACCESS_XATTR, .load = 0, .check = 1, }, { - .name = "system.posix_acl_default", + .name = POSIX_ACL_DEFAULT_XATTR, .load = 0, .check = 1, }, diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index e1f87f444..e295f8850 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -45,6 +45,7 @@ #include "timer.h" #include "glusterfs3-xdr.h" #include "hashfn.h" +#include "glusterfs-acl.h" #include <fnmatch.h> char *marker_xattrs[] = {"trusted.glusterfs.quota.*", @@ -982,17 +983,17 @@ posix_acl_xattr_set (xlator_t *this, const char *path, dict_t *xattr_req) if (sys_lstat (path, &stat) != 0) goto out; - data = dict_get (xattr_req, "system.posix_acl_access"); + data = dict_get (xattr_req, POSIX_ACL_ACCESS_XATTR); if (data) { - ret = sys_lsetxattr (path, "system.posix_acl_access", + ret = sys_lsetxattr (path, POSIX_ACL_ACCESS_XATTR, data->data, data->len, 0); if (ret != 0) goto out; } - data = dict_get (xattr_req, "system.posix_acl_default"); + data = dict_get (xattr_req, POSIX_ACL_DEFAULT_XATTR); if (data) { - ret = sys_lsetxattr (path, "system.posix_acl_default", + ret = sys_lsetxattr (path, POSIX_ACL_DEFAULT_XATTR, data->data, data->len, 0); if (ret != 0) goto out; @@ -1013,8 +1014,8 @@ _handle_entry_create_keyvalue_pair (dict_t *d, char *k, data_t *v, if (!strcmp (GFID_XATTR_KEY, k) || !strcmp ("gfid-req", k) || - !strcmp ("system.posix_acl_default", k) || - !strcmp ("system.posix_acl_access", k) || + !strcmp (POSIX_ACL_DEFAULT_XATTR, k) || + !strcmp (POSIX_ACL_ACCESS_XATTR, k) || ZR_FILE_CONTENT_REQUEST(k)) { return 0; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 650a2d3a7..6bb743931 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -51,6 +51,7 @@ #include "glusterfs3-xdr.h" #include "hashfn.h" #include "posix-aio.h" +#include "glusterfs-acl.h" extern char *marker_xattrs[]; #define ALIGN_SIZE 4096 @@ -4650,7 +4651,7 @@ init (xlator_t *this) } } - size = sys_lgetxattr (dir_data->data, "system.posix_acl_access", + size = sys_lgetxattr (dir_data->data, POSIX_ACL_ACCESS_XATTR, NULL, 0); if ((size < 0) && (errno == ENOTSUP)) gf_log (this->name, GF_LOG_WARNING, diff --git a/xlators/system/posix-acl/src/posix-acl-xattr.c b/xlators/system/posix-acl/src/posix-acl-xattr.c index 460daf985..cc0937c5e 100644 --- a/xlators/system/posix-acl/src/posix-acl-xattr.c +++ b/xlators/system/posix-acl/src/posix-acl-xattr.c @@ -65,7 +65,7 @@ posix_acl_from_xattr (xlator_t *this, const char *xattr_buf, int xattr_size) count = size / sizeof (*entry); header = (struct posix_acl_xattr_header *) (xattr_buf); - entry = (struct posix_acl_xattr_entry *) (header + 1); + entry = (struct posix_acl_xattr_entry *) (header + 1); if (header->version != htole32 (POSIX_ACL_VERSION)) return NULL; @@ -126,7 +126,7 @@ posix_acl_to_xattr (xlator_t *this, struct posix_acl *acl, char *xattr_buf, return size; header = (struct posix_acl_xattr_header *) (xattr_buf); - entry = (struct posix_acl_xattr_entry *) (header + 1); + entry = (struct posix_acl_xattr_entry *) (header + 1); ace = acl->entries; header->version = htole32 (POSIX_ACL_VERSION); diff --git a/xlators/system/posix-acl/src/posix-acl-xattr.h b/xlators/system/posix-acl/src/posix-acl-xattr.h index c4e90f5f9..2933c2057 100644 --- a/xlators/system/posix-acl/src/posix-acl-xattr.h +++ b/xlators/system/posix-acl/src/posix-acl-xattr.h @@ -11,24 +11,10 @@ #ifndef _POSIX_ACL_XATTR_H #define _POSIX_ACL_XATTR_H -#include <stdint.h> - #include "common-utils.h" #include "posix-acl.h" #include "glusterfs.h" - -#define POSIX_ACL_VERSION 2 - -struct posix_acl_xattr_entry { - uint16_t tag; - uint16_t perm; - uint32_t id; -}; - -struct posix_acl_xattr_header { - uint32_t version; - struct posix_acl_xattr_entry entries[]; -}; +#include "glusterfs-acl.h" struct posix_acl *posix_acl_from_xattr (xlator_t *this, const char *buf, int size); diff --git a/xlators/system/posix-acl/src/posix-acl.h b/xlators/system/posix-acl/src/posix-acl.h index f85757106..c5e01967a 100644 --- a/xlators/system/posix-acl/src/posix-acl.h +++ b/xlators/system/posix-acl/src/posix-acl.h @@ -11,58 +11,10 @@ #ifndef _POSIX_ACL_H #define _POSIX_ACL_H -#include <stdint.h> - #include "xlator.h" #include "common-utils.h" #include "byte-order.h" - -#define POSIX_ACL_MINIMAL_ACE_COUNT 3 - -#define POSIX_ACL_READ (0x04) -#define POSIX_ACL_WRITE (0x02) -#define POSIX_ACL_EXECUTE (0x01) - -#define POSIX_ACL_UNDEFINED_TAG (0x00) -#define POSIX_ACL_USER_OBJ (0x01) -#define POSIX_ACL_USER (0x02) -#define POSIX_ACL_GROUP_OBJ (0x04) -#define POSIX_ACL_GROUP (0x08) -#define POSIX_ACL_MASK (0x10) -#define POSIX_ACL_OTHER (0x20) - -#define POSIX_ACL_UNDEFINED_ID ((id_t)-1) - - -struct posix_ace { - uint16_t tag; - uint16_t perm; - uint32_t id; -}; - - -struct posix_acl { - int refcnt; - int count; - struct posix_ace entries[]; -}; - - -struct posix_acl_ctx { - uid_t uid; - gid_t gid; - mode_t perm; - struct posix_acl *acl_access; - struct posix_acl *acl_default; -}; - - -struct posix_acl_conf { - gf_lock_t acl_lock; - uid_t super_uid; - struct posix_acl *minimal_acl; -}; - +#include "glusterfs-acl.h" struct posix_acl *posix_acl_new (xlator_t *this, int entry_count); struct posix_acl *posix_acl_ref (xlator_t *this, struct posix_acl *acl); |