summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuska <martin@matuska.org>2017-03-02 14:19:38 +0100
committerMartin Matuska <martin@matuska.org>2017-03-02 16:10:26 +0100
commitf5d473ed0b708f59f34c702891792efc9bb0817f (patch)
treec209007a2c49fd08ee93f7cc8bd40cb7501ed6a5
parent60f0931d3b97e00616d7122321e34116d926bcc5 (diff)
downloadlibarchive-f5d473ed0b708f59f34c702891792efc9bb0817f.tar.gz
New tar test: test_option_acls
Add sunacl_get() and setTestAcl() to common test code Test for membership.h on Mac OS X and make it a requirement for ACLs
-rw-r--r--CMakeLists.txt1
-rw-r--r--Makefile.am1
-rw-r--r--build/cmake/config.h.in3
-rw-r--r--cat/test/CMakeLists.txt5
-rw-r--r--configure.ac1
-rw-r--r--cpio/test/CMakeLists.txt5
-rw-r--r--libarchive/archive_platform.h2
-rw-r--r--libarchive/test/test_acl_platform_nfs4.c143
-rw-r--r--libarchive/test/test_acl_platform_posix1e.c130
-rw-r--r--tar/test/CMakeLists.txt6
-rw-r--r--tar/test/test_option_acls.c471
-rw-r--r--test_utils/test_common.h17
-rw-r--r--test_utils/test_main.c235
13 files changed, 753 insertions, 267 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5bcff485..bddf30c7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -579,6 +579,7 @@ int main(void) { return FS_IOC_GETFLAGS; }" HAVE_WORKING_FS_IOC_GETFLAGS)
LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
+LA_CHECK_INCLUDE_FILE("membership.h" HAVE_MEMBERSHIP_H)
LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H)
LA_CHECK_INCLUDE_FILE("paths.h" HAVE_PATHS_H)
LA_CHECK_INCLUDE_FILE("poll.h" HAVE_POLL_H)
diff --git a/Makefile.am b/Makefile.am
index 600e1ff4..b5a41f98 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -951,6 +951,7 @@ bsdtar_test_SOURCES= \
tar/test/test_option_T_upper.c \
tar/test/test_option_U_upper.c \
tar/test/test_option_X_upper.c \
+ tar/test/test_option_acls.c \
tar/test/test_option_a.c \
tar/test/test_option_b.c \
tar/test/test_option_b64encode.c \
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index fd4fbdcd..8c18edf8 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -773,6 +773,9 @@ typedef uint64_t uintmax_t;
/* Define to 1 if you have the `mbrtowc' function. */
#cmakedefine HAVE_MBRTOWC 1
+/* Define to 1 if you have the <membership.h> header file. */
+#cmakedefine HAVE_MEMBERSHIP_H 1
+
/* Define to 1 if you have the `memmove' function. */
#cmakedefine HAVE_MEMMOVE 1
diff --git a/cat/test/CMakeLists.txt b/cat/test/CMakeLists.txt
index 7f1ce5e7..0623cc36 100644
--- a/cat/test/CMakeLists.txt
+++ b/cat/test/CMakeLists.txt
@@ -29,6 +29,11 @@ IF(ENABLE_CAT AND ENABLE_TEST)
# Register target
#
ADD_EXECUTABLE(bsdcat_test ${bsdcat_test_SOURCES})
+ IF(ENABLE_ACL)
+ IF(HAVE_LIBACL)
+ TARGET_LINK_LIBRARIES(bsdcat_test ${ACL_LIBRARY})
+ ENDIF(HAVE_LIBACL)
+ ENDIF(ENABLE_ACL)
SET_PROPERTY(TARGET bsdcat_test PROPERTY COMPILE_DEFINITIONS LIST_H)
#
diff --git a/configure.ac b/configure.ac
index b9f7f53d..0592279d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -699,6 +699,7 @@ AC_ARG_ENABLE([acl],
if test "x$enable_acl" != "xno"; then
AC_CHECK_HEADERS([acl/libacl.h])
AC_CHECK_HEADERS([sys/acl.h])
+ AC_CHECK_HEADERS([membership.h])
AC_CHECK_LIB([acl],[acl_get_file])
AC_CHECK_FUNCS([acl_create_entry acl_get_fd_np])
AC_CHECK_FUNCS([acl_init acl_set_fd acl_set_fd_np acl_set_file])
diff --git a/cpio/test/CMakeLists.txt b/cpio/test/CMakeLists.txt
index ec9509be..cc5fe011 100644
--- a/cpio/test/CMakeLists.txt
+++ b/cpio/test/CMakeLists.txt
@@ -62,6 +62,11 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
# Register target
#
ADD_EXECUTABLE(bsdcpio_test ${bsdcpio_test_SOURCES})
+ IF(ENABLE_ACL)
+ IF(HAVE_LIBACL)
+ TARGET_LINK_LIBRARIES(bsdcpio_test ${ACL_LIBRARY})
+ ENDIF(HAVE_LIBACL)
+ ENDIF(ENABLE_ACL)
SET_PROPERTY(TARGET bsdcpio_test PROPERTY COMPILE_DEFINITIONS LIST_H)
#
diff --git a/libarchive/archive_platform.h b/libarchive/archive_platform.h
index 128f0e08..01d6a70d 100644
--- a/libarchive/archive_platform.h
+++ b/libarchive/archive_platform.h
@@ -150,7 +150,7 @@
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
#if HAVE_DECL_ACL_USER
#define HAVE_POSIX_ACL 1
-#elif HAVE_DECL_ACL_TYPE_EXTENDED
+#elif HAVE_DECL_ACL_TYPE_EXTENDED && HAVE_MEMBERSHIP_H
#define HAVE_DARWIN_ACL 1
#endif
#if HAVE_DECL_ACL_TYPE_NFS4
diff --git a/libarchive/test/test_acl_platform_nfs4.c b/libarchive/test/test_acl_platform_nfs4.c
index 5783e523..c8854082 100644
--- a/libarchive/test/test_acl_platform_nfs4.c
+++ b/libarchive/test/test_acl_platform_nfs4.c
@@ -248,63 +248,6 @@ static struct myacl_t acls_dir[] = {
static const int acls_dir_cnt = (int)(sizeof(acls_dir)/sizeof(acls_dir[0]));
-#if HAVE_SUN_ACL
-static void *
-sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
-{
- int cnt, cntcmd;
- size_t size;
- void *aclp;
-
- if (cmd == GETACL) {
- cntcmd = GETACLCNT;
- size = sizeof(aclent_t);
- }
-#if HAVE_SUN_NFS4_ACL
- else if (cmd == ACE_GETACL) {
- cntcmd = ACE_GETACLCNT;
- size = sizeof(ace_t);
- }
-#endif
- else {
- errno = EINVAL;
- *aclcnt = -1;
- return (NULL);
- }
-
- aclp = NULL;
- cnt = -2;
- while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
- if (path != NULL)
- cnt = acl(path, cntcmd, 0, NULL);
- else
- cnt = facl(fd, cntcmd, 0, NULL);
-
- if (cnt > 0) {
- if (aclp == NULL)
- aclp = malloc(cnt * size);
- else
- aclp = realloc(NULL, cnt * size);
- if (aclp != NULL) {
- if (path != NULL)
- cnt = acl(path, cmd, cnt, aclp);
- else
- cnt = facl(fd, cmd, cnt, aclp);
- }
- } else {
- if (aclp != NULL) {
- free(aclp);
- aclp = NULL;
- }
- break;
- }
- }
-
- *aclcnt = cnt;
- return (aclp);
-}
-#endif /* HAVE_SUN_ACL */
-
static void
set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
{
@@ -777,11 +720,10 @@ DEFINE_TEST(test_acl_platform_nfs4)
skipping("NFS4 ACLs are not supported on this platform");
#else
char buff[64];
+ int i;
struct stat st;
struct archive *a;
struct archive_entry *ae;
- int i;
- char *func;
#if HAVE_DARWIN_ACL /* On MacOS we skip trivial ACLs in some tests */
const int regcnt = acls_reg_cnt - 4;
const int dircnt = acls_dir_cnt - 4;
@@ -793,92 +735,15 @@ DEFINE_TEST(test_acl_platform_nfs4)
void *aclp;
int aclcnt;
#else /* !HAVE_SUN_NFS4_ACL */
-#if HAVE_DARWIN_ACL
- acl_entry_t aclent;
- acl_permset_t permset;
- const uid_t uid = 1000;
- uuid_t uuid;
-#endif /* HAVE_DARWIN_ACL */
- int n;
acl_t acl;
-#endif /* !HAVE_SUN_NFS4_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.
- */
-#if HAVE_FREEBSD_NFS4_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);
-#elif HAVE_DARWIN_ACL
- acl = acl_init(1);
- assert((void *)acl != NULL);
- assertEqualInt(0, acl_create_entry(&acl, &aclent));
- assertEqualInt(0, acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW));
- assertEqualInt(0, acl_get_permset(aclent, &permset));
- assertEqualInt(0, acl_add_perm(permset, ACL_READ_DATA));
- assertEqualInt(0, acl_add_perm(permset, ACL_WRITE_DATA));
- assertEqualInt(0, acl_add_perm(permset, ACL_APPEND_DATA));
- assertEqualInt(0, acl_add_perm(permset, ACL_EXECUTE));
- assertEqualInt(0, acl_set_permset(aclent, permset));
- assertEqualInt(0, mbr_identifier_to_uuid(ID_TYPE_UID, &uid,
- sizeof(uid_t), uuid));
- assertEqualInt(0, acl_set_qualifier(aclent, uuid));
#endif
- /* Create a test dir and try to set an ACL on it. */
- if (!assertMakeDir("pretest", 0755)) {
-#if !HAVE_SUN_NFS4_ACL
- acl_free(acl);
-#endif
- return;
- }
+ assertMakeFile("pretest", 0644, "a");
-#if HAVE_SUN_NFS4_ACL
- func = "acl()";
- aclp = sunacl_get(GETACL, &aclcnt, 0, "pretest");
- if (aclp != NULL) {
- skipping("NFS4 ACL is not supported on this filesystem");
- free(aclp);
+ if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) {
+ skipping("NFS4 ACLs are not writable on this filesystem");
return;
}
- free(aclp);
- aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "pretest");
-#else
- func = "acl_set_file()";
-#if HAVE_DARWIN_ACL
- n = acl_set_file("pretest", ACL_TYPE_EXTENDED, acl);
-#else
- n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
-#endif
- acl_free(acl);
-#endif
-#if HAVE_SUN_NFS4_ACL
- if (aclp == NULL)
-#else
- if (n != 0)
-#endif
- {
-#if HAVE_SUN_NFS4_ACL
- if (errno == ENOSYS || errno == ENOTSUP)
-#else
- if (errno == EOPNOTSUPP || errno == EINVAL)
-#endif
- {
- skipping("NFS4 ACL is not supported on this filesystem");
- return;
- }
- }
- failure("%s: errno = %d (%s)", func, errno, strerror(errno));
-#if HAVE_SUN_NFS4_ACL
- assert(aclp != NULL);
- free(aclp);
- aclp = NULL;
-#else
- assertEqualInt(0, n);
-#endif
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
diff --git a/libarchive/test/test_acl_platform_posix1e.c b/libarchive/test/test_acl_platform_posix1e.c
index a0da2273..0224a57f 100644
--- a/libarchive/test/test_acl_platform_posix1e.c
+++ b/libarchive/test/test_acl_platform_posix1e.c
@@ -35,63 +35,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-0
#define ACL_GET_PERM acl_get_perm_np
#endif
-#if HAVE_SUN_ACL
-static void *
-sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
-{
- int cnt, cntcmd;
- size_t size;
- void *aclp;
-
- if (cmd == GETACL) {
- cntcmd = GETACLCNT;
- size = sizeof(aclent_t);
- }
-#if HAVE_SUN_NFS4_ACL
- else if (cmd == ACE_GETACL) {
- cntcmd = ACE_GETACLCNT;
- size = sizeof(ace_t);
- }
-#endif
- else {
- errno = EINVAL;
- *aclcnt = -1;
- return (NULL);
- }
-
- aclp = NULL;
- cnt = -2;
- while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
- if (path != NULL)
- cnt = acl(path, cntcmd, 0, NULL);
- else
- cnt = facl(fd, cntcmd, 0, NULL);
-
- if (cnt > 0) {
- if (aclp == NULL)
- aclp = malloc(cnt * size);
- else
- aclp = realloc(NULL, cnt * size);
- if (aclp != NULL) {
- if (path != NULL)
- cnt = acl(path, cmd, cnt, aclp);
- else
- cnt = facl(fd, cmd, cnt, aclp);
- }
- } else {
- if (aclp != NULL) {
- free(aclp);
- aclp = NULL;
- }
- break;
- }
- }
-
- *aclcnt = cnt;
- return (aclp);
-}
-#endif /* HAVE_SUN_ACL */
-
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, "" },
@@ -361,8 +304,6 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
struct stat st;
struct archive *a;
struct archive_entry *ae;
- int n, fd;
- char *func;
#if HAVE_SUN_ACL
void *aclp;
int aclcnt;
@@ -370,77 +311,12 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
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
- aclent_t aclp1[] = {
- { USER_OBJ, -1, 4 | 2 | 1 },
- { USER, 1, 4 | 2 },
- { GROUP_OBJ, -1, 4 | 2 | 1 },
- { GROUP, 15, 4 | 1 },
- { CLASS_OBJ, -1, 4 | 2 | 1 },
- { OTHER_OBJ, -1, 4 | 2 | 1 }
- };
-#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);
-#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)) {
-#if !HAVE_SUN_ACL
- acl_free(acl);
-#endif
- return;
- }
+ assertMakeFile("pretest", 0644, "a");
-#if HAVE_SUN_ACL
- aclp = sunacl_get(GETACL, &aclcnt, fd, NULL);
- if (aclp == NULL)
- close(fd);
- if (errno == ENOSYS || errno == ENOTSUP) {
- skipping("POSIX.1e ACLs are not supported on this filesystem");
- return;
- }
- failure("facl(): errno = %d (%s)", errno, strerror(errno));
- if (assert(aclp != NULL) == 0) {
- free(aclp);
+ if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_POSIX1E) {
+ skipping("POSIX.1e ACLs are not writable on this filesystem");
return;
}
- free(aclp);
- aclp = NULL;
-
- func = "facl()";
- n = facl(fd, SETACL, (int)(sizeof(aclp1)/sizeof(aclp1[0])), &aclp1);
-#else
- func = "acl_set_fd()";
- n = acl_set_fd(fd, acl);
-#endif
-#if !HAVE_SUN_ACL
- acl_free(acl);
-#endif
- if (n != 0) {
-#if HAVE_SUN_ACL
- if (errno == ENOSYS || errno == ENOTSUP)
-#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);
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
diff --git a/tar/test/CMakeLists.txt b/tar/test/CMakeLists.txt
index 9115d6f6..e6054bab 100644
--- a/tar/test/CMakeLists.txt
+++ b/tar/test/CMakeLists.txt
@@ -34,6 +34,7 @@ IF(ENABLE_TAR AND ENABLE_TEST)
test_option_U_upper.c
test_option_X_upper.c
test_option_a.c
+ test_option_acls.c
test_option_b.c
test_option_b64encode.c
test_option_exclude.c
@@ -72,6 +73,11 @@ IF(ENABLE_TAR AND ENABLE_TEST)
# Register target
#
ADD_EXECUTABLE(bsdtar_test ${bsdtar_test_SOURCES})
+ IF(ENABLE_ACL)
+ IF(HAVE_LIBACL)
+ TARGET_LINK_LIBRARIES(bsdtar_test ${ACL_LIBRARY})
+ ENDIF(HAVE_LIBACL)
+ ENDIF(ENABLE_ACL)
SET_PROPERTY(TARGET bsdtar_test PROPERTY COMPILE_DEFINITIONS LIST_H)
#
diff --git a/tar/test/test_option_acls.c b/tar/test/test_option_acls.c
new file mode 100644
index 00000000..5c3fbfd1
--- /dev/null
+++ b/tar/test/test_option_acls.c
@@ -0,0 +1,471 @@
+/*-
+ * 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"
+__FBSDID("$FreeBSD$");
+
+#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
+static const acl_perm_t acl_perms[] = {
+#if HAVE_DARWIN_ACL
+ ACL_READ_DATA,
+ ACL_LIST_DIRECTORY,
+ ACL_WRITE_DATA,
+ ACL_ADD_FILE,
+ ACL_EXECUTE,
+ ACL_SEARCH,
+ ACL_DELETE,
+ ACL_APPEND_DATA,
+ ACL_ADD_SUBDIRECTORY,
+ ACL_DELETE_CHILD,
+ ACL_READ_ATTRIBUTES,
+ ACL_WRITE_ATTRIBUTES,
+ ACL_READ_EXTATTRIBUTES,
+ ACL_WRITE_EXTATTRIBUTES,
+ ACL_READ_SECURITY,
+ ACL_WRITE_SECURITY,
+ ACL_CHANGE_OWNER,
+ ACL_SYNCHRONIZE
+#else /* !HAVE_DARWIN_ACL */
+ ACL_EXECUTE,
+ ACL_WRITE,
+ ACL_READ,
+#if HAVE_FREEBSD_NFS4_ACL
+ ACL_READ_DATA,
+ ACL_LIST_DIRECTORY,
+ ACL_WRITE_DATA,
+ ACL_ADD_FILE,
+ ACL_APPEND_DATA,
+ ACL_ADD_SUBDIRECTORY,
+ ACL_READ_NAMED_ATTRS,
+ ACL_WRITE_NAMED_ATTRS,
+ ACL_DELETE_CHILD,
+ ACL_READ_ATTRIBUTES,
+ ACL_WRITE_ATTRIBUTES,
+ ACL_DELETE,
+ ACL_READ_ACL,
+ ACL_WRITE_ACL,
+ ACL_WRITE_OWNER,
+ ACL_SYNCHRONIZE
+#endif /* HAVE_FREEBSD_NFS4_ACL */
+#endif /* !HAVE_DARWIN_ACL */
+};
+#if HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL
+static const acl_flag_t acl_flags[] = {
+#if HAVE_DARWIN_ACL
+ ACL_FLAG_DEFER_INHERIT,
+ ACL_FLAG_NO_INHERIT,
+ ACL_ENTRY_INHERITED,
+ ACL_ENTRY_FILE_INHERIT,
+ ACL_ENTRY_DIRECTORY_INHERIT,
+ ACL_ENTRY_LIMIT_INHERIT,
+ ACL_ENTRY_ONLY_INHERIT
+#else /* HAVE_FREEBSD_NFS4_ACL */
+ ACL_ENTRY_FILE_INHERIT,
+ ACL_ENTRY_DIRECTORY_INHERIT,
+ ACL_ENTRY_NO_PROPAGATE_INHERIT,
+ ACL_ENTRY_INHERIT_ONLY,
+ ACL_ENTRY_SUCCESSFUL_ACCESS,
+ ACL_ENTRY_FAILED_ACCESS,
+ ACL_ENTRY_INHERITED
+#endif /* HAVE_FREEBSD_NFS4_ACL */
+};
+#endif /* HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL */
+
+/*
+ * Compare two ACL entries on FreeBSD or on Mac OS X
+ */
+static int
+compare_acl_entry(acl_entry_t ae_a, acl_entry_t ae_b, int is_nfs4)
+{
+ acl_tag_t tag_a, tag_b;
+ acl_permset_t permset_a, permset_b;
+ int perm_a, perm_b, perm_start, perm_end;
+ void *qual_a, *qual_b;
+#if HAVE_FREEBSD_NFS4_ACL
+ acl_entry_type_t type_a, type_b;
+#endif
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
+ acl_flagset_t flagset_a, flagset_b;
+ int flag_a, flag_b;
+#endif
+ int i, r;
+
+
+ /* Compare ACL tag */
+ r = acl_get_tag_type(ae_a, &tag_a);
+ failure("acl_get_tag_type() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ r = acl_get_tag_type(ae_b, &tag_b);
+ failure("acl_get_tag_type() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ if (tag_a != tag_b)
+ return (0);
+
+ /* Compare ACL qualifier */
+#if HAVE_DARWIN_ACL
+ if (tag_a == ACL_EXTENDED_ALLOW || tag_b == ACL_EXTENDED_DENY)
+#else
+ if (tag_a == ACL_USER || tag_a == ACL_GROUP)
+#endif
+ {
+ qual_a = acl_get_qualifier(ae_a);
+ failure("acl_get_qualifier() error: %s", strerror(errno));
+ if (assert(qual_a != NULL) == 0)
+ return (-1);
+ qual_b = acl_get_qualifier(ae_b);
+ failure("acl_get_qualifier() error: %s", strerror(errno));
+ if (assert(qual_b != NULL) == 0) {
+ acl_free(qual_a);
+ return (-1);
+ }
+#if HAVE_DARWIN_ACL
+ if (memcmp(((guid_t *)qual_a)->g_guid,
+ ((guid_t *)qual_b)->g_guid, KAUTH_GUID_SIZE) != 0)
+#else
+ if ((tag_a == ACL_USER &&
+ (*(uid_t *)qual_a != *(uid_t *)qual_b)) ||
+ (tag_a == ACL_GROUP &&
+ (*(gid_t *)qual_a != *(gid_t *)qual_b)))
+#endif
+ {
+ acl_free(qual_a);
+ acl_free(qual_b);
+ return (0);
+ }
+ acl_free(qual_a);
+ acl_free(qual_b);
+ }
+
+#if HAVE_FREEBSD_NFS4_ACL
+ if (is_nfs4) {
+ /* Compare NFS4 ACL type */
+ r = acl_get_entry_type_np(ae_a, &type_a);
+ failure("acl_get_entry_type_np() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ r = acl_get_entry_type_np(ae_b, &type_b);
+ failure("acl_get_entry_type_np() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ if (type_a != type_b)
+ return (0);
+ }
+#endif
+
+ /* Compare ACL perms */
+ r = acl_get_permset(ae_a, &permset_a);
+ failure("acl_get_permset() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ r = acl_get_permset(ae_b, &permset_b);
+ failure("acl_get_permset() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+
+ perm_start = 0;
+ perm_end = (int)(sizeof(acl_perms) / sizeof(acl_perms[0]));
+#if HAVE_FREEBSD_NFS4_ACL
+ if (is_nfs4)
+ perm_start = 3;
+ else
+ perm_end = 3;
+#endif
+ /* Cycle through all perms and compare their value */
+ for (i = perm_start; i < perm_end; i++) {
+#if HAVE_LIBACL
+ perm_a = acl_get_perm(permset_a, acl_perms[i]);
+ perm_b = acl_get_perm(permset_b, acl_perms[i]);
+#else
+ perm_a = acl_get_perm_np(permset_a, acl_perms[i]);
+ perm_b = acl_get_perm_np(permset_b, acl_perms[i]);
+#endif
+ if (perm_a == -1 || perm_b == -1)
+ return (-1);
+ if (perm_a != perm_b)
+ return (0);
+ }
+
+#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
+ if (is_nfs4) {
+ r = acl_get_flagset_np(ae_a, &flagset_a);
+ failure("acl_get_flagset_np() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ r = acl_get_flagset_np(ae_b, &flagset_b);
+ failure("acl_get_flagset_np() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ return (-1);
+ /* Cycle through all flags and compare their status */
+ for (i = 0; i < (int)(sizeof(acl_flags) / sizeof(acl_flags[0]));
+ i++) {
+ flag_a = acl_get_flag_np(flagset_a, acl_flags[i]);
+ flag_b = acl_get_flag_np(flagset_b, acl_flags[i]);
+ if (flag_a == -1 || flag_b == -1)
+ return (-1);
+ if (flag_a != flag_b)
+ return (0);
+ }
+ }
+#else /* HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL*/
+ (void)is_nfs4; /* UNUSED */
+#endif
+ return (1);
+}
+#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
+
+#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL
+/*
+ * Clear default ACLs or inheritance flags
+ */
+static void
+clear_inheritance_flags(const char *path, int type)
+{
+ switch (type) {
+ case ARCHIVE_TEST_ACL_TYPE_POSIX1E:
+#if HAVE_POSIX_ACL
+ acl_delete_def_file(path);
+#else
+ /* Solaris */
+ setTestAcl(path);
+#endif
+ break;
+ case ARCHIVE_TEST_ACL_TYPE_NFS4:
+#if HAVE_NFS4_ACL
+ setTestAcl(path);
+#endif
+ break;
+ default:
+ (void)path; /* UNUSED */
+ break;
+ }
+}
+
+static int
+compare_acls(const char *path_a, const char *path_b)
+{
+ int ret = 1;
+ int is_nfs4 = 0;
+#if HAVE_SUN_ACL
+ void *acl_a, *acl_b;
+ int aclcnt_a, aclcnt_b;
+ aclent_t *aclent_a, *aclent_b;
+ ace_t *ace_a, *ace_b;
+ int e;
+#else
+ acl_t acl_a, acl_b;
+ acl_entry_t aclent_a, aclent_b;
+ int a, b, r;
+#endif
+
+ acl_a = NULL;
+ acl_b = NULL;
+#if HAVE_SUN_ACL
+ acl_a = sunacl_get(GETACL, &aclcnt_a, 0, path_a);
+ if (acl_a == NULL) {
+#if HAVE_SUN_NFS4_ACL
+ is_nfs4 = 1;
+ acl_a = sunacl_get(ACE_GETACL, &aclcnt_a, 0, path_a);
+#endif
+ failure("acl_get() error: %s", strerror(errno));
+ if (assert(acl_a != NULL) == 0)
+ return (-1);
+#if HAVE_SUN_NFS4_ACL
+ acl_b = sunacl_get(ACE_GETACL, &aclcnt_b, 0, path_b);
+#endif
+ } else
+ acl_b = sunacl_get(GETACL, &aclcnt_b, 0, path_b);
+ if (acl_b == NULL && (errno == ENOSYS || errno == ENOTSUP)) {
+ free(acl_a);
+ return (0);
+ }
+ failure("acl_get() error: %s", strerror(errno));
+ if (assert(acl_b != NULL) == 0) {
+ free(acl_a);
+ return (-1);
+ }
+
+ if (aclcnt_a != aclcnt_b) {
+ ret = 0;
+ goto exit_free;
+ }
+
+ for (e = 0; e < aclcnt_a; e++) {
+ if (!is_nfs4) {
+ aclent_a = &((aclent_t *)acl_a)[e];
+ aclent_b = &((aclent_t *)acl_b)[e];
+ if (aclent_a->a_type != aclent_b->a_type ||
+ aclent_a->a_id != aclent_b->a_id ||
+ aclent_a->a_perm != aclent_b->a_perm) {
+ ret = 0;
+ goto exit_free;
+ }
+ }
+#if HAVE_SUN_NFS4_ACL
+ else {
+ ace_a = &((ace_t *)acl_a)[e];
+ ace_b = &((ace_t *)acl_b)[e];
+ if (ace_a->a_who != ace_b->a_who ||
+ ace_a->a_access_mask != ace_b->a_access_mask ||
+ ace_a->a_flags != ace_b->a_flags ||
+ ace_a->a_type != ace_b->a_type) {
+ ret = 0;
+ goto exit_free;
+ }
+ }
+#endif
+ }
+#else /* !HAVE_SUN_ACL */
+#if HAVE_DARWIN_ACL
+ is_nfs4 = 1;
+ acl_a = acl_get_file(path_a, ACL_TYPE_EXTENDED);
+#elif HAVE_FREEBSD_NFS4_ACL
+ acl_a = acl_get_file(path_a, ACL_TYPE_NFS4);
+ if (acl_a != NULL)
+ is_nfs4 = 1;
+#endif
+#if !HAVE_DARWIN_ACL
+ if (acl_a == NULL)
+ acl_a = acl_get_file(path_a, ACL_TYPE_ACCESS);
+#endif
+ failure("acl_get_file() error: %s (%s)", path_a, strerror(errno));
+ if (assert(acl_a != NULL) == 0)
+ return (-1);
+#if HAVE_DARWIN_ACL
+ acl_b = acl_get_file(path_b, ACL_TYPE_EXTENDED);
+#elif HAVE_FREEBSD_NFS4_ACL
+ acl_b = acl_get_file(path_b, ACL_TYPE_NFS4);
+#endif
+#if !HAVE_DARWIN_ACL
+ if (acl_b == NULL) {
+#if HAVE_FREEBSD_NFS4_ACL
+ if (is_nfs4) {
+ acl_free(acl_a);
+ return (0);
+ }
+#endif
+ acl_b = acl_get_file(path_b, ACL_TYPE_ACCESS);
+ }
+ failure("acl_get_file() error: %s (%s)", path_b, strerror(errno));
+ if (assert(acl_b != NULL) == 0) {
+ acl_free(acl_a);
+ return (-1);
+ }
+#endif
+ a = acl_get_entry(acl_a, ACL_FIRST_ENTRY, &aclent_a);
+ if (a == -1) {
+ ret = 0;
+ goto exit_free;
+ }
+ b = acl_get_entry(acl_b, ACL_FIRST_ENTRY, &aclent_b);
+ if (b == -1) {
+ ret = 0;
+ goto exit_free;
+ }
+#if HAVE_DARWIN_ACL
+ while (a == 0 && b == 0)
+#else /* FreeBSD, Linux */
+ while (a == 1 && b == 1)
+#endif
+ {
+ r = compare_acl_entry(aclent_a, aclent_b, is_nfs4);
+ if (r != 1) {
+ ret = r;
+ goto exit_free;
+ }
+ a = acl_get_entry(acl_a, ACL_NEXT_ENTRY, &aclent_a);
+ b = acl_get_entry(acl_b, ACL_NEXT_ENTRY, &aclent_b);
+ }
+ /* Entry count must match */
+ if (a != b)
+ ret = 0;
+#endif /* !HAVE_SUN_ACL */
+exit_free:
+#if HAVE_SUN_ACL
+ free(acl_a);
+ free(acl_b);
+#else
+ acl_free(acl_a);
+ acl_free(acl_b);
+#endif
+ return (ret);
+}
+#endif /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
+
+DEFINE_TEST(test_option_acls)
+{
+#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_POSIX_ACL
+ skipping("ACLs are not supported on this platform");
+#else /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
+ int acltype, r;
+
+ assertMakeFile("f", 0644, "a");
+ acltype = setTestAcl("f");
+ if (acltype == 0) {
+ skipping("Can't write ACLs on the filesystem");
+ return;
+ }
+
+ /* Archive it with acls */
+ r = systemf("%s -c --no-mac-metadata --acls -f acls.tar f >acls.out 2>acls.err", testprog);
+ assertEqualInt(r, 0);
+
+ /* Archive it without acls */
+ r = systemf("%s -c --no-mac-metadata --no-acls -f noacls.tar f >noacls.out 2>noacls.err", testprog);
+ assertEqualInt(r, 0);
+
+ /* Extract acls with acls */
+ assertMakeDir("acls_acls", 0755);
+ clear_inheritance_flags("acls_acls", acltype);
+ r = systemf("%s -x -C acls_acls --no-same-permissions --acls -f acls.tar >acls_acls.out 2>acls_acls.err", testprog);
+ assertEqualInt(r, 0);
+ r = compare_acls("f", "acls_acls/f");
+ assertEqualInt(r, 1);
+
+ /* Extractl acls without acls */
+ assertMakeDir("acls_noacls", 0755);
+ clear_inheritance_flags("acls_noacls", acltype);
+ r = systemf("%s -x -C acls_noacls -p --no-acls -f acls.tar >acls_noacls.out 2>acls_noacls.err", testprog);
+ assertEqualInt(r, 0);
+ r = compare_acls("f", "acls_noacls/f");
+ assertEqualInt(r, 0);
+
+ /* Extract noacls with acls flag */
+ assertMakeDir("noacls_acls", 0755);
+ clear_inheritance_flags("noacls_acls", acltype);
+ r = systemf("%s -x -C noacls_acls --no-same-permissions --acls -f noacls.tar >noacls_acls.out 2>noacls_acls.err", testprog);
+ assertEqualInt(r, 0);
+ r = compare_acls("f", "noacls_acls/f");
+ assertEqualInt(r, 0);
+
+ /* Extract noacls with noacls */
+ assertMakeDir("noacls_noacls", 0755);
+ clear_inheritance_flags("noacls_noacls", acltype);
+ r = systemf("%s -x -C noacls_noacls -p --no-acls -f noacls.tar >noacls_noacls.out 2>noacls_noacls.err", testprog);
+ assertEqualInt(r, 0);
+ r = compare_acls("f", "noacls_noacls/f");
+ assertEqualInt(r, 0);
+#endif /* HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_POSIX_ACL */
+}
diff --git a/test_utils/test_common.h b/test_utils/test_common.h
index 1e5c1fec..00780541 100644
--- a/test_utils/test_common.h
+++ b/test_utils/test_common.h
@@ -73,6 +73,12 @@
#include <unistd.h>
#endif
#include <wchar.h>
+#ifdef HAVE_ACL_LIBACL_H
+#include <acl/libacl.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
@@ -155,6 +161,9 @@
#define HAVE_NFS4_ACL 1
#endif
+#define ARCHIVE_TEST_ACL_TYPE_POSIX1E 1
+#define ARCHIVE_TEST_ACL_TYPE_NFS4 2
+
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/
@@ -363,9 +372,17 @@ int canXz(void);
/* Return true if this filesystem can handle nodump flags. */
int canNodump(void);
+/* Set test ACLs */
+int setTestAcl(const char *path);
+
/* Return true if the file has large i-node number(>0xffffffff). */
int is_LargeInode(const char *);
+#if HAVE_SUN_ACL
+/* Fetch ACLs on Solaris using acl() or facl() */
+void *sunacl_get(int cmd, int *aclcnt, int fd, const char *path);
+#endif
+
/* Suck file into string allocated via malloc(). Call free() when done. */
/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */
char *slurpfile(size_t *, const char *fmt, ...);
diff --git a/test_utils/test_main.c b/test_utils/test_main.c
index ec2fbfed..86ab5f1a 100644
--- a/test_utils/test_main.c
+++ b/test_utils/test_main.c
@@ -56,6 +56,20 @@
#include <stdarg.h>
#include <time.h>
+/* ACL support */
+#ifdef HAVE_ACL_LIBACL_H
+#include <acl/libacl.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif
+#if HAVE_DARWIN_ACL
+#include <membership.h>
+#endif
+
/*
*
* Windows support routines
@@ -2422,6 +2436,227 @@ canNodump(void)
return (0);
}
+#if HAVE_SUN_ACL
+/* Fetch ACLs on Solaris using acl() or facl() */
+void *
+sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
+{
+ int cnt, cntcmd;
+ size_t size;
+ void *aclp;
+
+ if (cmd == GETACL) {
+ cntcmd = GETACLCNT;
+ size = sizeof(aclent_t);
+ }
+#if HAVE_SUN_NFS4_ACL
+ else if (cmd == ACE_GETACL) {
+ cntcmd = ACE_GETACLCNT;
+ size = sizeof(ace_t);
+ }
+#endif
+ else {
+ errno = EINVAL;
+ *aclcnt = -1;
+ return (NULL);
+ }
+
+ aclp = NULL;
+ cnt = -2;
+ while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
+ if (path != NULL)
+ cnt = acl(path, cntcmd, 0, NULL);
+ else
+ cnt = facl(fd, cntcmd, 0, NULL);
+
+ if (cnt > 0) {
+ if (aclp == NULL)
+ aclp = malloc(cnt * size);
+ else
+ aclp = realloc(NULL, cnt * size);
+ if (aclp != NULL) {
+ if (path != NULL)
+ cnt = acl(path, cmd, cnt, aclp);
+ else
+ cnt = facl(fd, cmd, cnt, aclp);
+ }
+ } else {
+ if (aclp != NULL) {
+ free(aclp);
+ aclp = NULL;
+ }
+ break;
+ }
+ }
+
+ *aclcnt = cnt;
+ return (aclp);
+}
+#endif /* HAVE_SUN_ACL */
+
+/*
+ * Set test ACLs on a path
+ * Return values:
+ * 0: error setting ACLs
+ * ARCHIVE_TEST_ACL_TYPE_POSIX1E: POSIX.1E ACLs have been set
+ * ARCHIVE_TEST_ACL_TYPE_NFS4: NFSv4 or extended ACLs have been set
+ */
+int
+setTestAcl(const char *path)
+{
+#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
+ int r = 1;
+#if !HAVE_SUN_ACL
+ acl_t acl;
+#endif
+#if HAVE_POSIX_ACL /* Linux, FreeBSD POSIX.1e */
+ const char *acltext_posix1e = "user:1:rw-,"
+ "group:15:r-x,"
+ "user::rwx,"
+ "group::rwx,"
+ "other::r-x,"
+ "mask::rwx";
+#elif HAVE_SUN_ACL /* Solaris POSIX.1e */
+ aclent_t aclp_posix1e[] = {
+ { USER_OBJ, -1, 4 | 2 | 1 },
+ { USER, 1, 4 | 2 },
+ { GROUP_OBJ, -1, 4 | 2 | 1 },
+ { GROUP, 15, 4 | 1 },
+ { CLASS_OBJ, -1, 4 | 2 | 1 },
+ { OTHER_OBJ, -1, 4 | 2 | 1 }
+ };
+#endif
+#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFS4 */
+ const char *acltext_nfs4 = "user:1:rwpaRcs::allow:1,"
+ "group:15:rxaRcs::allow:15,"
+ "owner@:rwpxaARWcCos::allow,"
+ "group@:rwpxaRcs::allow,"
+ "everyone@:rxaRcs::allow";
+#elif HAVE_SUN_NFS4_ACL /* Solaris NFS4 */
+ ace_t aclp_nfs4[] = {
+ { 1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
+ ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | ACE_READ_ACL |
+ ACE_SYNCHRONIZE, 0, ACE_ACCESS_ALLOWED_ACE_TYPE },
+ { 15, ACE_READ_DATA | ACE_EXECUTE | ACE_READ_ATTRIBUTES |
+ ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE,
+ ACE_IDENTIFIER_GROUP, ACE_ACCESS_ALLOWED_ACE_TYPE },
+ { -1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
+ ACE_EXECUTE | ACE_READ_ATTRIBUTES | ACE_WRITE_ATTRIBUTES |
+ ACE_READ_NAMED_ATTRS | ACE_WRITE_NAMED_ATTRS |
+ ACE_READ_ACL | ACE_WRITE_ACL | ACE_WRITE_OWNER | ACE_SYNCHRONIZE,
+ ACE_OWNER, ACE_ACCESS_ALLOWED_ACE_TYPE },
+ { -1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
+ ACE_EXECUTE | ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
+ ACE_READ_ACL | ACE_SYNCHRONIZE, ACE_GROUP | ACE_IDENTIFIER_GROUP,
+ ACE_ACCESS_ALLOWED_ACE_TYPE },
+ { -1, ACE_READ_DATA | ACE_EXECUTE | ACE_READ_ATTRIBUTES |
+ ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE,
+ ACE_EVERYONE, ACE_ACCESS_ALLOWED_ACE_TYPE }
+ };
+#elif HAVE_DARWIN_ACL /* Mac OS X */
+ acl_entry_t aclent;
+ acl_permset_t permset;
+ const uid_t uid = 1;
+ uuid_t uuid;
+ int i;
+ const acl_perm_t acl_perms[] = {
+ ACL_READ_DATA,
+ ACL_WRITE_DATA,
+ ACL_APPEND_DATA,
+ ACL_EXECUTE,
+ ACL_READ_ATTRIBUTES,
+ ACL_READ_EXTATTRIBUTES,
+ ACL_READ_SECURITY,
+#if HAVE_DECL_ACL_SYNCHRONIZE
+ ACL_SYNCHRONIZE
+#endif
+ };
+#endif /* HAVE_DARWIN_ACL */
+
+#if HAVE_FREEBSD_NFS4_ACL
+ acl = acl_from_text(acltext_nfs4);
+ failure("acl_from_text() error: %s", strerror(errno));
+ if (assert(acl != NULL) == 0)
+ return (0);
+#elif HAVE_DARWIN_ACL
+ acl = acl_init(1);
+ failure("acl_init() error: %s", strerror(errno));
+ if (assert(acl != NULL) == 0)
+ return (0);
+ r = acl_create_entry(&acl, &aclent);
+ failure("acl_create_entry() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ r = acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW);
+ failure("acl_set_tag_type() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ r = acl_get_permset(aclent, &permset);
+ failure("acl_get_permset() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ for (i = 0; i < (int)(sizeof(acl_perms) / sizeof(acl_perms[0])); i++) {
+ r = acl_add_perm(permset, acl_perms[i]);
+ failure("acl_add_perm() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ }
+ r = acl_set_permset(aclent, permset);
+ failure("acl_set_permset() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ r = mbr_identifier_to_uuid(ID_TYPE_UID, &uid, sizeof(uid_t), uuid);
+ failure("mbr_identifier_to_uuid() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+ r = acl_set_qualifier(aclent, uuid);
+ failure("acl_set_qualifier() error: %s", strerror(errno));
+ if (assertEqualInt(r, 0) == 0)
+ goto testacl_free;
+#endif /* HAVE_DARWIN_ACL */
+
+#if HAVE_NFS4_ACL
+#if HAVE_FREEBSD_NFS4_ACL
+ r = acl_set_file(path, ACL_TYPE_NFS4, acl);
+ acl_free(acl);
+#elif HAVE_SUN_NFS4_ACL
+ r = acl(path, ACE_SETACL,
+ (int)(sizeof(aclp_nfs4)/sizeof(aclp_nfs4[0])), aclp_nfs4);
+#elif HAVE_DARWIN_ACL
+ r = acl_set_file(path, ACL_TYPE_EXTENDED, acl);
+ acl_free(acl);
+#endif
+ if (r == 0)
+ return (ARCHIVE_TEST_ACL_TYPE_NFS4);
+#endif /* HAVE_NFS4_ACL */
+
+#if HAVE_POSIX_ACL || HAVE_SUN_ACL
+#if HAVE_POSIX_ACL
+ acl = acl_from_text(acltext_posix1e);
+ failure("acl_from_text() error: %s", strerror(errno));
+ if (assert(acl != NULL) == 0)
+ return (0);
+
+ r = acl_set_file(path, ACL_TYPE_ACCESS, acl);
+ acl_free(acl);
+#elif HAVE_SUN_ACL
+ r = acl(path, SETACL,
+ (int)(sizeof(aclp_posix1e)/sizeof(aclp_posix1e[0])), aclp_posix1e);
+#endif
+ if (r == 0)
+ return (ARCHIVE_TEST_ACL_TYPE_POSIX1E);
+ else
+ return (0);
+#endif /* HAVE_POSIX_ACL || HAVE_SUN_ACL */
+#if HAVE_DARWIN_ACL
+testacl_free:
+ acl_free(acl);
+#endif
+#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
+ (void)path; /* UNUSED */
+ return (0);
+}
+
/*
* Sleep as needed; useful for verifying disk timestamp changes by
* ensuring that the wall-clock time has actually changed before we