Support extracting NFSv4 ACLs from Solaris tar archives
Fix read of default ACLs from Solaris tar archives
Update Solaris tar ACL test to test all ACL types
diff --git a/libarchive/archive_acl.c b/libarchive/archive_acl.c
index 7c68209..a1edc6d 100644
--- a/libarchive/archive_acl.c
+++ b/libarchive/archive_acl.c
@@ -1144,7 +1144,7 @@
 
 	const wchar_t *s, *st;
 
-	int numfields, fields, n, r, ret;
+	int numfields, fields, n, r, sol, ret;
 	int type, types, tag, permset, id;
 	size_t len;
 	wchar_t sep;
@@ -1192,6 +1192,7 @@
 		}
 
 		n = 0;
+		sol = 0;
 		id = -1;
 		permset = 0;
 		name.start = name.end = NULL;
@@ -1263,6 +1264,7 @@
 				    && ismode_w(field[n + 1].start,
 				    field[n + 1].end, &permset)) {
 					/* This is Solaris-style "other:rwx" */
+					sol = 1;
 				} else if (fields == (n + 3) &&
 				    field[n + 1].start < field[n + 1].end) {
 					/* Invalid mask or other field */
@@ -1287,9 +1289,12 @@
 				continue;
 			}
 
-			/* Without "default:" we expect mode in field 2 */
-			if (permset == 0 && !ismode_w(field[n + 2].start,
-			    field[n + 2].end, &permset)) {
+			/*
+			 * Without "default:" we expect mode in field 2
+			 * Exception: Solaris other and mask fields
+			 */
+			if (permset == 0 && !ismode_w(field[n + 2 - sol].start,
+			    field[n + 2 - sol].end, &permset)) {
 				/* Invalid mode, skip entry */
 				ret = ARCHIVE_WARN;
 				continue;
@@ -1615,7 +1620,7 @@
 	} field[6], name;
 
 	const char *s, *st;
-	int numfields, fields, n, r, ret;
+	int numfields, fields, n, r, sol, ret;
 	int type, types, tag, permset, id;
 	size_t len;
 	char sep;
@@ -1663,6 +1668,7 @@
 		}
 
 		n = 0;
+		sol = 0;
 		id = -1;
 		permset = 0;
 		name.start = name.end = NULL;
@@ -1734,6 +1740,7 @@
 				    && ismode(field[n + 1].start,
 				    field[n + 1].end, &permset)) {
 					/* This is Solaris-style "other:rwx" */
+					sol = 1;
 				} else if (fields == (n + 3) &&
 				    field[n + 1].start < field[n + 1].end) {
 					/* Invalid mask or other field */
@@ -1758,9 +1765,12 @@
 				continue;
 			}
 
