[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