Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Jul 2008 11:03:39 GMT
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 144478 for review
Message-ID:  <200807021103.m62B3d0O013866@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=144478

Change 144478 by trasz@trasz_traszkan on 2008/07/02 11:02:45

	NFSv4 ACLs, libc part.

Affected files ...

.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/Makefile.inc#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/Symbol.map#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_branding.c#1 add
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_calc_mask.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_copy.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_delete.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_delete_entry.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_entry.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_flags_nfs4.c#1 add
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_flags_nfs4.h#1 add
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_from_text.c#3 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_from_text_nfs4.c#1 add
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_get.c#3 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_init.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_perm.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_set.c#3 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_strip.c#1 add
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_support.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_support.h#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_to_text.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_to_text_nfs4.c#1 add
.. //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_valid.c#2 edit

Differences ...

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/Makefile.inc#2 (text+ko) ====

@@ -7,14 +7,20 @@
 	acl_delete.c			\
 	acl_delete_entry.c		\
 	acl_entry.c			\
+	acl_flags_nfs4.c		\
 	acl_free.c			\
 	acl_from_text.c			\
+	acl_from_text_nfs4.c		\
 	acl_get.c			\
 	acl_init.c			\
 	acl_perm.c			\
 	acl_set.c			\
 	acl_support.c			\
+	acl_branding.c			\
+	acl_strip.c			\
 	acl_to_text.c			\
+	acl_to_text_nfs4.c		\
+	acl_strip.c			\
 	acl_valid.c			\
 	extattr.c			\
 	mac.c				\

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/Symbol.map#2 (text) ====

@@ -13,12 +13,16 @@
 	acl_delete_link_np;
 	acl_delete_fd_np;
 	acl_delete_entry;
+	acl_delete_entry_at_position_np;
 	acl_create_entry;
+	acl_create_entry_at_position_np;
 	acl_get_entry;
 	acl_free;
 	acl_from_text;
 	acl_get_file;
 	acl_get_link_np;
+	acl_get_extended_np;
+	acl_get_flags_np;
 	acl_get_fd;
 	acl_get_fd_np;
 	acl_get_perm_np;
@@ -30,6 +34,8 @@
 	acl_add_perm;
 	acl_clear_perms;
 	acl_delete_perm;
+	acl_set_extended_np;
+	acl_set_flags_np;
 	acl_set_file;
 	acl_set_link_np;
 	acl_set_fd;
@@ -42,6 +48,8 @@
 	acl_valid_file_np;
 	acl_valid_link_np;
 	acl_valid_fd_np;
+	acl_is_trivial_np;
+	acl_strip_np;
 	extattr_namespace_to_string;
 	extattr_string_to_namespace;
 	mac_reload;

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_calc_mask.c#2 (text+ko) ====

@@ -35,6 +35,8 @@
 #include <errno.h>
 #include <stdio.h>
 
