]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Unify platform ACL tests
authorMartin Matuska <martin@matuska.org>
Wed, 11 Jan 2017 12:25:39 +0000 (13:25 +0100)
committerMartin Matuska <martin@matuska.org>
Wed, 11 Jan 2017 21:38:50 +0000 (22:38 +0100)
Enable POSIX.1e tests on Linux systems with libacl
Add POSIX.1e default ACL test

Makefile.am
libarchive/test/CMakeLists.txt
libarchive/test/test.h
libarchive/test/test_acl_platform_nfs4.c [moved from libarchive/test/test_acl_freebsd_nfs4.c with 75% similarity]
libarchive/test/test_acl_platform_posix1e.c [moved from libarchive/test/test_acl_freebsd_posix1e.c with 57% similarity]
libarchive/test/test_acl_solaris_nfs4.c [deleted file]
libarchive/test/test_acl_solaris_posix1e.c [deleted file]

index 318c7ac5ac481ed8764feb9496da02739e3d68db..c5f468645efafe573e448c4aab4f259f485f55a5 100644 (file)
@@ -323,13 +323,11 @@ libarchive_test_SOURCES= \
        libarchive/test/main.c \
        libarchive/test/read_open_memory.c \
        libarchive/test/test.h \
-       libarchive/test/test_acl_freebsd_nfs4.c \
-       libarchive/test/test_acl_freebsd_posix1e.c \
        libarchive/test/test_acl_nfs4.c \
        libarchive/test/test_acl_pax.c \
+       libarchive/test/test_acl_platform_nfs4.c \
+       libarchive/test/test_acl_platform_posix1e.c \
        libarchive/test/test_acl_posix1e.c \
-       libarchive/test/test_acl_solaris_nfs4.c \
-       libarchive/test/test_acl_solaris_posix1e.c \
        libarchive/test/test_acl_text.c \
        libarchive/test/test_archive_api_feature.c \
        libarchive/test/test_archive_clear_error.c \
index 9bf19b93aa41cd7e330dcb6058fe2e7bfe849791..6c4ac23baa24456f4177587638b4e6595cb54158 100644 (file)
@@ -9,13 +9,11 @@ IF(ENABLE_TEST)
     main.c
     read_open_memory.c
     test.h
-    test_acl_freebsd_nfs4.c
-    test_acl_freebsd_posix1e.c
     test_acl_nfs4.c
     test_acl_pax.c
+    test_acl_platform_nfs4.c
+    test_acl_platform_posix1e.c
     test_acl_posix1e.c
-    test_acl_solaris_nfs4.c
-    test_acl_solaris_posix1e.c
     test_acl_text.c
     test_archive_api_feature.c
     test_archive_clear_error.c
index 71ab1c6b3fe04679abfe0fc89c6de2335c4cc72b..dd1ee8fe5f9eb963c8040e929fb6f4cd8e8bdadd 100644 (file)
 #define        O_BINARY 0
 #endif
 
+/*
+ * If this platform has <sys/acl.h>, acl_create(), acl_init(),
+ * acl_set_file(), and ACL_USER, we assume it has the rest of the
+ * POSIX.1e draft functions used in archive_read_extract.c.
+ */
+#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE && HAVE_ACL_USER
+#define        HAVE_POSIX_ACL  1
+#endif
+
+/*
+ * If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
+ * facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
+ */
+#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
+#define        HAVE_SUN_ACL    1
+#endif
+
 /*
  * Redefine DEFINE_TEST for use in defining the test functions.
  */
similarity index 75%
rename from libarchive/test/test_acl_freebsd_nfs4.c
rename to libarchive/test/test_acl_platform_nfs4.c
index 4e68623c1722d33fd7197f0dab1d0fb649b4a491..728c6fc6529600581d688a01378a1151a63b6dfb 100644 (file)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2003-2010 Tim Kientzle
+ * Copyright (c) 2017 Martin Matuska
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "test.h"
 __FBSDID("$FreeBSD$");
 
-#if defined(__FreeBSD__) && __FreeBSD__ >= 8
+#if HAVE_SUN_ACL || HAVE_POSIX_ACL
 #define _ACL_PRIVATE
 #include <sys/acl.h>
