PERFORCE change 144481 for review

Edward Tomasz Napierala trasz at FreeBSD.org
Wed Jul 2 11:16:54 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=144481

Change 144481 by trasz at trasz_traszkan on 2008/07/02 11:16:14

	Add support for the new ACLs to setfacl(1).

Affected files ...

.. //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/merge.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/remove.c#2 edit
.. //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/setfacl.c#3 edit

Differences ...

==== //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/merge.c#2 (text+ko) ====

@@ -42,6 +42,8 @@
 merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new)
 {
 	acl_permset_t permset;
+	acl_extended_t extended;
+	acl_flag_t flags;
 	int have_entry;
 	uid_t *id, *id_new;
 
@@ -59,6 +61,18 @@
 			err(1, "acl_get_permset() failed");
 		if (acl_set_permset(*entry_new, permset) == -1)
 			err(1, "acl_set_permset() failed");
+
+		if (acl_type == ACL_TYPE_NFS4) {
+			if (acl_get_extended_np(*entry, &extended))
+				err(1, "acl_get_extended_np() failed");
+			if (acl_set_extended_np(*entry_new, extended))
+				err(1, "acl_set_extended_np() failed");
+			if (acl_get_flags_np(*entry, &flags))
+				err(1, "acl_get_flags_np() failed");
+			if (acl_set_flags_np(*entry_new, flags))
+				err(1, "acl_set_flags_np() failed");
+		}
+
 		have_entry = 1;
 	}
 	acl_free(id);
@@ -77,9 +91,11 @@
 	acl_permset_t permset;
 	acl_t acl_new;
 	acl_tag_t tag, tag_new;
+	acl_extended_t extended, extended_new;
+	acl_flag_t flags;
 	int entry_id, entry_id_new, have_entry;
 
-	if (acl_type == ACL_TYPE_ACCESS)
+	if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4)
 		acl_new = acl_dup(prev_acl[ACCESS_ACL]);
 	else
 		acl_new = acl_dup(prev_acl[DEFAULT_ACL]);
@@ -111,6 +127,19 @@
 			if (tag != tag_new)
 				continue;
 
+			/*
+			 * For NFS4, in addition to "tag" and "id" we also
+			 * compare "extended".
+			 */
+			if (acl_type == ACL_TYPE_NFS4) {
+				if (acl_get_extended_np(entry, &extended))
+					err(1, "acl_get_extended_np() failed");
+				if (acl_get_extended_np(entry_new, &extended_new))
+					err(1, "acl_get_extended_np() failed");
+				if (extended != extended_new)
+					continue;
+			}
+		
 			switch(tag) {
 			case ACL_USER:
 			case ACL_GROUP:
@@ -123,10 +152,22 @@
 			case ACL_GROUP_OBJ:
 			case ACL_OTHER:
 			case ACL_MASK:
+			case ACL_EVERYONE:
 				if (acl_get_permset(entry, &permset) == -1)
 					err(1, "acl_get_permset() failed");
 				if (acl_set_permset(entry_new, permset) == -1)
 					err(1, "acl_set_permset() failed");
+
+				if (acl_type == ACL_TYPE_NFS4) {
+					if (acl_get_extended_np(entry, &extended))
+						err(1, "acl_get_extended_np() failed");
+					if (acl_set_extended_np(entry_new, extended))
+						err(1, "acl_set_extended_np() failed");
+					if (acl_get_flags_np(entry, &flags))
+						err(1, "acl_get_flags_np() failed");
+					if (acl_set_flags_np(entry_new, flags))
+						err(1, "acl_set_flags_np() failed");
+				}
 				have_entry = 1;
 				break;
 			default:
@@ -138,16 +179,29 @@
 
 		/* if this entry has not been found, it must be new */
 		if (have_entry == 0) {
-			if (acl_create_entry(&acl_new, &entry_new) == -1) {
-				acl_free(acl_new);
-				return (-1);
+
+			/*
+			 * NFS4 ACL entries must be prepended to the ACL.
+			 * Appending them at the end makes no sense, since
+			 * in most cases they wouldn't even get evaluated.
+			 */
+			if (acl_type == ACL_TYPE_NFS4) {
+				if (acl_create_entry_at_position_np(&acl_new, &entry_new, 0) == -1) {
+					acl_free(acl_new);
+					return (-1);
+				}
+			} else {
+				if (acl_create_entry(&acl_new, &entry_new) == -1) {
+					acl_free(acl_new);
+					return (-1);
+				}
 			}
 			if (acl_copy_entry(entry_new, entry) == -1)
 				err(1, "acl_copy_entry() failed");
 		}
 	}
 
-	if (acl_type == ACL_TYPE_ACCESS) {
+	if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4) {
 		acl_free(prev_acl[ACCESS_ACL]);
 		prev_acl[ACCESS_ACL] = acl_new;
 	} else {

==== //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/remove.c#2 (text+ko) ====

@@ -50,7 +50,7 @@
 
 	carried_error = 0;
 
-	if (acl_type == ACL_TYPE_ACCESS)
+	if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4)
 		acl_new = acl_dup(prev_acl[ACCESS_ACL]);
 	else
 		acl_new = acl_dup(prev_acl[DEFAULT_ACL]);
@@ -73,7 +73,7 @@
 		}
 	}
 
