[Pkg-samba-maint] [samba] 11/29: vfs_glusterfs: Implement proper mashalling/unmarshalling of ACLs

Jelmer Vernooij jelmer at moszumanska.debian.org
Fri Dec 6 23:16:45 UTC 2013


This is an automated email from the git hooks/post-receive script.

jelmer pushed a commit to branch samba_4.1
in repository samba.

commit 683ac33b6e3fc3b237bd7efca30e1d5d66d1c1a3
Author: Anand Avati <avati at redhat.com>
Date:   Sun Aug 11 15:59:29 2013 -0400

    vfs_glusterfs: Implement proper mashalling/unmarshalling of ACLs
    
    Use the primitives available in Samba byteorder.h for implementing
    proper (un)marshalling of ACL xattrs.
    - Incorporated Raghavendra Talur's comments on v3
    
    Signed-off-by: Anand Avati <avati at redhat.com>
    Signed-off-by: Raghavendra Talur <rtalur at redhat.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Christopher R. Hertel <crh at samba.org>
    Tested-by: Jose A. Rivera <jarrpa at redhat.com>
    
    Autobuild-User(master): Simo Sorce <idra at samba.org>
    Autobuild-Date(master): Fri Aug 16 20:34:51 CEST 2013 on sn-devel-104
---
 source3/modules/vfs_glusterfs.c | 153 +++++++++++++++++++++++++++++-----------
 1 file changed, 111 insertions(+), 42 deletions(-)

diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index af8d5b7..eac1b24 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,49 @@ 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[];
-};
+#define GLUSTER_ACL_HEADER_SIZE    4
+#define GLUSTER_ACL_ENTRY_SIZE     8
 
 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 < GLUSTER_ACL_HEADER_SIZE) {
+		/* ACL should be at least as big as the header (4 bytes) */
 		errno = EINVAL;
 		return NULL;
 	}
 
-	size -= sizeof(*hdr);
+	size -= GLUSTER_ACL_HEADER_SIZE; /* size of header = 4 bytes */
 
-	if (size % sizeof(*ace)) {
+	if (size % GLUSTER_ACL_ENTRY_SIZE) {
 		/* 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 / GLUSTER_ACL_ENTRY_SIZE;
 
-	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 = GLUSTER_ACL_HEADER_SIZE;
 
 	result = sys_acl_init(mem_ctx);
 	if (!result) {
@@ -1078,10 +1092,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 +1130,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 +1142,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 +1150,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 +1157,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 = IVAL(left, 4);
+		id_right = IVAL(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 = GLUSTER_ACL_HEADER_SIZE + (count * GLUSTER_ACL_ENTRY_SIZE);
 	if (!buf) {
 		return size;
 	}
@@ -1162,13 +1214,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 = GLUSTER_ACL_HEADER_SIZE;
 
 	for (i = 0; i < count; i++) {
+		/* Calculate tag */
 		switch(smb_ace->a_type) {
 		case SMB_ACL_USER:
 			tag = GLUSTER_ACL_USER;
@@ -1195,8 +1248,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 +1262,36 @@ 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+GLUSTER_ACL_HEADER_SIZE, count, GLUSTER_ACL_ENTRY_SIZE,
+	      gluster_ace_cmp);
+
 	return size;
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-samba/samba.git




More information about the Pkg-samba-maint mailing list