+#endif
+
+#if HAVE_SUN_ACL || (HAVE_POSIX_ACL && defined(ACL_TYPE_NFS4))
 
 struct myacl_t {
        int type;
@@ -90,7 +94,6 @@ static struct myacl_t acls_reg[] = {
          ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
 };
 
-
 static struct myacl_t acls_dir[] = {
        /* For this test, we need to be able to read and write the ACL. */
        { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL,
@@ -188,9 +191,32 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
 }
 
 static int
+#ifdef HAVE_SUN_ACL
+acl_permset_to_bitmap(uint32_t a_access_mask)
+#else
 acl_permset_to_bitmap(acl_permset_t opaque_ps)
+#endif
 {
        static struct { int machine; int portable; } perms[] = {
+#ifdef HAVE_SUN_ACL
+               {ACE_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
+               {ACE_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
+               {ACE_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
+               {ACE_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
+               {ACE_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
+               {ACE_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
+               {ACE_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
+               {ACE_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
+               {ACE_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
+               {ACE_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
+               {ACE_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
+               {ACE_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
+               {ACE_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
+               {ACE_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
+               {ACE_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
+               {ACE_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
+               {ACE_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
+#else
                {ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
                {ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
                {ACL_READ, ARCHIVE_ENTRY_ACL_READ},
@@ -210,51 +236,109 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
                {ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
                {ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
                {ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
+#endif
        };
        int i, permset = 0;
 
        for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
+#if HAVE_SUN_ACL
+               if (a_access_mask & perms[i].machine)
+#else
                if (acl_get_perm_np(opaque_ps, perms[i].machine))
+#endif
                        permset |= perms[i].portable;
        return permset;
 }
 
 static int
+#if HAVE_SUN_ACL
+acl_flagset_to_bitmap(uint16_t a_flags)
+#else
 acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
+#endif
 {
        static struct { int machine; int portable; } flags[] = {
+#if HAVE_SUN_ACL
+               {ACE_FILE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
+               {ACE_DIRECTORY_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
+               {ACE_NO_PROPAGATE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
+               {ACE_INHERIT_ONLY_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
+               {ACE_SUCCESSFUL_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
+               {ACE_FAILED_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
+               {ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
+#else
                {ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
                {ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
                {ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
+               {ACL_ENTRY_SUCCESSFUL_ACCESS, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
+               {ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
+
                {ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
+#endif
        };
        int i, flagset = 0;
 
        for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
+#if HAVE_SUN_ACL
+               if (a_flags & flags[i].machine)
+#else
                if (acl_get_flag_np(opaque_fs, flags[i].machine))
+#endif
                        flagset |= flags[i].portable;
        return flagset;
 }
 
 static int
+#if HAVE_SUN_ACL
+acl_match(ace_t *ace, struct myacl_t *myacl)
+#else
 acl_match(acl_entry_t aclent, struct myacl_t *myacl)
+#endif
 {
+#if !HAVE_SUN_ACL
        gid_t g, *gp;
        uid_t u, *up;
        acl_tag_t tag_type;
        acl_permset_t opaque_ps;
        acl_flagset_t opaque_fs;
+#endif
        int perms;
 
+#if HAVE_SUN_ACL
+       perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags);
+#else
        acl_get_tag_type(aclent, &tag_type);
 
        /* translate the silly opaque permset to a bitmap */
        acl_get_permset(aclent, &opaque_ps);
        acl_get_flagset_np(aclent, &opaque_fs);
        perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
+#endif
        if (perms != myacl->permset)
                return (0);
 
+#if HAVE_SUN_ACL
+       if (ace->a_flags & ACE_OWNER) {
+               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ)
+                       return (0);
+       } else if (ace->a_flags & ACE_GROUP) {
+               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ)
+                       return (0);
+       } else if (ace->a_flags & ACE_EVERYONE) {
+               if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE)
+                       return (0);
+       } else if (ace->a_flags & ACE_IDENTIFIER_GROUP) {
+               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
+                       return (0);
+               if ((gid_t)myacl->qual != ace->a_who)
+                       return (0);
+       } else {
+               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
+                       return (0);
+               if ((uid_t)myacl->qual != ace->a_who)
+                       return (0);
+       }
+#else  /* !HAVE_SUN_ACL */
        switch (tag_type) {
        case ACL_USER_OBJ:
                if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
@@ -287,17 +371,29 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
                if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
                break;
        }
+#endif /* !HAVE_SUN_ACL */
        return (1);
 }
 
 static void
-compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start, int end)
+compare_acls(
+#if HAVE_SUN_ACL
+    acl_t *acl,
+#else
+    acl_t acl,
+#endif
+    struct myacl_t *myacls, const char *filename, int start, int end)
 {
        int *marker;
-       int entry_id = ACL_FIRST_ENTRY;
        int matched;
        int i, n;
+#if HAVE_SUN_ACL
+       int e;
+       ace_t *acl_entry;
+#else
+       int entry_id = ACL_FIRST_ENTRY;
        acl_entry_t acl_entry;
+#endif
 
        n = end - start;
        marker = malloc(sizeof(marker[0]) * (n + 1));
@@ -313,10 +409,18 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
         * Iterate over acls in system acl object, try to match each
         * one with an item in the myacls array.
         */
-       while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
+#if HAVE_SUN_ACL
+       for (e = 0; e < acl->acl_cnt; e++)
+#else
+       while (1 == acl_get_entry(acl, entry_id, &acl_entry))
+#endif
+       {
+#if HAVE_SUN_ACL
+               acl_entry = &((ace_t *)acl->acl_aclp)[e];
+#else
                /* After the first time... */
                entry_id = ACL_NEXT_ENTRY;
-
+#endif
                /* Search for a matching entry (tag and qualifier) */
                for (i = 0, matched = 0; i < n && !matched; i++) {
                        if (acl_match(acl_entry, &myacls[marker[i]])) {
@@ -327,7 +431,8 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
                        }
                }
 
-               failure("ACL entry on file %s that shouldn't be there", filename);
+               failure("ACL entry on file %s that shouldn't be there",
+                   filename);
                assert(matched == 1);
        }
 
@@ -368,7 +473,8 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
         * Iterate over acls in entry, try to match each
         * one with an item in the myacls array.
         */
-       assertEqualInt(n, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
+       assertEqualInt(n, archive_entry_acl_reset(ae,
+           ARCHIVE_ENTRY_ACL_TYPE_NFS4));
        while (ARCHIVE_OK == archive_entry_acl_next(ae,
            ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) {
 
@@ -403,53 +509,78 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
        }
        free(marker);
 }
-#endif
+#endif /* HAVE_SUN_ACL || (HAVE_POSIX_ACL && defined(ACL_TYPE_NFS4)) */
 
 /*
- * Verify ACL restore-to-disk.  This test is FreeBSD-specific.
+ * Verify ACL restore-to-disk.  This test is Platform-specific.
  */
 
-DEFINE_TEST(test_acl_freebsd_nfs4)
+DEFINE_TEST(test_acl_platform_nfs4)
 {
-#if !defined(__FreeBSD__)
-       skipping("FreeBSD-specific NFS4 ACL restore test");
-#elif __FreeBSD__ < 8
-       skipping("NFS4 ACLs supported only on FreeBSD 8.0 and later");
+#if !HAVE_SUN_ACL && (!HAVE_POSIX_ACL || !defined(ACL_TYPE_NFS4))
+       skipping("NFS4 ACLs are not supported on this platform");
 #else
        char buff[64];
        struct stat st;
        struct archive *a;
        struct archive_entry *ae;
        int i, n;
+       char *func;
+#if HAVE_SUN_ACL
+       acl_t *acl;
+#else
        acl_t acl;
+#endif
 
        /*
         * First, do a quick manual set/read of ACL data to
         * verify that the local filesystem does support ACLs.
         * If it doesn't, we'll simply skip the remaining tests.
         */
+#if !HAVE_SUN_ACL
        acl = acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
+       failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
        assert((void *)acl != NULL);
+#endif
+
        /* Create a test dir and try to set an ACL on it. */
        if (!assertMakeDir("pretest", 0755)) {
+#if !HAVE_SUN_ACL
                acl_free(acl);
+#endif
                return;
        }
 
+#if HAVE_SUN_ACL
+       func = "acl_get()";
+       n = acl_get("pretest", 0, &acl);
+#else
+       func = "acl_set_file()";
        n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
        acl_free(acl);
-       if (n != 0 && errno == EOPNOTSUPP) {
-               skipping("NFS4 ACL tests require that NFS4 ACLs"
-                   " be enabled on the filesystem");
-               return;
+#endif
+       if (n != 0) {
+#if HAVE_SUN_ACL
+               if (errno == ENOSYS)
+#else
+               if (errno == EOPNOTSUPP || errno == EINVAL)
+#endif
+               {
+                       skipping("NFS4 ACL is not supported on this filesystem");
+                       return;
+               }
        }
-       if (n != 0 && errno == EINVAL) {
-               skipping("This filesystem does not support NFS4 ACLs");
+       failure("%s: errno = %d (%s)", func, errno, strerror(errno));
+       assertEqualInt(0, n);
+
+#if HAVE_SUN_ACL
+       if (acl->acl_type != ACE_T) {
+               acl_free(acl);
+               skipping("NFS4 ACL is not supported on this filesystem");
                return;
        }
-       failure("acl_set_file(): errno = %d (%s)",
-           errno, strerror(errno));
-       assertEqualInt(0, n);
+       acl_free(acl);
+#endif
 
        /* Create a write-to-disk object. */
        assert(NULL != (a = archive_write_disk_new()));
@@ -496,28 +627,51 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
        /* Verify the data on disk. */
        assertEqualInt(0, stat("testall", &st));
        assertEqualInt(st.st_mtime, 123456);
+#if HAVE_SUN_ACL
+       n = acl_get("testall", 0, &acl);
+       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+#else
        acl = acl_get_file("testall", ACL_TYPE_NFS4);
+       failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
        assert(acl != (acl_t)NULL);
+#endif
        compare_acls(acl, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
        acl_free(acl);
 
        /* Verify single-permission dirs on disk. */
        for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
-         sprintf(buff, "dir%d", i);
-         assertEqualInt(0, stat(buff, &st));
-         assertEqualInt(st.st_mtime, 123456 + i);
-         acl = acl_get_file(buff, ACL_TYPE_NFS4);
-         assert(acl != (acl_t)NULL);
-         compare_acls(acl, acls_dir, buff, i, i + 1);
-         acl_free(acl);
+               sprintf(buff, "dir%d", i);
+               assertEqualInt(0, stat(buff, &st));
+               assertEqualInt(st.st_mtime, 123456 + i);
+#if HAVE_SUN_ACL
+               n = acl_get(buff, 0, &acl);
+               failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
+               assertEqualInt(0, n);
+#else
+               acl = acl_get_file(buff, ACL_TYPE_NFS4);
+               failure("acl_get_file(): errno = %d (%s)", errno,
+                   strerror(errno));
+               assert(acl != (acl_t)NULL);
+#endif
+               compare_acls(acl, acls_dir, buff, i, i + 1);
+               acl_free(acl);
        }
 
        /* Verify "dirall" on disk. */
        assertEqualInt(0, stat("dirall", &st));
        assertEqualInt(st.st_mtime, 123456);
+#if HAVE_SUN_ACL
+       n = acl_get("dirall", 0, &acl);
+       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+#else
        acl = acl_get_file("dirall", ACL_TYPE_NFS4);
+       failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
        assert(acl != (acl_t)NULL);
-       compare_acls(acl, acls_dir, "dirall", 0,  (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
+#endif
+       compare_acls(acl, acls_dir, "dirall", 0,
+           (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
        acl_free(acl);
 
        /* Read and compare ACL via archive_read_disk */
@@ -528,7 +682,8 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
        archive_entry_set_pathname(ae, "testall");
        assertEqualInt(ARCHIVE_OK,
                       archive_read_disk_entry_from_file(a, ae, -1, NULL));
-       compare_entry_acls(ae, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
+       compare_entry_acls(ae, acls_reg, "testall", 0,
+           (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
        archive_entry_free(ae);
        assertEqualInt(ARCHIVE_OK, archive_read_free(a));
 
@@ -539,9 +694,10 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
        assert(ae != NULL);
        archive_entry_set_pathname(ae, "dirall");
        assertEqualInt(ARCHIVE_OK,
-                      archive_read_disk_entry_from_file(a, ae, -1, NULL));
-       compare_entry_acls(ae, acls_dir, "dirall", 0,  (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
+       archive_read_disk_entry_from_file(a, ae, -1, NULL));
+       compare_entry_acls(ae, acls_dir, "dirall", 0,
+           (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
        archive_entry_free(ae);
        assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-#endif
+#endif /* HAVE_SUN_ACL || (HAVE_POSIX_ACL && defined(ACL_TYPE_NFS4)) */
 }
similarity index 57%
rename from libarchive/test/test_acl_freebsd_posix1e.c
rename to libarchive/test/test_acl_platform_posix1e.c
index 7e5212ac01fd6fcd30d115386259b8586edcf25b..0c6a2c8f67362a87d16ea1433d2cd0fbf4dd5c93 100644 (file)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2003-2008 Tim Kientzle
+ * Copyright (c) 2017 Martin Matuska
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "test.h"
 __FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $");
 
-#if defined(__FreeBSD__) && __FreeBSD__ > 4
+#if HAVE_POSIX_ACL || HAVE_SUN_ACL
 #include <sys/acl.h>
+#if HAVE_ACL_GET_PERM
+#include <acl/libacl.h>
+#define ACL_GET_PERM acl_get_perm
+#elif HAVE_ACL_GET_PERM_NP
+#define ACL_GET_PERM acl_get_perm_np
+#endif
 
 static struct archive_test_acl_t acls2[] = {
        { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
@@ -48,18 +55,34 @@ static struct archive_test_acl_t acls2[] = {
 };
 
 static int
-acl_entry_get_perm(acl_entry_t aclent) {
+#if HAVE_SUN_ACL
+acl_entry_get_perm(aclent_t *aclent)
+#else
+acl_entry_get_perm(acl_entry_t aclent)
+#endif
+{
        int permset = 0;
+#if HAVE_POSIX_ACL
        acl_permset_t opaque_ps;
+#endif
 
+#if HAVE_SUN_ACL
+       if (aclent->a_perm & 1)
+               permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
+       if (aclent->a_perm & 2)
+               permset |= ARCHIVE_ENTRY_ACL_WRITE;
+       if (aclent->a_perm & 4)
+               permset |= ARCHIVE_ENTRY_ACL_READ;
+#else
        /* translate the silly opaque permset to a bitmap */
        acl_get_permset(aclent, &opaque_ps);
-       if (acl_get_perm_np(opaque_ps, ACL_EXECUTE))
+       if (ACL_GET_PERM(opaque_ps, ACL_EXECUTE))
                permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
-       if (acl_get_perm_np(opaque_ps, ACL_WRITE))
+       if (ACL_GET_PERM(opaque_ps, ACL_WRITE))
                permset |= ARCHIVE_ENTRY_ACL_WRITE;
-       if (acl_get_perm_np(opaque_ps, ACL_READ))
+       if (ACL_GET_PERM(opaque_ps, ACL_READ))
                permset |= ARCHIVE_ENTRY_ACL_READ;
+#endif
        return permset;
 }
 
@@ -105,45 +128,96 @@ acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_ta
 #endif
 
 static int
+#if HAVE_SUN_ACL
+acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl)
+#else
 acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
+#endif
 {
+#if HAVE_POSIX_ACL
        gid_t g, *gp;
        uid_t u, *up;
        acl_tag_t tag_type;
+#endif
 
        if (myacl->permset != acl_entry_get_perm(aclent))
                return (0);
 
+#if HAVE_SUN_ACL
+       switch (aclent->a_type)
+#else
        acl_get_tag_type(aclent, &tag_type);
-       switch (tag_type) {
+       switch (tag_type)
+#endif
+       {
+#if HAVE_SUN_ACL
+       case DEF_USER_OBJ:
+       case USER_OBJ:
+#else
        case ACL_USER_OBJ:
+#endif
                if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
                break;
+#if HAVE_SUN_ACL
+       case DEF_USER:
+       case USER:
+#else
        case ACL_USER:
+#endif
                if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
                        return (0);
+#if HAVE_SUN_ACL
+               if ((uid_t)myacl->qual != aclent->a_id)
+                       return (0);
+#else
                up = acl_get_qualifier(aclent);
                u = *up;
                acl_free(up);
                if ((uid_t)myacl->qual != u)
                        return (0);
+#endif
                break;
+#if HAVE_SUN_ACL
+       case DEF_GROUP_OBJ:
+       case GROUP_OBJ:
+#else
        case ACL_GROUP_OBJ:
+#endif
                if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
                break;
+#if HAVE_SUN_ACL
+       case DEF_GROUP:
+       case GROUP:
+#else
        case ACL_GROUP:
+#endif
                if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
                        return (0);
+#if HAVE_SUN_ACL
+               if ((gid_t)myacl->qual != aclent->a_id)
+                       return (0);
+#else
                gp = acl_get_qualifier(aclent);
                g = *gp;
                acl_free(gp);
                if ((gid_t)myacl->qual != g)
                        return (0);
+#endif
                break;
+#if HAVE_SUN_ACL
+       case DEF_CLASS_OBJ:
+       case CLASS_OBJ:
+#else
        case ACL_MASK:
+#endif
                if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
                break;
+#if HAVE_SUN_ACL
+       case DEF_OTHER_OBJ:
+       case OTHER_OBJ:
+#else
        case ACL_OTHER:
+#endif
                if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0);
                break;
        }
@@ -151,13 +225,22 @@ acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
 }
 
 static void
+#if HAVE_SUN_ACL
+compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n)
+#else
 compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
+#endif
 {
        int *marker;
-       int entry_id = ACL_FIRST_ENTRY;
        int matched;
        int i;
+#if HAVE_SUN_ACL
+       int e;
+       aclent_t *acl_entry;
+#else
+       int entry_id = ACL_FIRST_ENTRY;
        acl_entry_t acl_entry;
+#endif
 
        /* Count ACL entries in myacls array and allocate an indirect array. */
        marker = malloc(sizeof(marker[0]) * n);
@@ -170,9 +253,14 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
         * Iterate over acls in system acl object, try to match each
         * one with an item in the myacls array.
         */
+#if HAVE_SUN_ACL
+       for(e = 0; e < acl->acl_cnt; e++) {
+               acl_entry = &((aclent_t *)acl->acl_aclp)[e];
+#else
        while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
                /* After the first time... */
                entry_id = ACL_NEXT_ENTRY;
+#endif
 
                /* Search for a matching entry (tag and qualifier) */
                for (i = 0, matched = 0; i < n && !matched; i++) {
@@ -205,30 +293,41 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
 
 
 /*
- * Verify ACL restore-to-disk.  This test is FreeBSD-specific.
+ * Verify ACL restore-to-disk.  This test is Platform-specific.
  */
 
-DEFINE_TEST(test_acl_freebsd_posix1e_restore)
+DEFINE_TEST(test_acl_platform_posix1e_restore)
 {
-#if !defined(__FreeBSD__)
-       skipping("FreeBSD-specific ACL restore test");
-#elif __FreeBSD__ < 5
-       skipping("ACL restore supported only on FreeBSD 5.0 and later");
-#else
+#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
+       skipping("POSIX.1e ACLs are not supported on this platform");
+#else  /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
        struct stat st;
        struct archive *a;
        struct archive_entry *ae;
        int n, fd;
+       char *func;
+#if HAVE_SUN_ACL
+       acl_t *acl, *acl2;
+#else
        acl_t acl;
+#endif
 
        /*
         * First, do a quick manual set/read of ACL data to
         * verify that the local filesystem does support ACLs.
         * If it doesn't, we'll simply skip the remaining tests.
         */
+#if HAVE_SUN_ACL
+       n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl);
+       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+#else
        acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
+       failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
        assert((void *)acl != NULL);
-       /* Create a test file and try to set an ACL on it. */
+#endif
+
+       /* Create a test file and try ACL on it. */
        fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
        failure("Could not create test file?!");
        if (!assert(fd >= 0)) {
@@ -236,21 +335,51 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
                return;
        }
 
-       n = acl_set_fd(fd, acl);
-       acl_free(acl);
-       if (n != 0 && errno == EOPNOTSUPP) {
+#if HAVE_SUN_ACL
+       n = facl_get(fd, 0, &acl2);
+       if (n != 0) {
                close(fd);
-               skipping("ACL tests require that ACL support be enabled on the filesystem");
+               acl_free(acl);
+       }
+       if (errno == ENOSYS) {
+               skipping("POSIX.1e ACLs are not supported on this filesystem");
                return;
        }
-       if (n != 0 && errno == EINVAL) {
-               close(fd);
-               skipping("This filesystem does not support POSIX.1e ACLs");
+       failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+
+       if (acl2->acl_type != ACLENT_T) {
+               acl_free(acl2);
+               skipping("POSIX.1e ACLs are not supported on this filesystem");
                return;
        }
-       failure("acl_set_fd(): errno = %d (%s)",
-           errno, strerror(errno));
+       acl_free(acl2);
+
+       func = "facl_set()";
+       n = facl_set(fd, acl);
+#else
+       func = "acl_set_fd()";
+       n = acl_set_fd(fd, acl);
+#endif
+       acl_free(acl);
+       if (n != 0) {
+#if HAVE_SUN_ACL
+               if (errno == ENOSYS)
+#else
+               if (errno == EOPNOTSUPP || errno == EINVAL)
+#endif
+               {
+                       close(fd);
+                       skipping("POSIX.1e ACLs are not supported on this filesystem");
+                       return;
+               }
+       }
+       failure("%s: errno = %d (%s)", func, errno, strerror(errno));
        assertEqualInt(0, n);
+
+#if HAVE_SUN_ACL
+
+#endif
        close(fd);
 
        /* Create a write-to-disk object. */
@@ -275,28 +404,38 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
        /* Verify the data on disk. */
        assertEqualInt(0, stat("test0", &st));
        assertEqualInt(st.st_mtime, 123456);
+#if HAVE_SUN_ACL
+       n = acl_get("test0", 0, &acl);
+       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+#else
        acl = acl_get_file("test0", ACL_TYPE_ACCESS);
+       failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
        assert(acl != (acl_t)NULL);
+#endif
        compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0]));
        acl_free(acl);
-#endif
+#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
 }
 
 /*
- * Verify ACL read-from-disk.  This test is FreeBSD-specific.
+ * Verify ACL read-from-disk.  This test is Platform-specific.
  */
-DEFINE_TEST(test_acl_freebsd_posix1e_read)
+DEFINE_TEST(test_acl_platform_posix1e_read)
 {
-#if !defined(__FreeBSD__)
-       skipping("FreeBSD-specific ACL read test");
-#elif __FreeBSD__ < 5
-       skipping("ACL read supported only on FreeBSD 5.0 and later");
+#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
+       skipping("POSIX.1e ACLs are not supported on this platform");
 #else
        struct archive *a;
        struct archive_entry *ae;
-       int n, fd;
-       const char *acl1_text, *acl2_text;
-       acl_t acl1, acl2;
+       int n, fd, flags, dflags;
+       char *func;
+       const char *acl1_text, *acl2_text, *acl3_text;
+#if HAVE_SUN_ACL
+       acl_t *acl, *acl1, *acl2, *acl3;
+#else
+       acl_t acl1, acl2, acl3;
+#endif
 
        /*
         * Manually construct a directory and two files with
@@ -305,6 +444,17 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
         */
 
        /* Create a test file f1 with acl1 */
+#if HAVE_SUN_ACL
+       acl1_text = "user::rwx,"
+           "group::rwx,"
+           "other:rwx,"
+           "user:1:rw-,"
+           "group:15:r-x,"
+           "mask:rwx";
+       n = acl_fromtext(acl1_text, &acl1);
+       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+#else
        acl1_text = "user::rwx\n"
            "group::rwx\n"
            "other::rwx\n"
@@ -312,28 +462,57 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
            "group:15:r-x\n"
            "mask::rwx";
        acl1 = acl_from_text(acl1_text);
+       failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
        assert((void *)acl1 != NULL);
+#endif
        fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
        failure("Could not create test file?!");
        if (!assert(fd >= 0)) {
                acl_free(acl1);
                return;
        }
-       n = acl_set_fd(fd, acl1);
-       acl_free(acl1);
-       if (n != 0 && errno == EOPNOTSUPP) {
+#if HAVE_SUN_ACL
+       /* Check if Solars filesystem supports POSIX.1e ACLs */
+       n = facl_get(fd, 0, &acl);
+       if (n != 0)
                close(fd);
-               skipping("ACL tests require that ACL support be enabled on the filesystem");
+       if (n != 0 && errno == ENOSYS) {
+               acl_free(acl1);
+               skipping("POSIX.1e ACLs are not supported on this filesystem");
                return;
        }
-       if (n != 0 && errno == EINVAL) {
+       failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+
+       if (acl->acl_type != ACLENT_T) {
+               acl_free(acl);
+               acl_free(acl1);
                close(fd);
-               skipping("This filesystem does not support POSIX.1e ACLs");
+               skipping("POSIX.1e ACLs are not supported on this filesystem");
                return;
        }
-       failure("acl_set_fd(): errno = %d (%s)",
-           errno, strerror(errno));
+
+       func = "facl_set()";
+       n = facl_set(fd, acl1);
+#else
+       func = "acl_set_fd()";
+       n = acl_set_fd(fd, acl1);
+#endif
+       if (n != 0) {
+#if HAVE_SUN_ACL
+               if (errno == ENOSYS)
+#else
+               if (errno == EOPNOTSUPP || errno == EINVAL)
+#endif
+               {
+                       close(fd);
+                       skipping("POSIX.1e ACLs are not supported on this filesystem");
+                       return;
+               }
+       }
+       failure("%s: errno = %d (%s)", func, errno, strerror(errno));
        assertEqualInt(0, n);
+
        close(fd);
 
        assertMakeDir("d", 0700);
@@ -349,6 +528,17 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
         * to read ACLs, resulting in reading the ACL from a like-named
         * file in the wrong directory.
         */
+#if HAVE_SUN_ACL
+       acl2_text = "user::rwx,"
+           "group::rwx,"
+           "other:---,"
+           "user:1:r--,"
+           "group:15:r--,"
+           "mask:rwx";
+       n = acl_fromtext(acl2_text, &acl2);
+       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+#else
        acl2_text = "user::rwx\n"
            "group::rwx\n"
            "other::---\n"
@@ -356,43 +546,98 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
            "group:15:r--\n"
            "mask::rwx";
        acl2 = acl_from_text(acl2_text);
+       failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
        assert((void *)acl2 != NULL);
+#endif
        fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
        failure("Could not create test file?!");
        if (!assert(fd >= 0)) {
                acl_free(acl2);
                return;
        }
+#if HAVE_SUN_ACL
+       func = "facl_set()";
+       n = facl_set(fd, acl2);
+#else
+       func = "acl_set_fd()";
        n = acl_set_fd(fd, acl2);
-       acl_free(acl2);
-       if (n != 0 && errno == EOPNOTSUPP) {
+#endif
+       if (n != 0) {
+               acl_free(acl2);
                close(fd);
-               skipping("ACL tests require that ACL support be enabled on the filesystem");
-               return;
        }
-       if (n != 0 && errno == EINVAL) {
-               close(fd);
-               skipping("This filesystem does not support POSIX.1e ACLs");
-               return;
-       }
-       failure("acl_set_fd(): errno = %d (%s)",
-           errno, strerror(errno));
+       failure("%s: errno = %d (%s)", func, errno, strerror(errno));
        assertEqualInt(0, n);
        close(fd);
 
+       /* Create directory d2 with default ACLs */
+       assertMakeDir("d2", 0755);
+
+#if HAVE_SUN_ACL
+       acl3_text = "user::rwx,"
+           "group::r-x,"
+           "other:r-x,"
+           "user:2:r--,"
+           "group:16:-w-,"
+           "mask:rwx,"
+           "default:user::rwx,"
+           "default:user:1:r--,"
+           "default:group::r-x,"
+           "default:group:15:r--,"
+           "default:mask:rwx,"
+           "default:other:r-x";
+       n = acl_fromtext(acl3_text, &acl3);
+       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
+       assertEqualInt(0, n);
+#else
+       acl3_text = "user::rwx\n"
+           "user:1:r--\n"
+           "group::r-x\n"
+           "group:15:r--\n"
+           "mask::rwx\n"
+           "other::r-x";
+       acl3 = acl_from_text(acl3_text);
+       failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
+       assert((void *)acl3 != NULL);
+#endif
+
+#if HAVE_SUN_ACL
+       func = "acl_set()";
+       n = acl_set("d2", acl3);
+#else
+       func = "acl_set_file()";
+       n = acl_set_file("d2", ACL_TYPE_DEFAULT, acl3);
+#endif
+       if (n != 0)
+               acl_free(acl3);
+       failure("%s: errno = %d (%s)", func, errno, strerror(errno));
+       assertEqualInt(0, n);
+
        /* Create a read-from-disk object. */
        assert(NULL != (a = archive_read_disk_new()));
        assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
        assert(NULL != (ae = archive_entry_new()));
 
+#if HAVE_SUN_ACL
+       flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E
+           | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA
+           | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS;
+       dflags = flags;
+#else
+       flags = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+       dflags = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
+#endif
+
        /* Walk the dir until we see both of the files */
        while (ARCHIVE_OK == archive_read_next_header2(a, ae)) {
                archive_read_disk_descend(a);
                if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
-                       assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl1_text);
+                       assertEqualString(archive_entry_acl_to_text(ae, NULL, flags), acl1_text);
                            
                } else if (strcmp(archive_entry_pathname(ae), "./d/f1") == 0) {
-                       assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl2_text);
+                       assertEqualString(archive_entry_acl_to_text(ae, NULL, flags), acl2_text);
+               } else if (strcmp(archive_entry_pathname(ae), "./d2") == 0) {
+                       assertEqualString(archive_entry_acl_to_text(ae, NULL, dflags), acl3_text);
                }
        }
 
diff --git a/libarchive/test/test_acl_solaris_nfs4.c b/libarchive/test/test_acl_solaris_nfs4.c
deleted file mode 100644 (file)
index 6580de4..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/*-
- * Copyright (c) 2003-2010 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "test.h"
-
-#if defined(__sun__)
-#include <sys/acl.h>
-
-struct myacl_t {
-       int type;
-       int permset;
-       int tag;
-       int qual; /* GID or UID of user/group, depending on tag. */
-       const char *name; /* Name of user/group, depending on tag. */
-};
-
-static struct myacl_t acls_reg[] = {
-       /* For this test, we need the file owner to be able to read and write the ACL. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
-         ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
-
-       /* An entry for each type. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
-       { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_USER, 109, "user109" },
-
-       /* An entry for each permission. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_USER, 112, "user112" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA,
-         ARCHIVE_ENTRY_ACL_USER, 113, "user113" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA,
-         ARCHIVE_ENTRY_ACL_USER, 115, "user115" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA,
-         ARCHIVE_ENTRY_ACL_USER, 117, "user117" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
-         ARCHIVE_ENTRY_ACL_USER, 119, "user119" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
-         ARCHIVE_ENTRY_ACL_USER, 120, "user120" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
-         ARCHIVE_ENTRY_ACL_USER, 122, "user122" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
-         ARCHIVE_ENTRY_ACL_USER, 123, "user123" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
-         ARCHIVE_ENTRY_ACL_USER, 124, "user124" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
-         ARCHIVE_ENTRY_ACL_USER, 125, "user125" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
-         ARCHIVE_ENTRY_ACL_USER, 126, "user126" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
-         ARCHIVE_ENTRY_ACL_USER, 127, "user127" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
-         ARCHIVE_ENTRY_ACL_USER, 128, "user128" },
-
-       /* One entry for each qualifier. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_USER, 135, "user135" },
-//     { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
-//       ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
-};
-
-
-static struct myacl_t acls_dir[] = {
-       /* For this test, we need to be able to read and write the ACL. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL,
-         ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
-
-       /* An entry for each type. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
-         ARCHIVE_ENTRY_ACL_USER, 101, "user101" },
-       { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
-         ARCHIVE_ENTRY_ACL_USER, 102, "user102" },
-
-       /* An entry for each permission. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
-         ARCHIVE_ENTRY_ACL_USER, 201, "user201" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE,
-         ARCHIVE_ENTRY_ACL_USER, 202, "user202" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
-         ARCHIVE_ENTRY_ACL_USER, 203, "user203" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
-         ARCHIVE_ENTRY_ACL_USER, 204, "user204" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
-         ARCHIVE_ENTRY_ACL_USER, 205, "user205" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD,
-         ARCHIVE_ENTRY_ACL_USER, 206, "user206" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
-         ARCHIVE_ENTRY_ACL_USER, 207, "user207" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
-         ARCHIVE_ENTRY_ACL_USER, 208, "user208" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
-         ARCHIVE_ENTRY_ACL_USER, 209, "user209" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
-         ARCHIVE_ENTRY_ACL_USER, 210, "user210" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
-         ARCHIVE_ENTRY_ACL_USER, 211, "user211" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
-         ARCHIVE_ENTRY_ACL_USER, 212, "user212" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
-         ARCHIVE_ENTRY_ACL_USER, 213, "user213" },
-
-       /* One entry with each inheritance value. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT,
-         ARCHIVE_ENTRY_ACL_USER, 301, "user301" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
-         ARCHIVE_ENTRY_ACL_USER, 302, "user302" },
-#if 0
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
-         ARCHIVE_ENTRY_ACL_USER, 303, "user303" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
-         ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
-#endif
-
-#if 0
-       /* FreeBSD does not support audit entries. */
-       { ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS,
-         ARCHIVE_ENTRY_ACL_USER, 401, "user401" },
-       { ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
-         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS,
-         ARCHIVE_ENTRY_ACL_USER, 402, "user402" },
-#endif
-
-       /* One entry for each qualifier. */
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
-         ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
-         ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
-         ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
-         ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
-};
-
-static void
-set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
-{
-       int i;
-
-       archive_entry_acl_clear(ae);
-       if (start > 0) {
-               assertEqualInt(ARCHIVE_OK,
-                       archive_entry_acl_add_entry(ae,
-                           acls[0].type, acls[0].permset, acls[0].tag,
-                           acls[0].qual, acls[0].name));
-       }
-       for (i = start; i < end; i++) {
-               assertEqualInt(ARCHIVE_OK,
-                   archive_entry_acl_add_entry(ae,
-                       acls[i].type, acls[i].permset, acls[i].tag,
-                       acls[i].qual, acls[i].name));
-       }
-}
-
-static int
-acl_permset_to_bitmap(uint32_t a_access_mask)
-{
-       static struct { int machine; int portable; } perms[] = {
-               {ACE_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
-               {ACE_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
-               {ACE_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
-               {ACE_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
-               {ACE_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
-               {ACE_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
-               {ACE_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
-               {ACE_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
-               {ACE_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
-               {ACE_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
-               {ACE_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
-               {ACE_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
-               {ACE_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
-               {ACE_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
-               {ACE_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
-               {ACE_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
-               {ACE_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
-       };
-       int i, permset = 0;
-
-       for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
-               if (a_access_mask & perms[i].machine)
-                       permset |= perms[i].portable;
-       return permset;
-}
-
-static int
-acl_flagset_to_bitmap(uint16_t a_flags)
-{
-       static struct { int machine; int portable; } flags[] = {
-               {ACE_FILE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
-               {ACE_DIRECTORY_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
-               {ACE_NO_PROPAGATE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
-               {ACE_INHERIT_ONLY_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
-               {ACE_SUCCESSFUL_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
-               {ACE_FAILED_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
-               {ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
-       };
-       int i, flagset = 0;
-
-       for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
-               if (a_flags & flags[i].machine)
-                       flagset |= flags[i].portable;
-       return flagset;
-}
-
-static int
-acl_match(ace_t *ace, struct myacl_t *myacl)
-{
-       int perms;
-
-       /* translate the silly opaque permset to a bitmap */
-       perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags);
-       if (perms != myacl->permset)
-               return (0);
-
-       if (ace->a_flags & ACE_OWNER) {
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ)
-                       return (0);
-       } else if (ace->a_flags & ACE_GROUP) {
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ)
-                       return (0);
-       } else if (ace->a_flags & ACE_EVERYONE) {
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE)
-                       return (0);
-       } else if (ace->a_flags & ACE_IDENTIFIER_GROUP) {
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
-                       return (0);
-               if ((gid_t)myacl->qual != ace->a_who)
-                       return (0);
-       } else {
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
-                       return (0);
-               if ((uid_t)myacl->qual != ace->a_who)
-                       return (0);
-       }
-       return (1);
-}
-
-static void
-compare_acls(acl_t *acl, struct myacl_t *myacls, const char *filename, int start, int end)
-{
-       int *marker;
-       int matched;
-       int e, i, n;
-       ace_t *ace;
-
-       n = end - start;
-       marker = malloc(sizeof(marker[0]) * (n + 1));
-       for (i = 0; i < n; i++)
-               marker[i] = i + start;
-       /* Always include the first ACE. */
-       if (start > 0) {
-         marker[n] = 0;
-         ++n;
-       }
-
-       /*
-        * Iterate over acls in system acl object, try to match each
-        * one with an item in the myacls array.
-        */
-       for (e = 0; e < acl->acl_cnt; e++) {
-               ace = &((ace_t *)acl->acl_aclp)[e];
-               /* Search for a matching entry (tag and qualifier) */
-               for (i = 0, matched = 0; i < n && !matched; i++) {
-                       if (acl_match(ace, &myacls[marker[i]])) {
-                               /* We found a match; remove it. */
-                               marker[i] = marker[n - 1];
-                               n--;
-                               matched = 1;
-                       }
-               }
-
-               failure("ACL entry on file %s that shouldn't be there", filename);
-               assert(matched == 1);
-       }
-
-       /* Dump entries in the myacls array that weren't in the system acl. */
-       for (i = 0; i < n; ++i) {
-               failure(" ACL entry %d missing from %s: "
-                   "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n",
-                   marker[i], filename,
-                   myacls[marker[i]].type, myacls[marker[i]].permset,
-                   myacls[marker[i]].tag, myacls[marker[i]].qual,
-                   myacls[marker[i]].name);
-               assert(0); /* Record this as a failure. */
-       }
-       free(marker);
-}
-
-static void
-compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char *filename, int start, int end)
-{
-       int *marker;
-       int matched;
-       int i, n;
-       int type, permset, tag, qual;
-       const char *name;
-
-       /* Count ACL entries in myacls array and allocate an indirect array. */
-       n = end - start;
-       marker = malloc(sizeof(marker[0]) * (n + 1));
-       for (i = 0; i < n; i++)
-               marker[i] = i + start;
-       /* Always include the first ACE. */
-       if (start > 0) {
-         marker[n] = 0;
-         ++n;
-       }
-
-       /*
-        * Iterate over acls in entry, try to match each
-        * one with an item in the myacls array.
-        */
-       assertEqualInt(n, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
-       while (ARCHIVE_OK == archive_entry_acl_next(ae,
-           ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) {
-
-               /* Search for a matching entry (tag and qualifier) */
-               for (i = 0, matched = 0; i < n && !matched; i++) {
-                       if (tag == myacls[marker[i]].tag
-                           && qual == myacls[marker[i]].qual
-                           && permset == myacls[marker[i]].permset
-                           && type == myacls[marker[i]].type) {
-                               /* We found a match; remove it. */
-                               marker[i] = marker[n - 1];
-                               n--;
-                               matched = 1;
-                       }
-               }
-
-               failure("ACL entry on file that shouldn't be there: "
-                       "type=%#010x,permset=%#010x,tag=%d,qual=%d",
-                       type,permset,tag,qual);
-               assert(matched == 1);
-       }
-
-       /* Dump entries in the myacls array that weren't in the system acl. */
-       for (i = 0; i < n; ++i) {
-               failure(" ACL entry %d missing from %s: "
-                   "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n",
-                   marker[i], filename,
-                   myacls[marker[i]].type, myacls[marker[i]].permset,
-                   myacls[marker[i]].tag, myacls[marker[i]].qual,
-                   myacls[marker[i]].name);
-               assert(0); /* Record this as a failure. */
-       }
-       free(marker);
-}
-#endif
-
-/*
- * Verify ACL restore-to-disk.  This test is FreeBSD-specific.
- */
-
-DEFINE_TEST(test_acl_solaris_nfs4)
-{
-#if !defined(__sun__)
-       skipping("Solaris-specific NFS4 ACL restore test");
-#else
-       char buff[64];
-       struct stat st;
-       struct archive *a;
-       struct archive_entry *ae;
-       int i, n;
-       acl_t *acl;
-
-       /* Create a test dir and try to get trivial ACL from it. */
-       if (!assertMakeDir("pretest", 0755))
-               return;
-
-       n = acl_get("pretest", 0, &acl);
-       if (n != 0 && errno == ENOSYS) {
-               skipping("ACL tests require ACL support on the filesystem");
-               return;
-       }
-       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-
-       if (acl->acl_type != ACE_T) {
-               acl_free(acl);
-               skipping("Filesystem does not use NFSv4 ACLs");
-               return;
-       }
-
-       acl_free(acl);
-
-       /* Create a write-to-disk object. */
-       assert(NULL != (a = archive_write_disk_new()));
-       archive_write_disk_set_options(a,
-           ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL);
-
-       /* Populate an archive entry with some metadata, including ACL info */
-       ae = archive_entry_new();
-       assert(ae != NULL);
-       archive_entry_set_pathname(ae, "testall");
-       archive_entry_set_filetype(ae, AE_IFREG);
-       archive_entry_set_perm(ae, 0654);
-       archive_entry_set_mtime(ae, 123456, 7890);
-       archive_entry_set_size(ae, 0);
-       set_acls(ae, acls_reg, 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
-
-       /* Write the entry to disk, including ACLs. */
-       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
-
-       /* Likewise for a dir. */
-       archive_entry_set_pathname(ae, "dirall");
-       archive_entry_set_filetype(ae, AE_IFDIR);
-       archive_entry_set_perm(ae, 0654);
-       archive_entry_set_mtime(ae, 123456, 7890);
-       set_acls(ae, acls_dir, 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
-       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
-
-       for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
-         sprintf(buff, "dir%d", i);
-         archive_entry_set_pathname(ae, buff);
-         archive_entry_set_filetype(ae, AE_IFDIR);
-         archive_entry_set_perm(ae, 0654);
-         archive_entry_set_mtime(ae, 123456 + i, 7891 + i);
-         set_acls(ae, acls_dir, i, i + 1);
-         assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
-       }
-
-       archive_entry_free(ae);
-
-       /* Close the archive. */
-       assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
-
-       /* Verify the data on disk. */
-       assertEqualInt(0, stat("testall", &st));
-       assertEqualInt(st.st_mtime, 123456);
-       n = acl_get("testall", 0, &acl);
-       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-       compare_acls(acl, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
-       acl_free(acl);
-
-       /* Verify single-permission dirs on disk. */
-       for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
-         sprintf(buff, "dir%d", i);
-         assertEqualInt(0, stat(buff, &st));
-         assertEqualInt(st.st_mtime, 123456 + i);
-         n = acl_get(buff, 0, &acl);
-         failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
-         assertEqualInt(0, n);
-         compare_acls(acl, acls_dir, buff, i, i + 1);
-         acl_free(acl);
-       }
-
-       /* Verify "dirall" on disk. */
-       assertEqualInt(0, stat("dirall", &st));
-       assertEqualInt(st.st_mtime, 123456);
-       n = acl_get("dirall", 0, &acl);
-       failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-       compare_acls(acl, acls_dir, "dirall", 0,  (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
-       acl_free(acl);
-
-       /* Read and compare ACL via archive_read_disk */
-       a = archive_read_disk_new();
-       assert(a != NULL);
-       ae = archive_entry_new();
-       assert(ae != NULL);
-       archive_entry_set_pathname(ae, "testall");
-       assertEqualInt(ARCHIVE_OK,
-                      archive_read_disk_entry_from_file(a, ae, -1, NULL));
-       compare_entry_acls(ae, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
-       archive_entry_free(ae);
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
-       /* Read and compare ACL via archive_read_disk */
-       a = archive_read_disk_new();
-       assert(a != NULL);
-       ae = archive_entry_new();
-       assert(ae != NULL);
-       archive_entry_set_pathname(ae, "dirall");
-       assertEqualInt(ARCHIVE_OK,
-                      archive_read_disk_entry_from_file(a, ae, -1, NULL));
-       compare_entry_acls(ae, acls_dir, "dirall", 0,  (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
-       archive_entry_free(ae);
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-#endif
-}
diff --git a/libarchive/test/test_acl_solaris_posix1e.c b/libarchive/test/test_acl_solaris_posix1e.c
deleted file mode 100644 (file)
index 4f41221..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-/*-
- * Copyright (c) 2003-2008 Tim Kientzle
- * Copyright (c) 2017 Martin Matuska
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "test.h"
-
-#if defined(__sun__)
-#include <sys/acl.h>
-
-static struct archive_test_acl_t acls2[] = {
-       { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
-         ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
-         ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
-         ARCHIVE_ENTRY_ACL_USER, 78, "user78" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
-         ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
-         ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-         ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
-       { ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
-         ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EXECUTE,
-         ARCHIVE_ENTRY_ACL_MASK, -1, "" },
-};
-
-static int
-acl_entry_get_perm(aclent_t *aclent) {
-       int permset = 0;
-
-       if (aclent->a_perm & 1)
-               permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
-       if (aclent->a_perm & 2)
-               permset |= ARCHIVE_ENTRY_ACL_WRITE;
-       if (aclent->a_perm & 4)
-               permset |= ARCHIVE_ENTRY_ACL_READ;
-
-       return permset;
-}
-
-static int
-acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl)
-{
-       if (myacl->permset != acl_entry_get_perm(aclent))
-               return (0);
-
-       switch (aclent->a_type) {
-       case DEF_USER_OBJ:
-       case USER_OBJ:
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
-               break;
-       case DEF_USER:
-       case USER:
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
-                       return (0);
-               if ((uid_t)myacl->qual != aclent->a_id)
-                       return (0);
-               break;
-       case DEF_GROUP_OBJ:
-       case GROUP_OBJ:
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
-               break;
-       case DEF_GROUP:
-       case GROUP:
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
-                       return (0);
-               if ((gid_t)myacl->qual != aclent->a_id)
-                       return (0);
-               break;
-       case DEF_CLASS_OBJ:
-       case CLASS_OBJ:
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
-               break;
-       case DEF_OTHER_OBJ:
-       case OTHER_OBJ:
-               if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0);
-               break;
-       }
-       return (1);
-}
-
-static void
-compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n)
-{
-       int *marker;
-       int matched;
-       int e, i;
-       aclent_t *aclent;
-
-       /* Count ACL entries in myacls array and allocate an indirect array. */
-       marker = malloc(sizeof(marker[0]) * n);
-       if (marker == NULL)
-               return;
-       for (i = 0; i < n; i++)
-               marker[i] = i;
-
-       /*
-        * Iterate over acls in system acl object, try to match each
-        * one with an item in the myacls array.
-        */
-       for(e = 0; e < acl->acl_cnt; e++) {
-               aclent = &((aclent_t *)acl->acl_aclp)[e];
-
-               /* Search for a matching entry (tag and qualifier) */
-               for (i = 0, matched = 0; i < n && !matched; i++) {
-                       if (acl_match(aclent, &myacls[marker[i]])) {
-                               /* We found a match; remove it. */
-                               marker[i] = marker[n - 1];
-                               n--;
-                               matched = 1;
-                       }
-               }
-
-               /* TODO: Print out more details in this case. */
-               failure("ACL entry on file that shouldn't be there");
-               assert(matched == 1);
-       }
-
-       /* Dump entries in the myacls array that weren't in the system acl. */
-       for (i = 0; i < n; ++i) {
-               failure(" ACL entry missing from file: "
-                   "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n",
-                   myacls[marker[i]].type, myacls[marker[i]].permset,
-                   myacls[marker[i]].tag, myacls[marker[i]].qual,
-                   myacls[marker[i]].name);
-               assert(0); /* Record this as a failure. */
-       }
-       free(marker);
-}
-
-#endif
-
-
-/*
- * Verify ACL restore-to-disk.  This test is Solaris-specific.
- */
-
-DEFINE_TEST(test_acl_solaris_posix1e_restore)
-{
-#if !defined(__sun__)
-       skipping("Solaris-specific ACL restore test");
-#else
-       struct stat st;
-       struct archive *a;
-       struct archive_entry *ae;
-       int n, fd;
-       acl_t *acl;
-
-       /*
-        * First, do a quick manual set/read of ACL data to
-        * verify that the local filesystem does support ACLs.
-        * If it doesn't, we'll simply skip the remaining tests.
-        */
-       acl = NULL;
-
-       /* Create a test file and try to set an ACL on it. */
-       fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
-       failure("Could not create test file?!");
-       if (!assert(fd >= 0))
-               return;
-       n = facl_get(fd, 0, &acl);
-       if (n != 0)
-               close(fd);
-       if (n != 0 && errno == ENOSYS) {
-               skipping("ACL tests require ACL support on the filesystem");
-               return;
-       }
-       failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-
-       if (acl->acl_type != ACLENT_T) {
-               acl_free(acl);
-               close(fd);
-               skipping("Filesystem does not use POSIX.1e ACLs");
-               return;
-       }
-
-       acl_free(acl);
-
-       n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl);
-       if (n != 0)
-               close(fd);
-       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-
-       n = facl_set(fd, acl);
-       acl_free(acl);
-       if (n != 0 && errno == ENOSYS) {
-               close(fd);
-               skipping("ACL tests require ACL support on the filesystem");
-               return;
-       }
-       failure("facl_set(): errno = %d (%s)",
-           errno, strerror(errno));
-       assertEqualInt(0, n);
-       close(fd);
-
-       /* Create a write-to-disk object. */
-       assert(NULL != (a = archive_write_disk_new()));
-       archive_write_disk_set_options(a,
-           ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL);
-
-       /* Populate an archive entry with some metadata, including ACL info */
-       ae = archive_entry_new();
-       assert(ae != NULL);
-       archive_entry_set_pathname(ae, "test0");
-       archive_entry_set_mtime(ae, 123456, 7890);
-       archive_entry_set_size(ae, 0);
-       archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
-       assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
-       archive_entry_free(ae);
-
-       /* Close the archive. */
-       assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
-
-       /* Verify the data on disk. */
-       assertEqualInt(0, stat("test0", &st));
-       assertEqualInt(st.st_mtime, 123456);
-       n = acl_get("test0", 0, &acl);
-       failure("acl_get(): errno = %d (%s)",
-           errno, strerror(errno));
-       assert(n == 0);
-       if (acl->acl_type != ACLENT_T) {
-               acl_free(acl);
-               skipping("Filesystem uses other than POSIX.1e ACLs");
-               return;
-       }
-       assertEqualInt(ACLENT_T, acl->acl_type);
-       compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0]));
-       acl_free(acl);
-#endif
-}
-
-/*
- * Verify ACL read-from-disk.  This test is FreeBSD-specific.
- */
-DEFINE_TEST(test_acl_solaris_posix1e_read)
-{
-#if !defined(__sun__)
-       skipping("Solaris-specific ACL read test");
-#else
-       struct archive *a;
-       struct archive_entry *ae;
-       int n, fd;
-       const char *acl1_text, *acl2_text, *acl3_text;
-       acl_t *acl;
-
-       /*
-        * Manually construct a directory and two files with
-        * different ACLs.  This also serves to verify that ACLs
-        * are supported on the local filesystem.
-        */
-
-       /* Create a test file f1 with acl1_text */
-       fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
-       failure("Could not create test file?!");
-       if (!assert(fd >= 0))
-               return;
-       n = facl_get(fd, 0, &acl);
-       if (n != 0)
-               close(fd);
-       if (n != 0 && errno == ENOSYS) {
-               skipping("ACL tests require ACL support on the filesystem");
-               return;
-       }
-       failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-
-       if (acl->acl_type != ACLENT_T) {
-               acl_free(acl);
-               close(fd);
-               skipping("Filesystem does not use POSIX.1e ACLs");
-               return;
-       }
-
-       acl_free(acl);
-
-       acl1_text = "user::rwx,"
-           "group::rwx,"
-           "other:rwx,"
-           "user:1:rw-,"
-           "group:15:r-x,"
-           "mask:rwx";
-       n = acl_fromtext(acl1_text, &acl);
-       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-
-       n = facl_set(fd, acl);
-       acl_free(acl);
-       if (n != 0 && errno == ENOSYS) {
-               close(fd);
-               skipping("ACL tests require ACL support on the filesystem");
-               return;
-       }
-       failure("facl_set(): errno = %d (%s)",
-           errno, strerror(errno));
-       assertEqualInt(0, n);
-       close(fd);
-
-       assertMakeDir("d1", 0700);
-
-       /*
-        * Create file d/f1 with acl2_text
-        *
-        * This differs from acl1_text in the u:1: and g:15: permissions.
-        *
-        * This file deliberately has the same name but a different ACL.
-        * Github Issue #777 explains how libarchive's directory traversal
-        * did not always correctly enter directories before attempting
-        * to read ACLs, resulting in reading the ACL from a like-named
-        * file in the wrong directory.
-        */
-       acl2_text = "user::rwx,"
-           "group::rwx,"
-           "other:---,"
-           "user:1:r--,"
-           "group:15:r--,"
-           "mask:rwx";
-       n = acl_fromtext(acl2_text, &acl);
-       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-
-       fd = open("d1/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
-       failure("Could not create test file?!");
-       if (!assert(fd >= 0)) {
-               acl_free(acl);
-               return;
-       }
-       n = facl_set(fd, acl);
-       acl_free(acl);
-       if (n != 0 && errno == ENOSYS) {
-               close(fd);
-               skipping("ACL tests require ACL support on the filesystem");
-               return;
-       }
-       failure("facl_set(): errno = %d (%s)",
-           errno, strerror(errno));
-       assertEqualInt(0, n);
-       close(fd);
-
-       /* Create directory d2 with access and default ACLs */
-       assertMakeDir("d2", 0755);
-
-       acl3_text = "user::rwx,"
-           "group::r-x,"
-           "other:r-x,"
-           "user:2:r--,"
-           "group:16:-w-,"
-           "mask:rwx,"
-           "default:user::rwx,"
-            "default:user:1:r--,"
-           "default:group::r-x,"
-           "default:group:15:r--,"
-           "default:mask:rwx,"
-           "default:other:r-x";
-
-       n = acl_fromtext(acl3_text, &acl);
-       failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
-       assertEqualInt(0, n);
-
-       n = acl_set("d2", acl);
-       acl_free(acl);
-       if (n != 0 && errno == ENOSYS) {
-               close(fd);
-               skipping("ACL tests require ACL support on the filesystem");
-               return;
-       }
-       failure("acl_set(): errno = %d (%s)",
-           errno, strerror(errno));
-       assertEqualInt(0, n);
-
-       /* Create a read-from-disk object. */
-       assert(NULL != (a = archive_read_disk_new()));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
-       assert(NULL != (ae = archive_entry_new()));
-
-       /* Walk the dir until we see both of the files */
-       while (ARCHIVE_OK == archive_read_next_header2(a, ae)) {
-               archive_read_disk_descend(a);
-               if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
-                       assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_POSIX1E | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS), acl1_text);
-               } else if (strcmp(archive_entry_pathname(ae), "./d1/f1") == 0) {
-                       assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_POSIX1E | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS), acl2_text);
-               } else if (strcmp(archive_entry_pathname(ae), "./d2") == 0) {
-                       assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_POSIX1E | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS), acl3_text);
-               }
-       }
-
-       archive_free(a);
-#endif
-}