-			/* Without "default:" we expect mode in field 2 */
-			if (permset == 0 && !ismode(field[n + 2].start,
-			    field[n + 2].end, &permset)) {
+			/*
+			 * Without "default:" we expect mode in field 3
+			 * Exception: Solaris other and mask fields
+			 */
+			if (permset == 0 && !ismode(field[n + 2 - sol].start,
+			    field[n + 2 - sol].end, &permset)) {
 				/* Invalid mode, skip entry */
 				ret = ARCHIVE_WARN;
 				continue;
diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index 3373253..bc4ba3d 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -944,7 +944,7 @@
 {
 	const struct archive_entry_header_ustar *header;
 	size_t size;
-	int err;
+	int err, acl_type;
 	int64_t type;
 	char *acl, *p;
 
@@ -989,11 +989,12 @@
 	switch ((int)type & ~0777777) {
 	case 01000000:
 		/* POSIX.1e ACL */
+		acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
 		break;
 	case 03000000:
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Solaris NFSv4 ACLs not supported");
-		return (ARCHIVE_WARN);
+		/* NFSv4 ACL */
+		acl_type = ARCHIVE_ENTRY_ACL_TYPE_NFS4;
+		break;
 	default:
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 		    "Malformed Solaris ACL attribute (unsupported type %o)",
@@ -1023,7 +1024,7 @@
 	}
 	archive_strncpy(&(tar->localname), acl, p - acl);
 	err = archive_acl_from_text_l(archive_entry_acl(entry),
-	    tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, tar->sconv_acl);
+	    tar->localname.s, acl_type, tar->sconv_acl);
 	if (err != ARCHIVE_OK) {
 		if (errno == ENOMEM) {
 			archive_set_error(&a->archive, ENOMEM,
diff --git a/libarchive/test/test_compat_solaris_tar_acl.c b/libarchive/test/test_compat_solaris_tar_acl.c
index a0cf9a8..3d063c1 100644
--- a/libarchive/test/test_compat_solaris_tar_acl.c
+++ b/libarchive/test/test_compat_solaris_tar_acl.c
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2016 Martin Matuska
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,104 +24,242 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD: head/lib/libarchive/test/test_compat_solaris_tar_acl.c 201247 2009-12-30 05:59:21Z kientzle $");
+__FBSDID("$FreeBSD$");
 
 /*
- * Exercise support for reading Solaris-style ACL data
- * from tar archives.
+ * Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created
+ * with Solaris tar.
  *
- * This should work on all systems, regardless of whether local
- * filesystems support ACLs or not.
+ * This should work on all systems, regardless of whether local filesystems
+ * support ACLs or not.
  */
 
+static struct archive_test_acl_t acls0[] = {
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE |
+	    ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
+	  ARCHIVE_ENTRY_ACL_USER, 71, "lp" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER, 666, "666" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER, 1000, "1000" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
+};
+
+static struct archive_test_acl_t acls1[] = {
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
+	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
+	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
+};
+
+static struct archive_test_acl_t acls2[] = {
+	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
+	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
+	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0,
+	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
+};
+
+static struct archive_test_acl_t acls3[] = {
+	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
+	    ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
+	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
+	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_GROUP, 12, "daemon" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
+	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_GROUP, 2, "bin" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_USER, 4, "adm" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
+	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
+	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
+};
+
+static struct archive_test_acl_t acls4[] = {
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
+	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
+	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
+	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
+	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT |
+	    ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
+	  ARCHIVE_ENTRY_ACL_USER, 1100, "1100" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
+	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
+	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
+	  ARCHIVE_ENTRY_ACL_GROUP, 4, "adm" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
+	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
+	    ARCHIVE_ENTRY_ACL_DELETE_CHILD |
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
+	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_EXECUTE |
+	    ARCHIVE_ENTRY_ACL_READ_DATA |
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
+	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
+	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
+	    ARCHIVE_ENTRY_ACL_READ_ACL |
+	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
+};
+
 DEFINE_TEST(test_compat_solaris_tar_acl)
 {
+	char name[] = "test_compat_solaris_tar_acl.tar";
 	struct archive *a;
 	struct archive_entry *ae;
-	const char *reference1 = "test_compat_solaris_tar_acl.tar";
-	int type, permset, tag, qual;
-	const char *name;
 
-	/* Sample file generated on Solaris 10 */
-	extract_reference_file(reference1);
+	/* Read archive file */
 	assert(NULL != (a = archive_read_new()));
-	assertA(0 == archive_read_support_format_all(a));
-	assertA(0 == archive_read_support_filter_all(a));
-	assertA(0 == archive_read_open_filename(a, reference1, 512));
+        assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
+        assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+        extract_reference_file(name);
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name,
+	    10240));
 
-	/* Archive has 1 entry with some ACLs set on it. */
+	/* First item has access ACLs */
 	assertA(0 == archive_read_next_header(a, &ae));
+	failure("One extended ACL should flag all ACLs to be returned.");
+	assertEqualInt(7, archive_entry_acl_reset(ae,
+	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
+	archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
+	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0644);
 	failure("Basic ACLs should set mode to 0644, not %04o",
 	    archive_entry_mode(ae)&0777);
-	assertEqualInt((archive_entry_mode(ae) & 0777), 0644);
-	assertEqualInt(7, archive_entry_acl_reset(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
-	assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-		&type, &permset, &tag, &qual, &name));
-	assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
-	assertEqualInt(006, permset);
-	assertEqualInt(ARCHIVE_ENTRY_ACL_USER_OBJ, tag);
-	assertEqualInt(-1, qual);
-	assert(name == NULL);
+	assert((archive_entry_mode(ae) & 0777) == 0644);
 
-	assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-		&type, &permset, &tag, &qual, &name));
-	assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
-	assertEqualInt(004, permset);
-	assertEqualInt(ARCHIVE_ENTRY_ACL_GROUP_OBJ, tag);
-	assertEqualInt(-1, qual);
-	assert(name == NULL);
+	/* Second item has default and access ACLs */
+	assertA(0 == archive_read_next_header(a, &ae));
+	assertEqualInt(6, archive_entry_acl_reset(ae,
+	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
+	archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
+	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0750);
+	failure("Basic ACLs should set mode to 0750, not %04o",
+	    archive_entry_mode(ae)&0777);
+	assert((archive_entry_mode(ae) & 0777) == 0750);
+	assertEqualInt(6, archive_entry_acl_reset(ae,
+	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
+	archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
+	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0750);
 
-	assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-		&type, &permset, &tag, &qual, &name));
-	assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
-	assertEqualInt(004, permset);
-	assertEqualInt(ARCHIVE_ENTRY_ACL_OTHER, tag);
-	assertEqualInt(-1, qual);
-	assert(name == NULL);
+	/* Third item has NFS4 ACLs */
+	assertA(0 == archive_read_next_header(a, &ae));
+	assertEqualInt(6, archive_entry_acl_reset(ae,
+	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
+	archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
+	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
 
-	assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-		&type, &permset, &tag, &qual, &name));
-	assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
-	assertEqualInt(001, permset);
-	assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
-	assertEqualInt(71, qual);
-	assertEqualString(name, "lp");
-
-	assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-		&type, &permset, &tag, &qual, &name));
-	assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
-	assertEqualInt(004, permset);
-	assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
-	assertEqualInt(666, qual);
-	assertEqualString(name, "666");
-
-	assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-		&type, &permset, &tag, &qual, &name));
-	assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
-	assertEqualInt(007, permset);
-	assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
-	assertEqualInt(1000, qual);
-	assertEqualString(name, "trasz");
-
-	assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-		&type, &permset, &tag, &qual, &name));
-	assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
-	assertEqualInt(004, permset);
-	assertEqualInt(ARCHIVE_ENTRY_ACL_MASK, tag);
-	assertEqualInt(-1, qual);
-	assertEqualString(name, NULL);
-
-	assertEqualInt(ARCHIVE_EOF, archive_entry_acl_next(ae,
-		ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-		&type, &permset, &tag, &qual, &name));
+	/* Fourth item has NFS4 ACLs and inheritance flags */
+	assertA(0 == archive_read_next_header(a, &ae));
+	assertEqualInt(5, archive_entry_acl_reset(ae,
+	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
+	archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
+	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
 
 	/* Close the archive. */
 	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
diff --git a/libarchive/test/test_compat_solaris_tar_acl.tar.uu b/libarchive/test/test_compat_solaris_tar_acl.tar.uu
index 54aabc2..028dd61 100644
--- a/libarchive/test/test_compat_solaris_tar_acl.tar.uu
+++ b/libarchive/test/test_compat_solaris_tar_acl.tar.uu
@@ -1,61 +1,163 @@
-$FreeBSD: head/lib/libarchive/test/test_compat_solaris_tar_acl.tar.uu 191576 2009-04-27 18:27:54Z kientzle $
-begin 644 test_acl_solaris.tar
-M9FEL92UW:71H+7!O<VEX+6%C;',`````````````````````````````````
-M````````````````````````````````````````````````````````````
-M`````````````#`P,#`V-#0`,#`P,3<U,``P,#`P,#`P`#`P,#`P,#`P,30T
-M`#$Q,3<T-C`T,34W`#`P,34Q-S8`00``````````````````````````````
-M````````````````````````````````````````````````````````````
-M``````````````````````````````````````````!U<W1A<@`P,'1R87-Z
-M````````````````````````````````````<F]O=```````````````````
-M```````````````````P,#`P,C$P`#`P,#`P,3``````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M```````````````````````Q,#`P,#`W`'5S97(Z.G)W+2QU<V5R.FQP.BTM
-M>#HW,2QU<V5R.C8V-CIR+2TZ-C8V+'5S97(Z=')A<WHZ<G=X.C$P,#`L9W)O
-M=7`Z.G(M+2QM87-K.G(M+2QO=&AE<CIR+2T``````````3````````/-@```
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````!%&8`````````&L`````,3`P,#`P-P!U
+begin 644 test_compat_solaris_tar_acl.tar
+M9FEL92UW:71H+7!O<VEX+6%C;',                                 
+M                                                            
+M             # P,# V-#0 ,# P,3<U,  P,# P,# P # P,# P,# P,30S
+M #$Q,3<T-C T,34W # P,30Q,C$ 00                              
+M                                                            
+M                                          !U<W1A<@ P,       
+M                                    <F]O=                   
+M                   P,# P-#$T # P,# P,#,                     
+M                                                            
+M                                                            
+M                                                            
+M                       Q,# P,# W '5S97(Z.G)W+2QU<V5R.FQP.BTM
+M>#HW,2QU<V5R.C8V-CIR+2TZ-C8V+'5S97(Z,3 P,#IR=W@Z,3 P,"QG<F]U
+M<#HZ<BTM+&UA<VLZ<BTM+&]T:&5R.G(M+0       # !                
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                           (Q@@(     &L         ,3 P,# P-P!U
 M<V5R.CIR=RTL=7-E<CIL<#HM+7@Z-S$L=7-E<CHV-C8Z<BTM.C8V-BQU<V5R
-M.G1R87-Z.G)W>#HQ,#`P+&=R;W5P.CIR+2TL;6%S:SIR+69I;&4M=VET:"UP
-M;W-I>"UA8VQS````````````````````````````````````````````````
-M```````````````````````````````````````````````````````````P
-M,#`P-C0T`#`P,#$W-3``,#`P,#`P,``P,#`P,#`P,#`P,``Q,3$W-#8P-#$U
-M-P`P,#$U,30T`#``````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````=7-T87(`,#!T<F%S>@``````````````
-M`````````````````````')O;W0`````````````````````````````````
-M````,#`P,#(Q,``P,#`P,#$P````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````````
-H````````````````````````````````````````````````````````
-`
+M.C$P,# Z<G=X.C$P,# L9W)O=7 Z.G(M+2QM87-K.G(M+69I;&4M=VET:"UP
+M;W-I>"UA8VQS                                                
+M                                                           P
+M,# P-C0T # P,#$W-3  ,# P,# P,  P,# P,# P,# P,  Q,3$W-#8P-#$U
+M-P P,#$T,#<P #                                              
+M                                                            
+M                            =7-T87( ,#                      
+M                     ')O;W0                                 
+M    ,# P,#0Q-  P,# P,# S                                    
+M                                                            
+M                                                            
+M                                                            
+M        9&ER+7=I=&@M<&]S:7@M86-L<R\                         
+M                                                            
+M                     # P,# W-3  ,# P,3<U,  P,# P,# P # P,# P
+M,# P,S P #$S,#,V-3$R,C4T # P,30P,C, 00                      
+M                                                            
+M                                                  !U<W1A<@ P
+M,                                           <F]O=           
+M                           P,# P-#$T # P,# P,#,             
+M                                                            
+M                                                            
+M                                                            
+M                               Q,# P,#$T '5S97(Z.G)W>"QU<V5R
+M.F)I;CIR=W@Z,BQG<F]U<#HZ<BUX+&=R;W5P.G-Y<SIR+7@Z,RQM87-K.G(M
+M>"QO=&AE<CHM+2TL9&5F875L='5S97(Z.G)W>"QD969A=6QT=7-E<CIB:6XZ
+M<G=X.C(L9&5F875L=&=R;W5P.CIR+7@L9&5F875L=&=R;W5P.G-Y<SIR+7@Z
+M,RQD969A=6QT;6%S:SIR=W@L9&5F875L=&]T:&5R.BTM+0   @       #C%
+M" @                                                         
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                     &1I<BUW
+M:71H+7!O<VEX+6%C;',O                                        
+M                                                            
+M       P,# P-S4P # P,#$W-3  ,# P,# P,  P,# P,# P,# P,  Q,S S
+M-C4Q,C(U-  P,#$T,# T #4                                     
+M                                                            
+M                                    =7-T87( ,#              
+M                             ')O;W0                         
+M            ,# P,#0Q-  P,# P,# S                            
+M                                                            
+M                                                            
+M                                                            
+M                9FEL92UW:71H+6YF<W8T+6%C;',                 
+M                                                            
+M                             # P,# V-#  ,# P,3<U,  P,# P,# P
+M # P,# P,# P,S8T #$S,#,V-3$S-C0Q # P,30P,34 00              
+M                                                            
+M                                                          !U
+M<W1A<@ P,                                           <F]O=   
+M                                   P,# P-#$T # R,# P,#(     
+M                                                            
+M                                                            
+M                                                            
+M                                       S,# P,# V &=R;W5P.F1A
+M96UO;CIR=WAP+2UA05)78T-O<SHM+2TM+2TM.F1E;GDZ,3(L9W)O=7 Z8FEN
+M.G)W>' M+2TM+2TM+2US.BTM+2TM+2TZ86QL;W<Z,BQU<V5R.F%D;3IR+2TM
+M+2UA+5(M8RTM<SHM+2TM+2TM.F%L;&]W.C0L;W=N97) .G)W+7 M+6%!4E=C
+M0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7! .G(M+2TM+6$M4BUC+2US.BTM+2TM
+M+2TZ86QL;W<L979E<GEO;F5 .BTM+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL
+M;W<      &@                                                 
+M                                                            
+M                            F-8("     #[         #,P,# P,#8 
+M9W)O=7 Z9&%E;6]N.G)W>' M+6%!4E=C0V]S.BTM+2TM+2TZ9&5N>3HQ,BQG
+M<F]U<#IB:6XZ<G=X<"TM+2TM+2TM+7,Z+2TM+2TM+3IA;&QO=SHR+'5S97(Z
+M861M.G(M+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL;W<Z-"QO=VYE<D Z<G<M
+M<&9I;&4M=VET:"UN9G-V-"UA8VQS                                
+M                                                            
+M               P,# P-C0P # P,#$W-3  ,# P,# P,  P,# P,# P,# P
+M,  Q,S S-C4Q,S8T,0 P,#$S-S4W #                              
+M                                                            
+M                                            =7-T87( ,#      
+M                                     ')O;W0                 
+M                    ,# P,#0Q-  P,C P,# R                    
+M                                                            
+M                                                            
+M                                                            
+M                        9&ER+7=I=&@M;F9S=C0M86-L<R\         
+M                                                            
+M                                     # P,# W-3  ,# P,# P,  P
+M,# P,# P # P,# P,# P,S$T #$S,#,V-3$S-S,U # P,30V,C, 00      
+M                                                            
+M                                                            
+M      !U<W1A<@ P,')O;W0                                     
+M<F]O=                                      P,# P-#$T # R,# P
+M,#(                                                         
+M                                                            
+M                                                            
+M                                               S,# P,# U '5S
+M97(Z,3$P,#IR=WAP+2UA05)78T-O<SIF9&DM+2TM.F%L;&]W.C$Q,# L9W)O
+M=7 Z861M.G(M+2TM+6$M4BUC+2US.F9D+2TM+2TZ86QL;W<Z-"QO=VYE<D Z
+M<G=X<"U$84%25V-#;W,Z+2TM+2TM+3IA;&QO=RQG<F]U<$ Z<BUX+2TM82U2
+M+6,M+7,Z+2TM+2TM+3IA;&QO=RQE=F5R>6]N94 Z+2TM+2TM82U2+6,M+7,Z
+M+2TM+2TM+3IA;&QO=P      4                                   
+M                                                            
+M          "HUP@(     -,         ,S P,# P-0!U<V5R.C$Q,# Z<G=X
+M<"TM84%25V-#;W,Z9F1I+2TM+3IA;&QO=SHQ,3 P+&=R;W5P.F%D;3IR+2TM
+M+2UA+5(M8RTM<SIF9"TM+2TM.F%L;&]W.C0L;W=N97) .G)W>' M1&%!4E=C
+M0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7! .G(M>"TM+6$M4BUC+2US.BTM+2TM
+M+2TZ86QL;W<L979E<GEO;F5 .BTM+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL
+M;W<      &1I<BUW:71H+6YF<W8T+6%C;',O                        
+M                                                            
+M                       P,# P-S4P # P,# P,#  ,# P,# P,  P,# P
+M,# P,# P,  Q,S S-C4Q,S<S-0 P,#$T-3<W #4                     
+M                                                            
+M                                                    =7-T87( 
+M,#!R;V]T                                     ')O;W0         
+M                            ,# P,#0Q-  P,C P,# R            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+M                                                            
+-                    
+ 
 end