[PATCH v3] vfs_glusterfs: Implement proper mashalling/unmarshalling of ACLs
Anand Avati
avati at redhat.com
Sun Aug 11 13:49:52 MDT 2013
On 8/11/13 12:40 PM, Raghavendra Talur wrote:
> I would prefer to have sizes of header and entries
> #defined.(4 and 8 bytes)
>
OK. Will send out an updated v4.
Thanks,
Avati
> +1 for the patch.
>
> Thanks!
> Raghavendra Talur | Red Hat Storage Developer | Bangalore | +918039245176
>
> ----- Original Message -----
> From: "Anand Avati" <avati at redhat.com>
> To: samba-technical at lists.samba.org
> Cc: jra at samba.org, s at ssimo.org, rtalur at redhat.com, crh at redhat.com
> Sent: Saturday, August 10, 2013 2:36:34 PM
> Subject: [PATCH v3] vfs_glusterfs: Implement proper mashalling/unmarshalling of ACLs
>
> Use the primitives available in Samba byteorder.h for implementing
> proper (un)marshalling of ACL xattrs.
>
> Signed-off-by: Anand Avati <avati at redhat.com>
> ---
> - fixed typos
> - re-organized code to minimize patch size and improve readability
> - apologies for the spam!
>
> source3/modules/vfs_glusterfs.c | 151 ++++++++++++++++++++++++++++-----------
> 1 files changed, 108 insertions(+), 43 deletions(-)
>
> diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
> index af8d5b7..8069b39 100644
> --- a/source3/modules/vfs_glusterfs.c
> +++ b/source3/modules/vfs_glusterfs.c
> @@ -992,13 +992,36 @@ static int vfs_gluster_set_offline(struct vfs_handle_struct *handle,
> return -1;
> }
>
> -/* Posix ACL Operations */
> +/*
> + Gluster ACL Format:
> +
> + Size = 4 (header) + N * 8 (entry)
> +
> + Offset Size Field (Little Endian)
> + -------------------------------------
> + 0-3 4-byte Version
> +
> + 4-5 2-byte Entry-1 tag
> + 6-7 2-byte Entry-1 perm
> + 8-11 4-byte Entry-1 id
> +
> + 12-13 2-byte Entry-2 tag
> + 14-15 2-byte Entry-2 perm
> + 16-19 4-byte Entry-2 id
>
> + ...
> +
> + */
> +
> +/* header version */
> #define GLUSTER_ACL_VERSION 2
> +
> +/* perm bits */
> #define GLUSTER_ACL_READ 0x04
> #define GLUSTER_ACL_WRITE 0x02
> #define GLUSTER_ACL_EXECUTE 0x01
>
> +/* tag values */
> #define GLUSTER_ACL_UNDEFINED_TAG 0x00
> #define GLUSTER_ACL_USER_OBJ 0x01
> #define GLUSTER_ACL_USER 0x02
> @@ -1009,58 +1032,46 @@ static int vfs_gluster_set_offline(struct vfs_handle_struct *handle,
>
> #define GLUSTER_ACL_UNDEFINED_ID (-1)
>
> -struct gluster_ace {
> - uint16_t tag;
> - uint16_t perm;
> - uint32_t id;
> -};
> -
> -struct gluster_acl_header {
> - uint32_t version;
> - struct gluster_ace entries[];
> -};
> -
> static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size,
> TALLOC_CTX *mem_ctx)
> {
> int count;
> size_t size;
> - struct gluster_ace *ace;
> struct smb_acl_entry *smb_ace;
> - struct gluster_acl_header *hdr;
> struct smb_acl_t *result;
> int i;
> + int offset;
> uint16_t tag;
> uint16_t perm;
> uint32_t id;
>
> size = xattr_size;
>
> - if (size < sizeof(*hdr)) {
> - /* ACL should be at least as big as the header */
> + if (size < 4) {
> + /* ACL should be at least as big as the header (4 bytes) */
> errno = EINVAL;
> return NULL;
> }
>
> - size -= sizeof(*hdr);
> + size -= 4; /* size of header = 4 bytes */
>
> - if (size % sizeof(*ace)) {
> + if (size % 8) {
> /* Size of entries must strictly be a multiple of
> - size of an ACE
> + size of an ACE (8 bytes)
> */
> errno = EINVAL;
> return NULL;
> }
>
> - count = size / sizeof(*ace);
> + count = size / 8;
>
> - hdr = (void *)buf;
> -
> - if (ntohl(hdr->version) != GLUSTER_ACL_VERSION) {
> + /* Version is the first 4 bytes of the ACL */
> + if (IVAL(buf, 0) != GLUSTER_ACL_VERSION) {
> DEBUG(0, ("Unknown gluster ACL version: %d\n",
> - ntohl(hdr->version)));
> + IVAL(buf, 0)));
> return NULL;
> }
> + offset = 4;
>
> result = sys_acl_init(mem_ctx);
> if (!result) {
> @@ -1078,10 +1089,19 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size,
> result->count = count;
>
> smb_ace = result->acl;
> - ace = hdr->entries;
>
> for (i = 0; i < count; i++) {
> - tag = ntohs(ace->tag);
> + /* TAG is the first 2 bytes of an entry */
> + tag = SVAL(buf, offset);
> + offset += 2;
> +
> + /* PERM is the next 2 bytes of an entry */
> + perm = SVAL(buf, offset);
> + offset += 2;
> +
> + /* ID is the last 4 bytes of an entry */
> + id = IVAL(buf, offset);
> + offset += 4;
>
> switch(tag) {
> case GLUSTER_ACL_USER:
> @@ -1107,7 +1127,6 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size,
> return NULL;
> }
>
> - id = ntohl(ace->id);
>
> switch(smb_ace->a_type) {
> case SMB_ACL_USER:
> @@ -1120,8 +1139,6 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size,
> break;
> }
>
> - perm = ntohs(ace->perm);
> -
> smb_ace->a_perm = 0;
> smb_ace->a_perm |=
> ((perm & GLUSTER_ACL_READ) ? SMB_ACL_READ : 0);
> @@ -1130,7 +1147,6 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size,
> smb_ace->a_perm |=
> ((perm & GLUSTER_ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0);
>
> - ace++;
> smb_ace++;
> }
>
> @@ -1138,21 +1154,54 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size,
> }
>
>
> +static int gluster_ace_cmp(const void *left, const void *right)
> +{
> + int ret = 0;
> + uint16_t tag_left, tag_right;
> + uint32_t id_left, id_right;
> +
> + /*
> + Sorting precedence:
> +
> + - Smaller TAG values must be earlier.
> +
> + - Within same TAG, smaller identifiers must be earlier, E.g:
> + UID 0 entry must be earlier than UID 200
> + GID 17 entry must be earlier than GID 19
> + */
> +
> + /* TAG is the first element in the entry */
> + tag_left = SVAL(left, 0);
> + tag_right = SVAL(right, 0);
> +
> + ret = (tag_left - tag_right);
> + if (!ret) {
> + /* ID is the third element in the entry, after two short
> + integers (tag and perm), i.e at offset 4.
> + */
> + id_left = SVAL(left, 4);
> + id_right = SVAL(right, 4);
> + ret = id_left - id_right;
> + }
> +
> + return ret;
> +}
> +
> +
> static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len)
> {
> ssize_t size;
> - struct gluster_ace *ace;
> struct smb_acl_entry *smb_ace;
> - struct gluster_acl_header *hdr;
> int i;
> int count;
> uint16_t tag;
> uint16_t perm;
> uint32_t id;
> + int offset;
>
> count = theacl->count;
>
> - size = sizeof(*hdr) + (count * sizeof(*ace));
> + size = 4 + (count * 8);
> if (!buf) {
> return size;
> }
> @@ -1162,13 +1211,14 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len)
> return -1;
> }
>
> - hdr = (void *)buf;
> - ace = hdr->entries;
> smb_ace = theacl->acl;
>
> - hdr->version = htonl(GLUSTER_ACL_VERSION);
> + /* Version is the first 4 bytes of the ACL */
> + SIVAL(buf, 0, GLUSTER_ACL_VERSION);
> + offset = 4;
>
> for (i = 0; i < count; i++) {
> + /* Calculate tag */
> switch(smb_ace->a_type) {
> case SMB_ACL_USER:
> tag = GLUSTER_ACL_USER;
> @@ -1195,8 +1245,8 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len)
> return -1;
> }
>
> - ace->tag = ntohs(tag);
>
> + /* Calculate id */
> switch(smb_ace->a_type) {
> case SMB_ACL_USER:
> id = smb_ace->info.user.uid;
> @@ -1209,20 +1259,35 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len)
> break;
> }
>
> - ace->id = ntohl(id);
> + /* Calculate perm */
> + perm = 0;
>
> - ace->perm = 0;
> - ace->perm |=
> + perm |=
> ((smb_ace->a_perm & SMB_ACL_READ) ? GLUSTER_ACL_READ : 0);
> - ace->perm |=
> + perm |=
> ((smb_ace->a_perm & SMB_ACL_WRITE) ? GLUSTER_ACL_WRITE : 0);
> - ace->perm |=
> + perm |=
> ((smb_ace->a_perm & SMB_ACL_EXECUTE) ? GLUSTER_ACL_EXECUTE : 0);
>
> - ace++;
> +
> + /* TAG is the first 2 bytes of an entry */
> + SSVAL(buf, offset, tag);
> + offset += 2;
> +
> + /* PERM is the next 2 bytes of an entry */
> + SSVAL(buf, offset, perm);
> + offset += 2;
> +
> + /* ID is the last 4 bytes of an entry */
> + SIVAL(buf, offset, id);
> + offset += 4;
> +
> smb_ace++;
> }
>
> + /* Skip the header, sort @count number of 8-byte entries */
> + qsort(buf+4, count, 8, gluster_ace_cmp);
> +
> return size;
> }
>
>
More information about the samba-technical
mailing list