+#include "acl_support.h"
+
 /*
  * acl_calc_mask() (23.4.2): calculate and set the permissions
  * associated with the ACL_MASK ACL entry.  If the ACL already
@@ -48,6 +50,11 @@
 	acl_t		acl_new;
 	int		i, mask_mode, mask_num;
 
+	if (!_acl_must_be_posix(*acl_p)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
 	/*
 	 * (23.4.2.4) requires acl_p to point to a pointer to a valid ACL.
 	 * Since one of the primary reasons to use this function would be

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_copy.c#2 (text+ko) ====

@@ -35,6 +35,8 @@
 #include <errno.h>
 #include <string.h>
 
+#include "acl_support.h"
+
 /*
  * acl_copy_entry() (23.4.4): copy the contents of ACL entry src_d to
  * ACL entry dest_d
@@ -48,9 +50,25 @@
 		return (-1);
 	}
 
-	dest_d->ae_tag  = src_d->ae_tag;
-	dest_d->ae_id   = src_d->ae_id;
+	if (_entry_is_posix(src_d)) {
+		if (!_entry_must_be_posix(dest_d)) {
+			errno = EINVAL;
+			return (-1);
+		}
+	}
+
+	if (_entry_is_nfs4(src_d)) {
+		if (!_entry_must_be_nfs4(dest_d)) {
+			errno = EINVAL;
+			return (-1);
+		}
+	}
+
+	dest_d->ae_tag = src_d->ae_tag;
+	dest_d->ae_id = src_d->ae_id;
 	dest_d->ae_perm = src_d->ae_perm;
+	dest_d->ae_extended = src_d->ae_extended;
+	dest_d->ae_flags = src_d->ae_flags;
 
 	return (0);
 }

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_delete.c#2 (text+ko) ====

@@ -38,6 +38,8 @@
 #include "un-namespace.h"
 #include <sys/errno.h>
 
+#include "acl_support.h"
+
 int
 acl_delete_def_file(const char *path_p)
 {
@@ -56,6 +58,8 @@
 acl_delete_file_np(const char *path_p, acl_type_t type)
 {
 
+	type = _acl_type_unold(type);
+
 	return (__acl_delete_file(path_p, type));
 }
 
@@ -63,6 +67,8 @@
 acl_delete_link_np(const char *path_p, acl_type_t type)
 {
 
+	type = _acl_type_unold(type);
+
 	return (__acl_delete_link(path_p, type));
 }
 
@@ -71,5 +77,7 @@
 acl_delete_fd_np(int filedes, acl_type_t type)
 {
 
+	type = _acl_type_unold(type);
+
 	return (___acl_delete_fd(filedes, type));
 }

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_delete_entry.c#2 (text+ko) ====

@@ -33,6 +33,40 @@
 #include "un-namespace.h"
 #include <errno.h>
 #include <string.h>
+#include <stdio.h>
+
+#include "acl_support.h"
+
+static int
+_entry_matches(const acl_entry_t a, const acl_entry_t b)
+{
+	/*
+	 * There is a semantical difference here between NFSv4 and POSIX
+	 * draft ACLs.  In POSIX, there may be only one entry for the particular
+	 * user or group.  In NFSv4 ACL, there may be any number of them.  We're
+	 * trying to be more specific here in that case.
+	 *
+	 * XXX: The proper way would be to remove them by entry number.
+	 */
+	if (_entry_is_nfs4(a)) {
+		if (a->ae_tag != b->ae_tag || a->ae_extended != b->ae_extended)
+			return (0);
+
+		/* If ae_ids matter, compare them as well. */
+		if (a->ae_tag == ACL_USER || a->ae_tag == ACL_GROUP) {
+			if (a->ae_id != b->ae_id)
+				return (0);
+		}
+
+		return (1);
+
+	} else {
+		if ((a->ae_tag == b->ae_tag) && (a->ae_id == b->ae_id))
+			return (1);
+	} 
+
+	return (0);
+}
 
 /*
  * acl_delete_entry() (23.4.9): remove the ACL entry indicated by entry_d
@@ -42,7 +76,7 @@
 acl_delete_entry(acl_t acl, acl_entry_t entry_d)
 {
 	struct acl *acl_int;
-	int i;
+	int i, found = 0;
 
 	if (acl == NULL || entry_d == NULL) {
 		errno = EINVAL;
@@ -51,15 +85,18 @@
 
 	acl_int = &acl->ats_acl;
 
+	if (_entry_is_nfs4(entry_d) != _acl_is_nfs4(acl)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
 	if ((acl->ats_acl.acl_cnt < 1) ||
 	    (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) {
 		errno = EINVAL;
 		return (-1);
 	}
 	for (i = 0; i < acl->ats_acl.acl_cnt; i++) {
-		/* if this is our entry... */
-		if ((acl->ats_acl.acl_entry[i].ae_tag == entry_d->ae_tag) &&
-		    (acl->ats_acl.acl_entry[i].ae_id == entry_d->ae_id)) {
+		if (_entry_matches(&(acl->ats_acl.acl_entry[i]), entry_d)) {
 			/* ...shift the remaining entries... */
 			for (; i < acl->ats_acl.acl_cnt - 1; ++i)
 				acl->ats_acl.acl_entry[i] =
@@ -68,12 +105,57 @@
 			acl->ats_acl.acl_cnt--;
 			bzero(&acl->ats_acl.acl_entry[i],
 			    sizeof(struct acl_entry));
+			/* XXX: We need this because of the bzero above. */
+			_acl_fixup_entry_pointers(acl);
 			acl->ats_cur_entry = 0;
-			return (0);
+			
+			/* Continue with the loop to remove all maching entries. */
+			found = 1;
 		}
 	}
 