-	if (acl_type == ACL_TYPE_ACCESS) {
+	if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4) {
 		acl_free(prev_acl[ACCESS_ACL]);
 		prev_acl[ACCESS_ACL] = acl_new;
 	} else {
@@ -113,64 +113,17 @@
 remove_ext(acl_t *prev_acl)
 {
 	acl_t acl_new, acl_old;
-	acl_entry_t entry, entry_new;
-	acl_permset_t perm;
-	acl_tag_t tag;
-	int entry_id, have_mask_entry;
 
-	if (acl_type == ACL_TYPE_ACCESS)
-		acl_old = acl_dup(prev_acl[ACCESS_ACL]);
+	if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4)
+		acl_old = prev_acl[ACCESS_ACL];
 	else
-		acl_old = acl_dup(prev_acl[DEFAULT_ACL]);
-	if (acl_old == NULL)
-		err(1, "acl_dup() failed");
+		acl_old = prev_acl[DEFAULT_ACL];
 
-	have_mask_entry = 0;
-	acl_new = acl_init(ACL_MAX_ENTRIES);
+	acl_new = acl_strip_np(acl_old, !n_flag);
 	if (acl_new == NULL)
-		err(1, "acl_init() failed");
-	tag = ACL_UNDEFINED_TAG;
+		err(1, "acl_strip_np() failed");
 
-	/* only save the default user/group/other entries */
-	entry_id = ACL_FIRST_ENTRY;
-	while (acl_get_entry(acl_old, entry_id, &entry) == 1) {
-		entry_id = ACL_NEXT_ENTRY;
-
-		if (acl_get_tag_type(entry, &tag) == -1)
-			err(1, "acl_get_tag_type() failed");
-
-		switch(tag) {
-		case ACL_USER_OBJ:
-		case ACL_GROUP_OBJ:
-		case ACL_OTHER:
-			if (acl_get_tag_type(entry, &tag) == -1)
-				err(1, "acl_get_tag_type() failed");
-			if (acl_get_permset(entry, &perm) == -1)
-				err(1, "acl_get_permset() failed");
-			if (acl_create_entry(&acl_new, &entry_new) == -1)
-				err(1, "acl_create_entry() failed");
-			if (acl_set_tag_type(entry_new, tag) == -1)
-				err(1, "acl_set_tag_type() failed");
-			if (acl_set_permset(entry_new, perm) == -1)
-				err(1, "acl_get_permset() failed");
-			if (acl_copy_entry(entry_new, entry) == -1)
-				err(1, "acl_copy_entry() failed");
-			break;
-		case ACL_MASK:
-			have_mask_entry = 1;
-			break;
-		default:
-			break;
-		}
-	}
-	if (have_mask_entry && n_flag == 0) {
-		if (acl_calc_mask(&acl_new) == -1)
-			err(1, "acl_calc_mask() failed");
-	} else {
-		have_mask = 1;
-	}
-
-	if (acl_type == ACL_TYPE_ACCESS) {
+	if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4) {
 		acl_free(prev_acl[ACCESS_ACL]);
 		prev_acl[ACCESS_ACL] = acl_new;
 	} else {

==== //depot/projects/soc2008/trasz_nfs4acl/bin/setfacl/setfacl.c#3 (text+ko) ====

@@ -64,20 +64,26 @@
 {
 	acl_t *acl;
 	struct stat sb;
+	int type;
 
 	if (stat(filename, &sb) == -1) {
 		warn("stat() of %s failed", filename);
 		return (NULL);
 	}
 
+	if (pathconf(filename, _PC_EXTENDED_SECURITY_NP))
+		type = ACL_TYPE_NFS4;
+	else
+		type = ACL_TYPE_ACCESS;
+
 	acl = zmalloc(sizeof(acl_t) * 2);
 	if (h_flag)
-		acl[ACCESS_ACL] = acl_get_link_np(filename, ACL_TYPE_ACCESS);
+		acl[ACCESS_ACL] = acl_get_link_np(filename, type);
 	else
-		acl[ACCESS_ACL] = acl_get_file(filename, ACL_TYPE_ACCESS);
+		acl[ACCESS_ACL] = acl_get_file(filename, type);
 	if (acl[ACCESS_ACL] == NULL)
 		err(1, "acl_get_file() failed");
-	if (S_ISDIR(sb.st_mode)) {
+	if (S_ISDIR(sb.st_mode) && type != ACL_TYPE_NFS4) {
 		if (h_flag)
 			acl[DEFAULT_ACL] = acl_get_link_np(filename,
 			    ACL_TYPE_DEFAULT);
@@ -210,6 +216,11 @@
 
 		local_error = 0;
 
+		if (acl_type != ACL_TYPE_DEFAULT && pathconf(file->filename, _PC_EXTENDED_SECURITY_NP))
+			acl_type = ACL_TYPE_NFS4;
+		else
+			acl_type = ACL_TYPE_ACCESS;
+
 		/* cycle through each option */
 		TAILQ_FOREACH(entry, &entrylist, next) {
 			if (local_error)
@@ -245,11 +256,14 @@
 			continue;
 		}
 
-		if (acl_type == ACL_TYPE_ACCESS)
+		if (acl_type == ACL_TYPE_ACCESS || acl_type == ACL_TYPE_NFS4)
 			final_acl = acl[ACCESS_ACL];
 		else
 			final_acl = acl[DEFAULT_ACL];
 
+		if (acl_type == ACL_TYPE_NFS4)
+			need_mask = 0;
+
 		if (need_mask && (set_acl_mask(&final_acl) == -1)) {
 			warnx("failed to set ACL mask on %s", file->filename);
 			carried_error++;


More information about the p4-projects mailing list