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
This commit is contained in:
13 files changed
+754
-268
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
#
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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)
|
||||
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,93 +735,16 @@ 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
|
||||
assertMakeFile("pretest", 0644, "a");
|
||||
|
||||
if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) {
|
||||
skipping("NFS4 ACLs are not writable on this filesystem");
|
||||
return;
|
||||
}
|
||||
|
||||
#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);
|
||||
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()));
|
||||
archive_write_disk_set_options(a,
|
||||
|
||||
@@ -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,78 +311,13 @@ 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
|
||||
assertMakeFile("pretest", 0644, "a");
|
||||
|
||||
/* 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
|
||||
if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_POSIX1E) {
|
||||
skipping("POSIX.1e ACLs are not writable on this filesystem");
|
||||
return;
|
||||
}
|
||||
|
||||
#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);
|
||||
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()));
|
||||
archive_write_disk_set_options(a,
|
||||
|
||||
@@ -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)
|
||||
|
||||
#
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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, ...);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user