+	if (found)
+		return (0);
 
 	errno = EINVAL;
 	return (-1);
 }
+
+int
+acl_delete_entry_at_position_np(acl_t acl, int offset)
+{
+	struct acl *acl_int;
+	int i;
+
+	if (acl == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	acl_int = &acl->ats_acl;
+
+	if (offset < 0 || offset >= acl_int->acl_cnt) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if ((acl->ats_acl.acl_cnt < 1) ||
+	    (acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	/* ...shift the remaining entries... */
+	for (i = offset; i < acl->ats_acl.acl_cnt - 1; ++i)
+		acl->ats_acl.acl_entry[i] =
+		    acl->ats_acl.acl_entry[i+1];
+	/* ...drop the count and zero the unused entry... */
+	acl->ats_acl.acl_cnt--;
+	bzero(&acl->ats_acl.acl_entry[i],
+	    sizeof(struct acl_entry));
+	/* XXX: We need this because of the bzero above. */
+	_acl_fixup_entry_pointers(acl);
+	acl->ats_cur_entry = 0;
+
+	return (0);
+}

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_entry.c#2 (text+ko) ====

@@ -51,7 +51,8 @@
 
 	acl_int = &(*acl_p)->ats_acl;
 
-	if ((acl_int->acl_cnt >= ACL_MAX_ENTRIES) || (acl_int->acl_cnt < 0)) {
+	/* XXX: There was a bug here. */
+	if ((acl_int->acl_cnt + 1 >= ACL_MAX_ENTRIES) || (acl_int->acl_cnt < 0)) {
 		errno = EINVAL;
 		return (-1);
 	}
@@ -61,6 +62,50 @@
 	(**entry_p).ae_tag  = ACL_UNDEFINED_TAG;
 	(**entry_p).ae_id   = ACL_UNDEFINED_ID;
 	(**entry_p).ae_perm = ACL_PERM_NONE;
+	(**entry_p).ae_acl  = acl_int;
+	(**entry_p).ae_flags= 0;
+
+	(*acl_p)->ats_cur_entry = 0;
+
+	return (0);
+}
+
+int
+acl_create_entry_at_position_np(acl_t *acl_p, acl_entry_t *entry_p, int offset)
+{
+	int i;
+	struct acl *acl_int;
+
+	if (acl_p == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	acl_int = &(*acl_p)->ats_acl;
+
+	if ((acl_int->acl_cnt + 1 >= ACL_MAX_ENTRIES) || (acl_int->acl_cnt < 0)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (offset < 0 || offset >= acl_int->acl_cnt) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	/* Make room for the new entry. */
+	for (i = acl_int->acl_cnt; i > offset; i--)
+		acl_int->acl_entry[i] = acl_int->acl_entry[i - 1];
+
+	acl_int->acl_cnt++;
+
+	*entry_p = &acl_int->acl_entry[offset];
+
+	(**entry_p).ae_tag  = ACL_UNDEFINED_TAG;
+	(**entry_p).ae_id   = ACL_UNDEFINED_ID;
+	(**entry_p).ae_perm = ACL_PERM_NONE;
+	(**entry_p).ae_acl  = acl_int;
+	(**entry_p).ae_flags= 0;
 
 	(*acl_p)->ats_cur_entry = 0;
 
@@ -90,6 +135,7 @@
 		if (acl->ats_cur_entry >= acl->ats_acl.acl_cnt)
 			return 0;
 		*entry_p = &acl_int->acl_entry[acl->ats_cur_entry++];
+		(*entry_p)->ae_acl = acl_int;
 		return (1);
 	}
 

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_from_text.c#3 (text+ko) ====

@@ -40,46 +40,16 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 #include "acl_support.h"
 
 static int _posix1e_acl_name_to_id(acl_tag_t tag, char *name, uid_t *id);
 static acl_tag_t acl_string_to_tag(char *tag, char *qualifier);
-static char *string_skip_whitespace(char *string);
-static void string_trim_trailing_whitespace(char *string);
 
-static char *
-string_skip_whitespace(char *string)
-{
-
-	while (*string && ((*string == ' ') || (*string == '\t'))) {
-		string++;
-	}
-	return (string);
-}
-
-static void
-string_trim_trailing_whitespace(char *string)
-{
-	char	*end;
+int _nfs4_acl_entry_from_text(acl_t aclp, char *entry);
+int _text_could_be_nfs4_acl(const char *entry);
 
-	if (*string == '\0')
-		return;
-
-	end = string + strlen(string) - 1;
-
-	while (end != string) {
-		if ((*end == ' ') || (*end == '\t')) {
-			*end = '\0';
-			end--;
-		} else {
-			return;
-		}
-	}
-
-	return;
-}
-
 static acl_tag_t
 acl_string_to_tag(char *tag, char *qualifier)
 {
@@ -118,6 +88,8 @@
 	uid_t		 id;
 	int		 error;
 
+	assert(_acl_is_posix(aclp));
+
 	/* Split into three ':' delimited fields. */
 	tag = strsep(&entry, ":");
 	if (tag == NULL) {
@@ -194,6 +166,25 @@
 	return (0);
 }
 
+static int
+_text_is_nfs4_entry(const char *entry)
+{
+	int count = 0;
+
+	assert(strlen(entry) > 0);
+
+	while (*entry != '\0') {
+		if (*entry == ':' || *entry == '@')
+			count++;
+		entry++;
+	}
+
+	if (count <= 2)
+		return (0);
+
+	return (1);
+}
+
 /*
  * acl_from_text -- Convert a string into an ACL.
  * Postpone most validity checking until the end and call acl_valid() to do
@@ -211,7 +202,7 @@
 	if (mybuf_p == NULL)
 		return(NULL);
 
-	acl = acl_init(3);
+	acl = acl_init(3); /* XXX: WTF, 3? */
 	if (acl == NULL) {
 		free(mybuf_p);
 		return(NULL);
@@ -226,7 +217,21 @@
 
 		/* Inner loop: delimit at ',' boundaries. */
 		while ((entry = strsep(&notcomment, ","))) {
-			error = _posix1e_acl_entry_from_text(acl, entry);
+
+			/* Skip empty lines. */
+			if (strlen(string_skip_whitespace(entry)) == 0)
+				continue;
+
+			if (_acl_is_unknown(acl) && _text_is_nfs4_entry(entry))
+				_acl_must_be_nfs4(acl);
+			else
+				_acl_must_be_posix(acl);
+
+			if (_acl_is_nfs4(acl))
+				error = _nfs4_acl_entry_from_text(acl, entry);
+			else
+				error = _posix1e_acl_entry_from_text(acl, entry);
+
 			if (error)
 				goto error_label;
 		}

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_get.c#3 (text+ko) ====

@@ -49,6 +49,9 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+
+#include "acl_support.h"
 
 acl_t
 acl_get_file(const char *path_p, acl_type_t type)
@@ -60,12 +63,17 @@
 	if (aclp == NULL)
 		return (NULL);
 
+	type = _acl_type_unold(type);
+
 	error = __acl_get_file(path_p, type, &aclp->ats_acl);
 	if (error) {
 		acl_free(aclp);
 		return (NULL);
 	}
 
+	_acl_fixup_entry_pointers(aclp);
+	_acl_brand_from_type(aclp, type);
+
 	return (aclp);
 }
 
@@ -79,18 +87,26 @@
 	if (aclp == NULL)
 		return (NULL);
 
+	type = _acl_type_unold(type);
+
 	error = __acl_get_link(path_p, type, &aclp->ats_acl);
 	if (error) {
 		acl_free(aclp);
 		return (NULL);
 	}
 
+	_acl_fixup_entry_pointers(aclp);
+	_acl_brand_from_type(aclp, type);
+
 	return (aclp);
 }
 
 acl_t
 acl_get_fd(int fd)
 {
+	if (fpathconf(fd, _PC_EXTENDED_SECURITY_NP))
+		return (acl_get_fd_np(fd, ACL_TYPE_NFS4));
+
 	return (acl_get_fd_np(fd, ACL_TYPE_ACCESS));
 }
 
@@ -104,15 +120,23 @@
 	if (aclp == NULL)
 		return (NULL);
 
+	type = _acl_type_unold(type);
+
 	error = ___acl_get_fd(fd, type, &aclp->ats_acl);
 	if (error) {
 		acl_free(aclp);
 		return (NULL);
 	}
 
+	_acl_fixup_entry_pointers(aclp);
+	_acl_brand_from_type(aclp, type);
+
 	return (aclp);
 }
 
+/*
+ * XXX: Possible binary compatibility problem; acl_perm_t definition changed.
+ */
 int
 acl_get_perm_np(acl_permset_t permset_d, acl_perm_t perm)
 {
@@ -200,3 +224,40 @@
 
 	return (0);
 }
+
+int
+acl_get_extended_np(acl_entry_t entry_d, acl_extended_t *extended_p)
+{
+	if (entry_d == NULL || extended_p == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (!_entry_is_nfs4(entry_d)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	*extended_p = entry_d->ae_extended;
+
+	return (0);
+}
+
+int
+acl_get_flags_np(acl_entry_t entry_d, acl_flag_t *flags_p)
+{
+	if (entry_d == NULL || flags_p == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (!_entry_is_nfs4(entry_d)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	*flags_p = entry_d->ae_flags;
+
+	return (0);
+}
+

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_init.c#2 (text+ko) ====

@@ -39,6 +39,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "acl_support.h"
+
 acl_t
 acl_init(int count)
 {
@@ -57,6 +59,11 @@
 	if (acl != NULL)
 		bzero(acl, sizeof(struct acl_t_struct));
 
+	acl->ats_acl.acl_brand = ACL_BRAND_UNKNOWN;
+	acl->ats_acl.acl_magic = ACL_MAGIC;
+
+	_acl_fixup_entry_pointers(acl);
+
 	return (acl);
 }
 
@@ -72,5 +79,7 @@
 		acl_new->ats_cur_entry = 0;
 	}
 
+	_acl_fixup_entry_pointers(acl_new);
+
 	return (acl_new);
 }

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_perm.c#2 (text+ko) ====

@@ -39,6 +39,9 @@
  * acl_add_perm() (23.4.1): add the permission contained in perm to the
  * permission set permset_d
  */
+/*
+ * XXX: Possible binary compatibility problem; acl_perm_t definition changed.
+ */
 int
 acl_add_perm(acl_permset_t permset_d, acl_perm_t perm)
 {
@@ -79,6 +82,9 @@
  * acl_delete_perm() (23.4.10): remove the permission in perm from the
  * permission set permset_d
  */
+/*
+ * XXX: Possible binary compatibility problem; acl_perm_t definition changed.
+ */
 int
 acl_delete_perm(acl_permset_t permset_d, acl_perm_t perm)
 {

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_set.c#3 (text+ko) ====

@@ -40,6 +40,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "acl_support.h"
 
@@ -58,6 +59,15 @@
 		errno = EINVAL;
 		return (-1);
 	}
+
+	/* This is for old binaries using new libc. */
+	type = _acl_type_unold(type);
+
+	if (_acl_type_not_valid_for_acl(acl, type)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
 	if (_posix1e_acl(acl, type)) {
 		error = _posix1e_acl_sort(acl);
 		if (error) {
@@ -80,6 +90,14 @@
 		errno = EINVAL;
 		return (-1);
 	}
+
+	type = _acl_type_unold(type);
+
+	if (_acl_type_not_valid_for_acl(acl, type)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
 	if (_posix1e_acl(acl, type)) {
 		error = _posix1e_acl_sort(acl);
 		if (error) {
@@ -96,6 +114,9 @@
 int
 acl_set_fd(int fd, acl_t acl)
 {
+	if (fpathconf(fd, _PC_EXTENDED_SECURITY_NP))
+		return (acl_set_fd_np(fd, acl, ACL_TYPE_NFS4));
+
 	return (acl_set_fd_np(fd, acl, ACL_TYPE_ACCESS));
 }
 
@@ -104,6 +125,18 @@
 {
 	int	error;
 
+	if (acl == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	type = _acl_type_unold(type);
+
+	if (_acl_type_not_valid_for_acl(acl, type)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
 	if (_posix1e_acl(acl, type)) {
 		error = _posix1e_acl_sort(acl);
 		if (error) {
@@ -130,6 +163,19 @@
 		return (-1);
 	}
 
+	if ((*permset_d & ACL_POSIX1E_BITS) != *permset_d) {
+
+		if ((*permset_d & ACL_NFS4_PERM_BITS) != *permset_d) {
+			errno = EINVAL;
+			return (-1);
+		}
+
+		if (!_entry_must_be_nfs4(entry_d)) {
+			errno = EINVAL;
+			return (-1);
+		}
+	}
+
 	entry_d->ae_perm = *permset_d;
 
 	return (0);
@@ -173,6 +219,15 @@
 		return (-1);
 	}
 
+	if ((tag_type == ACL_OTHER || tag_type == ACL_MASK) &&
+	    !_entry_must_be_posix(entry_d)) {
+		errno = EINVAL;
+		return (-1);
+	} else if (tag_type == ACL_EVERYONE && !_entry_must_be_nfs4(entry_d)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
 	switch(tag_type) {
 	case ACL_USER_OBJ:
 	case ACL_USER:
@@ -180,6 +235,7 @@
 	case ACL_GROUP:
 	case ACL_MASK:
 	case ACL_OTHER:
+	case ACL_EVERYONE:
 		entry_d->ae_tag = tag_type;
 		return (0);
 	}
@@ -187,3 +243,53 @@
 	errno = EINVAL;
 	return (-1);
 }
+
+int
+acl_set_extended_np(acl_entry_t entry_d, acl_extended_t extended)
+{
+	if (entry_d == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (!_entry_must_be_nfs4(entry_d)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	switch (extended) {
+	case ACL_EXTENDED_ALLOW:
+	case ACL_EXTENDED_DENY:
+	case ACL_EXTENDED_AUDIT:
+	case ACL_EXTENDED_ALARM:
+
+		entry_d->ae_extended = extended;
+		return (0);
+	}
+
+	errno = EINVAL;
+	return (-1);
+}
+
+int
+acl_set_flags_np(acl_entry_t entry_d, acl_flag_t flags)
+{
+	if (entry_d == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if ((flags & ACL_FLAGS_BITS) != flags) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	if (!_entry_must_be_nfs4(entry_d)) {
+		errno = EINVAL;
+		return (-1);
+	}
+
+	entry_d->ae_flags = flags;
+	return (0);
+}
+

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_support.c#2 (text+ko) ====

@@ -40,6 +40,8 @@
 #include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <assert.h>
 
 #include "acl_support.h"
 
@@ -49,6 +51,51 @@
 #define ACL_STRING_PERM_NONE    '-'
 
 /*
+ * Convert "old" type - ACL_TYPE_{ACCESS,DEFAULT}_OLD - into its "new"
+ * counterpart.  It's neccessary for the old (pre-NFS4 ACLs) binaries
+ * to work with new libc and kernel.  Fixing "type" for old binaries with
+ * old libc and new kernel is being done by kern/vfs_acl.c:type_unold().
+ */
+int
+_acl_type_unold(acl_type_t type)
+{
+	if (type == ACL_TYPE_ACCESS_OLD)
+		return (ACL_TYPE_ACCESS);
+
+	if (type == ACL_TYPE_DEFAULT_OLD)
+		return (ACL_TYPE_DEFAULT);
+
+	return (type);
+}
+
+/*
+ * Return 0, if both ACLs are identical.
+ */
+int
+_acl_differs(const acl_t a, const acl_t b)
+{
+	int i;
+	struct acl_entry *entrya, *entryb;
+
+	if (a->ats_acl.acl_cnt != b->ats_acl.acl_cnt)
+		return (1);
+
+	for (i = 0; i < b->ats_acl.acl_cnt; i++) {
+		entrya = &(a->ats_acl.acl_entry[i]);
+		entryb = &(b->ats_acl.acl_entry[i]);
+
+		if (entrya->ae_tag != entryb->ae_tag ||
+		    entrya->ae_id != entryb->ae_id ||
+		    entrya->ae_perm != entryb->ae_perm ||
+		    entrya->ae_extended != entryb->ae_extended ||
+		    entrya->ae_flags != entryb->ae_flags)
+			return (1);
+	}
+
+	return (0);
+}
+		    
+/*
  * _posix1e_acl_entry_compare -- compare two acl_entry structures to
  * determine the order they should appear in.  Used by _posix1e_acl_sort to
  * sort ACL entries into the kernel-desired order -- i.e., the order useful
@@ -59,6 +106,9 @@
 static int
 _posix1e_acl_entry_compare(struct acl_entry *a, struct acl_entry *b)
 {
+	assert(_entry_is_posix(a));
+	assert(_entry_is_posix(b));
+
 	/*
 	 * First, sort between tags -- conveniently defined in the correct
 	 * order for verification.
@@ -101,6 +151,9 @@
 
 	acl_int = &acl->ats_acl;
 
+	/* XXX: */
+	assert(_entry_is_posix(&(acl->ats_acl.acl_entry[3])));
+
 	qsort(&acl_int->acl_entry[0], acl_int->acl_cnt,
 	    sizeof(struct acl_entry), (compare) _posix1e_acl_entry_compare);
 
@@ -115,6 +168,8 @@
 int
 _posix1e_acl(acl_t acl, acl_type_t type)
 {
+	if (!_acl_is_posix(acl))
+		return (0);
 
 	return ((type == ACL_TYPE_ACCESS) || (type == ACL_TYPE_DEFAULT));
 }
@@ -382,3 +437,37 @@
 
 	return (0);
 }
+
+char *
+string_skip_whitespace(char *string)
+{
+
+	while (*string && ((*string == ' ') || (*string == '\t'))) {
+		string++;
+	}
+	return (string);
+}
+
+void
+string_trim_trailing_whitespace(char *string)
+{
+	char	*end;
+
+	if (*string == '\0')
+		return;
+
+	end = string + strlen(string) - 1;
+
+	while (end != string) {
+		if ((*end == ' ') || (*end == '\t')) {
+			*end = '\0';
+			end--;
+		} else {
+			return;
+		}
+	}
+
+	return;
+}
+
+

==== //depot/projects/soc2008/trasz_nfs4acl/lib/libc/posix1e/acl_support.h#2 (text+ko) ====

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807021103.m62B3d0O013866>