diff options
author | Martin Matuska <mm@FreeBSD.org> | 2017-03-20 13:02:27 +0000 |
---|---|---|
committer | Martin Matuska <mm@FreeBSD.org> | 2017-03-20 13:02:27 +0000 |
commit | 4657548d18877f64bd02be888406aa5b02bf9b06 (patch) | |
tree | a799a9cee40e53706103a717a7c73fb3ba1f6aa1 /contrib/libarchive | |
parent | 90589b904f71be5b92a8dbea319f5ef6c4a89d80 (diff) | |
parent | 4a7f6834348e3853977e1b7d69ff44f6eb93313c (diff) | |
download | src-4657548d18877f64bd02be888406aa5b02bf9b06.tar.gz src-4657548d18877f64bd02be888406aa5b02bf9b06.zip |
Notes
Diffstat (limited to 'contrib/libarchive')
28 files changed, 1682 insertions, 2424 deletions
diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS index 281c1768c30b..9e517934547e 100644 --- a/contrib/libarchive/NEWS +++ b/contrib/libarchive/NEWS @@ -1,3 +1,5 @@ +Mar 16, 2017: NFSv4 ACL support for Linux (librichacl) + Feb 26, 2017: libarchive 3.3.1 released Security & Feature release @@ -293,7 +295,7 @@ May 04, 2008: libarchive 2.5.3b released * libarchive: Mark which entry strings are set; be accurate about distinguishing empty strings ("") from unset ones (NULL) * tar: Don't crash reading entries with empty filenames - * libarchive_test, bsdtar_test, bsdcpio_test: Better detaults: + * libarchive_test, bsdtar_test, bsdcpio_test: Better defaults: run all tests, delete temp dirs, summarize repeated failures * -no-undefined to libtool for Cygwin * libarchive_test: Skip large file tests on systems with 32-bit off_t diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c index 7f1b11973c07..42e26cdf0af6 100644 --- a/contrib/libarchive/cpio/cpio.c +++ b/contrib/libarchive/cpio/cpio.c @@ -1344,23 +1344,23 @@ lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable, cache->cache[slot].name = NULL; } - if (lookup_fn(cpio, &name, id) == 0) { - if (name == NULL || name[0] == '\0') { - /* If lookup failed, format it as a number. */ - snprintf(asnum, sizeof(asnum), "%u", (unsigned)id); - name = asnum; - } - cache->cache[slot].name = strdup(name); - if (cache->cache[slot].name != NULL) { - cache->cache[slot].id = id; - return (cache->cache[slot].name); - } - /* - * Conveniently, NULL marks an empty slot, so - * if the strdup() fails, we've just failed to - * cache it. No recovery necessary. - */ + if (lookup_fn(cpio, &name, id)) { + /* If lookup failed, format it as a number. */ + snprintf(asnum, sizeof(asnum), "%u", (unsigned)id); + name = asnum; + } + + cache->cache[slot].name = strdup(name); + if (cache->cache[slot].name != NULL) { + cache->cache[slot].id = id; + return (cache->cache[slot].name); } + + /* + * Conveniently, NULL marks an empty slot, so + * if the strdup() fails, we've just failed to + * cache it. No recovery necessary. + */ return (NULL); } @@ -1381,15 +1381,14 @@ lookup_uname_helper(struct cpio *cpio, const char **name, id_t id) errno = 0; pwent = getpwuid((uid_t)id); if (pwent == NULL) { - *name = NULL; - if (errno != 0 && errno != ENOENT) + if (errno && errno != ENOENT) lafe_warnc(errno, "getpwuid(%s) failed", cpio_i64toa((int64_t)id)); - return (errno); + return 1; } *name = pwent->pw_name; - return (0); + return 0; } static const char * @@ -1409,15 +1408,14 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id) errno = 0; grent = getgrgid((gid_t)id); if (grent == NULL) { - *name = NULL; - if (errno != 0) + if (errno && errno != ENOENT) lafe_warnc(errno, "getgrgid(%s) failed", cpio_i64toa((int64_t)id)); - return (errno); + return 1; } *name = grent->gr_name; - return (0); + return 0; } /* diff --git a/contrib/libarchive/libarchive/archive_acl_maps.h b/contrib/libarchive/libarchive/archive_acl_maps.h new file mode 100644 index 000000000000..e3f4408286a1 --- /dev/null +++ b/contrib/libarchive/libarchive/archive_acl_maps.h @@ -0,0 +1,50 @@ +/*- + * 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. + */ + +#ifndef __LIBARCHIVE_BUILD +#error This header is only to be used internally to libarchive. +#endif + +#ifndef ARCHIVE_ACL_MAPS_H_INCLUDED +#define ARCHIVE_ACL_MAPS_H_INCLUDED + +#include "archive_platform_acl.h" + +typedef struct { + const int a_perm; /* Libarchive permission or flag */ + const int p_perm; /* Platform permission or flag */ +} acl_perm_map_t; + +#if ARCHIVE_ACL_POSIX1E +extern const acl_perm_map_t acl_posix_perm_map[]; +extern const int acl_posix_perm_map_size; +#endif +#if ARCHIVE_ACL_NFS4 +extern const acl_perm_map_t acl_nfs4_perm_map[]; +extern const int acl_nfs4_perm_map_size; +extern const acl_perm_map_t acl_nfs4_flag_map[]; +extern const int acl_nfs4_flag_map_size; +#endif +#endif /* ARCHIVE_ACL_MAPS_H_INCLUDED */ diff --git a/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c b/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c new file mode 100644 index 000000000000..17b1e953a396 --- /dev/null +++ b/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c @@ -0,0 +1,86 @@ +/*- + * 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 "archive_platform.h" + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_ACL_H +#define _ACL_PRIVATE /* For debugging */ +#include <sys/acl.h> +#endif + +#include "archive_entry.h" +#include "archive_private.h" +#include "archive_read_disk_private.h" +#include "archive_acl_maps.h" + +const acl_perm_map_t acl_posix_perm_map[] = { + {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, + {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE}, + {ARCHIVE_ENTRY_ACL_READ, ACL_READ}, +}; + +const int acl_posix_perm_map_size = + (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0])); + +#if ARCHIVE_ACL_FREEBSD_NFS4 +const acl_perm_map_t acl_nfs4_perm_map[] = { + {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, + {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, + {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, + {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, + {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, + {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, + {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, + {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, + {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, + {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL}, + {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL}, + {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER}, + {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} +}; + +const int acl_nfs4_perm_map_size = + (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0])); + +const acl_perm_map_t acl_nfs4_flag_map[] = { + {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}, + {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS}, + {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS}, + {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED} +}; + +const int acl_nfs4_flag_map_size = + (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0])); +#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */ diff --git a/contrib/libarchive/libarchive/archive_entry.3 b/contrib/libarchive/libarchive/archive_entry.3 index f5e22af85122..f75916c9e41b 100644 --- a/contrib/libarchive/libarchive/archive_entry.3 +++ b/contrib/libarchive/libarchive/archive_entry.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Feburary 2, 2012 +.Dd February 2, 2012 .Dt ARCHIVE_ENTRY 3 .Os .Sh NAME diff --git a/contrib/libarchive/libarchive/archive_entry_acl.3 b/contrib/libarchive/libarchive/archive_entry_acl.3 index 7ede7b76bc15..534dbfac6ef6 100644 --- a/contrib/libarchive/libarchive/archive_entry_acl.3 +++ b/contrib/libarchive/libarchive/archive_entry_acl.3 @@ -267,7 +267,7 @@ Only inherit, do not apply the permission on the directory itself. .It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n ) Do not propagate inherit flags. Only first-level entries inherit ACLs. .It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S ) -Trigger alarm or audit on succesful access. +Trigger alarm or audit on successful access. .It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F ) Trigger alarm or audit on failed access. .It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERITED ( Sy I ) @@ -279,7 +279,7 @@ and .Fn archive_entry_acl_add_entry_w add a single ACL entry. For the access ACL and non-extended principals, the classic Unix permissions -are updated. An archive enry cannot contain both POSIX.1e and NFSv4 ACL +are updated. An archive entry cannot contain both POSIX.1e and NFSv4 ACL entries. .Pp .Fn archive_entry_acl_clear @@ -303,7 +303,7 @@ for POSIX.1e ACLs and for NFSv4 ACLs. For POSIX.1e ACLs if .Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS is included and at least one extended ACL entry is found, -the three non-extened ACLs are added. +the three non-extended ACLs are added. .Pp .Fn archive_entry_acl_from_text and @@ -367,7 +367,7 @@ and .Fn archive_entry_acl_to_text_w convert the ACL entries for the given type into a .Pq wide -string of ACL entries separated by newline. If the the pointer +string of ACL entries separated by newline. If the pointer .Fa len_p is not NULL, then the function shall return the length of the string .Pq not including the NULL terminator diff --git a/contrib/libarchive/libarchive/archive_platform.h b/contrib/libarchive/libarchive/archive_platform.h index 7d99d20a1510..692238277a84 100644 --- a/contrib/libarchive/libarchive/archive_platform.h +++ b/contrib/libarchive/libarchive/archive_platform.h @@ -143,40 +143,6 @@ #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 -#if HAVE_DECL_ACL_USER -#define HAVE_POSIX_ACL 1 -#elif HAVE_DECL_ACL_TYPE_EXTENDED && HAVE_MEMBERSHIP_H -#define HAVE_DARWIN_ACL 1 -#endif -#if HAVE_DECL_ACL_TYPE_NFS4 -#define HAVE_FREEBSD_NFS4_ACL 1 -#endif -#endif - -/* - * If this platform has <sys/acl.h>, acl(), facl() and ACLENT_T - * facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions - */ -#if HAVE_SYS_ACL_H && HAVE_ACL && HAVE_FACL && HAVE_ACLENT_T && \ - HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL -#define HAVE_SUN_ACL 1 -#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \ - HAVE_DECL_ACE_SETACL -#define HAVE_SUN_NFS4_ACL 1 -#endif -#endif - -/* Define if platform supports NFSv4 ACLs */ -#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL -#define HAVE_NFS4_ACL 1 -#endif - -/* * If we can't restore metadata using a file descriptor, then * for compatibility's sake, close files before trying to restore metadata. */ diff --git a/contrib/libarchive/libarchive/archive_platform_acl.h b/contrib/libarchive/libarchive/archive_platform_acl.h new file mode 100644 index 000000000000..3498f78b3c85 --- /dev/null +++ b/contrib/libarchive/libarchive/archive_platform_acl.h @@ -0,0 +1,49 @@ +/*- + * 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. + * + * $FreeBSD$ + */ + +/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */ + +#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED +#define ARCHIVE_PLATFORM_ACL_H_INCLUDED + +/* + * Determine what ACL types are supported + */ +#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_SUNOS || ARCHIVE_ACL_LIBACL +#define ARCHIVE_ACL_POSIX1E 1 +#endif + +#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_SUNOS_NFS4 || \ + ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL +#define ARCHIVE_ACL_NFS4 1 +#endif + +#if ARCHIVE_ACL_POSIX1E || ARCHIVE_ACL_NFS4 +#define ARCHIVE_ACL_SUPPORT 1 +#endif + +#endif /* ARCHIVE_PLATFORM_ACL_H_INCLUDED */ diff --git a/contrib/libarchive/libarchive/archive_random.c b/contrib/libarchive/libarchive/archive_random.c index 357f9733a870..65ea6915768d 100644 --- a/contrib/libarchive/libarchive/archive_random.c +++ b/contrib/libarchive/libarchive/archive_random.c @@ -221,8 +221,11 @@ arc4_stir(void) /* * Discard early keystream, as per recommendations in: * "(Not So) Random Shuffles of RC4" by Ilya Mironov. + * As per the Network Operations Division, cryptographic requirements + * published on wikileaks on March 2017. */ - for (i = 0; i < 1024; i++) + + for (i = 0; i < 3072; i++) (void)arc4_getbyte(); arc4_count = 1600000; } diff --git a/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c b/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c new file mode 100644 index 000000000000..c09c3e1c2b51 --- /dev/null +++ b/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c @@ -0,0 +1,371 @@ +/*- + * Copyright (c) 2003-2009 Tim Kientzle + * Copyright (c) 2010-2012 Michihiro NAKAJIMA + * Copyright (c) 2016-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 "archive_platform.h" + +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_ACL_H +#define _ACL_PRIVATE /* For debugging */ +#include <sys/acl.h> +#endif + +#include "archive_entry.h" +#include "archive_private.h" +#include "archive_read_disk_private.h" +#include "archive_acl_maps.h" + +/* + * Translate FreeBSD ACLs into libarchive internal structure + */ +static int +translate_acl(struct archive_read_disk *a, + struct archive_entry *entry, acl_t acl, int default_entry_acl_type) +{ +#if ARCHIVE_ACL_FREEBSD_NFS4 + int brand; + acl_flagset_t acl_flagset; +#endif + acl_tag_t acl_tag; + acl_entry_t acl_entry; + acl_permset_t acl_permset; + acl_entry_type_t acl_type; + int i, entry_acl_type, perm_map_size; + const acl_perm_map_t *perm_map; + int r, s, ae_id, ae_tag, ae_perm; + void *q; + const char *ae_name; + +#if ARCHIVE_ACL_FREEBSD_NFS4 + // FreeBSD "brands" ACLs as POSIX.1e or NFSv4 + // Make sure the "brand" on this ACL is consistent + // with the default_entry_acl_type bits provided. + if (acl_get_brand_np(acl, &brand) != 0) { + archive_set_error(&a->archive, errno, + "Failed to read ACL brand"); + return (ARCHIVE_WARN); + } + switch (brand) { + case ACL_BRAND_POSIX: + switch (default_entry_acl_type) { + case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: + case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: + break; + default: + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Invalid ACL entry type for POSIX.1e ACL"); + return (ARCHIVE_WARN); + } + break; + case ACL_BRAND_NFS4: + if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Invalid ACL entry type for NFSv4 ACL"); + return (ARCHIVE_WARN); + } + break; + default: + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Unknown ACL brand"); + return (ARCHIVE_WARN); + } +#endif + + s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); + if (s == -1) { + archive_set_error(&a->archive, errno, + "Failed to get first ACL entry"); + return (ARCHIVE_WARN); + } + + while (s == 1) { + ae_id = -1; + ae_name = NULL; + ae_perm = 0; + + if (acl_get_tag_type(acl_entry, &acl_tag) != 0) { + archive_set_error(&a->archive, errno, + "Failed to get ACL tag type"); + return (ARCHIVE_WARN); + } + switch (acl_tag) { + case ACL_USER: + q = acl_get_qualifier(acl_entry); + if (q != NULL) { + ae_id = (int)*(uid_t *)q; + acl_free(q); + ae_name = archive_read_disk_uname(&a->archive, + ae_id); + } + ae_tag = ARCHIVE_ENTRY_ACL_USER; + break; + case ACL_GROUP: + q = acl_get_qualifier(acl_entry); + if (q != NULL) { + ae_id = (int)*(gid_t *)q; + acl_free(q); + ae_name = archive_read_disk_gname(&a->archive, + ae_id); + } + ae_tag = ARCHIVE_ENTRY_ACL_GROUP; + break; + case ACL_MASK: + ae_tag = ARCHIVE_ENTRY_ACL_MASK; + break; + case ACL_USER_OBJ: + ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; + break; + case ACL_GROUP_OBJ: + ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; + break; + case ACL_OTHER: + ae_tag = ARCHIVE_ENTRY_ACL_OTHER; + break; +#if ARCHIVE_ACL_FREEBSD_NFS4 + case ACL_EVERYONE: + ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE; + break; +#endif + default: + /* Skip types that libarchive can't support. */ + s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); + continue; + } + + // XXX acl_type maps to allow/deny/audit/YYYY bits + entry_acl_type = default_entry_acl_type; + +#if ARCHIVE_ACL_FREEBSD_NFS4 + if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { + /* + * acl_get_entry_type_np() fails with non-NFSv4 ACLs + */ + if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) { + archive_set_error(&a->archive, errno, "Failed " + "to get ACL type from a NFSv4 ACL entry"); + return (ARCHIVE_WARN); + } + switch (acl_type) { + case ACL_ENTRY_TYPE_ALLOW: + entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; + break; + case ACL_ENTRY_TYPE_DENY: + entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; + break; + case ACL_ENTRY_TYPE_AUDIT: + entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT; + break; + case ACL_ENTRY_TYPE_ALARM: + entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; + break; + default: + archive_set_error(&a->archive, errno, + "Invalid NFSv4 ACL entry type"); + return (ARCHIVE_WARN); + } + + /* + * Libarchive stores "flag" (NFSv4 inheritance bits) + * in the ae_perm bitmap. + * + * acl_get_flagset_np() fails with non-NFSv4 ACLs + */ + if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { + archive_set_error(&a->archive, errno, + "Failed to get flagset from a NFSv4 " + "ACL entry"); + return (ARCHIVE_WARN); + } + for (i = 0; i < acl_nfs4_flag_map_size; ++i) { + r = acl_get_flag_np(acl_flagset, + acl_nfs4_flag_map[i].p_perm); + if (r == -1) { + archive_set_error(&a->archive, errno, + "Failed to check flag in a NFSv4 " + "ACL flagset"); + return (ARCHIVE_WARN); + } else if (r) + ae_perm |= acl_nfs4_flag_map[i].a_perm; + } + } +#endif + + if (acl_get_permset(acl_entry, &acl_permset) != 0) { + archive_set_error(&a->archive, errno, + "Failed to get ACL permission set"); + return (ARCHIVE_WARN); + } + +#if ARCHIVE_ACL_FREEBSD_NFS4 + if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { + perm_map_size = acl_nfs4_perm_map_size; + perm_map = acl_nfs4_perm_map; + } else { +#endif + perm_map_size = acl_posix_perm_map_size; + perm_map = acl_posix_perm_map; +#if ARCHIVE_ACL_FREEBSD_NFS4 + } +#endif + + for (i = 0; i < perm_map_size; ++i) { + r = acl_get_perm_np(acl_permset, perm_map[i].p_perm); + if (r == -1) { + archive_set_error(&a->archive, errno, + "Failed to check permission in an ACL " + "permission set"); + return (ARCHIVE_WARN); + } else if (r) + ae_perm |= perm_map[i].a_perm; + } + + archive_entry_acl_add_entry(entry, entry_acl_type, + ae_perm, ae_tag, + ae_id, ae_name); + + s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); + if (s == -1) { + archive_set_error(&a->archive, errno, + "Failed to get next ACL entry"); + return (ARCHIVE_WARN); + } + } + return (ARCHIVE_OK); +} + +int +archive_read_disk_entry_setup_acls(struct archive_read_disk *a, + struct archive_entry *entry, int *fd) +{ + const char *accpath; + acl_t acl; + int r; + + accpath = NULL; + + if (*fd < 0) { + accpath = archive_read_disk_entry_setup_path(a, entry, fd); + if (accpath == NULL) + return (ARCHIVE_WARN); + } + + archive_entry_acl_clear(entry); + + acl = NULL; + +#if ARCHIVE_ACL_FREEBSD_NFS4 + /* Try NFSv4 ACL first. */ + if (*fd >= 0) + acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4); + else if (!a->follow_symlinks) + acl = acl_get_link_np(accpath, ACL_TYPE_NFS4); + else + acl = acl_get_file(accpath, ACL_TYPE_NFS4); + + /* Ignore "trivial" ACLs that just mirror the file mode. */ + if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) { + acl_free(acl); + acl = NULL; + return (ARCHIVE_OK); + } + + if (acl != NULL) { + r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4); + acl_free(acl); + acl = NULL; + + if (r != ARCHIVE_OK) { + archive_set_error(&a->archive, errno, + "Couldn't translate NFSv4 ACLs"); + } + + return (r); + } +#endif + + /* Retrieve access ACL from file. */ + if (*fd >= 0) + acl = acl_get_fd_np(*fd, ACL_TYPE_ACCESS); +#if HAVE_ACL_GET_LINK_NP + else if (!a->follow_symlinks) + acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); +#else + else if ((!a->follow_symlinks) + && (archive_entry_filetype(entry) == AE_IFLNK)) + /* We can't get the ACL of a symlink, so we assume it can't + have one. */ + acl = NULL; +#endif + else + acl = acl_get_file(accpath, ACL_TYPE_ACCESS); + +#if HAVE_ACL_IS_TRIVIAL_NP + /* Ignore "trivial" ACLs that just mirror the file mode. */ + if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) { + acl_free(acl); + acl = NULL; + } +#endif + + if (acl != NULL) { + r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); + acl_free(acl); + acl = NULL; + + if (r != ARCHIVE_OK) { + archive_set_error(&a->archive, errno, + "Couldn't translate access ACLs"); + return (r); + } + } + + /* Only directories can have default ACLs. */ + if (S_ISDIR(archive_entry_mode(entry))) { + if (*fd >= 0) + acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT); + else + acl = acl_get_file(accpath, ACL_TYPE_DEFAULT); + if (acl != NULL) { + r = translate_acl(a, entry, acl, + ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); + acl_free(acl); + if (r != ARCHIVE_OK) { + archive_set_error(&a->archive, errno, + "Couldn't translate default ACLs"); + return (r); + } + } + } + return (ARCHIVE_OK); +} diff --git a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c index 06d051a20846..154dd0f6582a 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c @@ -26,23 +26,14 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD"); /* This is the tree-walking code for POSIX systems. */ #if !defined(_WIN32) || defined(__CYGWIN__) #ifdef HAVE_SYS_TYPES_H -/* Mac OSX requires sys/types.h before sys/acl.h. */ #include <sys/types.h> #endif -#ifdef HAVE_SYS_ACL_H -#include <sys/acl.h> -#endif -#ifdef HAVE_DARWIN_ACL -#include <membership.h> -#include <grp.h> -#include <pwd.h> -#endif #ifdef HAVE_SYS_EXTATTR_H #include <sys/extattr.h> #endif @@ -63,9 +54,6 @@ __FBSDID("$FreeBSD$"); #ifdef HAVE_SYS_EA_H #include <sys/ea.h> #endif -#ifdef HAVE_ACL_LIBACL_H -#include <acl/libacl.h> -#endif #ifdef HAVE_COPYFILE_H #include <copyfile.h> #endif @@ -113,25 +101,6 @@ __FBSDID("$FreeBSD$"); #define O_CLOEXEC 0 #endif -/* - * Linux and FreeBSD plug this obvious hole in POSIX.1e in - * different ways. - */ -#if HAVE_ACL_GET_PERM -#define ACL_GET_PERM acl_get_perm -#elif HAVE_ACL_GET_PERM_NP -#define ACL_GET_PERM acl_get_perm_np -#endif - -/* NFSv4 platform ACL type */ -#if HAVE_DARWIN_ACL -#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED -#elif HAVE_FREEBSD_NFS4_ACL -#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4 -#endif - -static int setup_acls(struct archive_read_disk *, - struct archive_entry *, int *fd); static int setup_mac_metadata(struct archive_read_disk *, struct archive_entry *, int *fd); static int setup_xattrs(struct archive_read_disk *, @@ -143,6 +112,45 @@ static int setup_sparse_fiemap(struct archive_read_disk *, struct archive_entry *, int *fd); #endif +#if !ARCHIVE_ACL_SUPPORT +int +archive_read_disk_entry_setup_acls(struct archive_read_disk *a, + struct archive_entry *entry, int *fd) +{ + (void)a; /* UNUSED */ + (void)entry; /* UNUSED */ + (void)fd; /* UNUSED */ + return (ARCHIVE_OK); +} +#endif + +/* + * Enter working directory and return working pathname of archive_entry. + * If a pointer to an integer is provided and its value is below zero + * open a file descriptor on this pahtname. + */ +const char * +archive_read_disk_entry_setup_path(struct archive_read_disk *a, + struct archive_entry *entry, int *fd) +{ + const char *path; + + path = archive_entry_sourcepath(entry); + + if (path == NULL || (a->tree != NULL && + a->tree_enter_working_dir(a->tree) != 0)) + path = archive_entry_pathname(entry); + if (path == NULL) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Couldn't determine path"); + } else if (fd != NULL && *fd < 0 && a->tree != NULL && + (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) { + *fd = a->open_on_current_dir(a->tree, path, + O_RDONLY | O_NONBLOCK); + } + return (path); +} + int archive_read_disk_entry_from_file(struct archive *_a, struct archive_entry *entry, @@ -277,7 +285,7 @@ archive_read_disk_entry_from_file(struct archive *_a, r = 0; if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0) - r = setup_acls(a, entry, &fd); + r = archive_read_disk_entry_setup_acls(a, entry, &fd); if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) { r1 = setup_xattrs(a, entry, &fd); if (r1 < r) @@ -326,19 +334,10 @@ setup_mac_metadata(struct archive_read_disk *a, struct archive_string tempfile; (void)fd; /* UNUSED */ - name = archive_entry_sourcepath(entry); + + name = archive_read_disk_entry_setup_path(a, entry, NULL); if (name == NULL) - name = archive_entry_pathname(entry); - else if (a->tree != NULL && a->tree_enter_working_dir(a->tree) != 0) { - archive_set_error(&a->archive, errno, - "Can't change dir to read extended attributes"); - return (ARCHIVE_FAILED); - } - if (name == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't open file to read extended attributes: No name"); return (ARCHIVE_WARN); - } /* Short-circuit if there's nothing to do. */ have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK); @@ -424,1116 +423,6 @@ setup_mac_metadata(struct archive_read_disk *a, } #endif -#if HAVE_DARWIN_ACL -static int translate_guid(struct archive *, acl_entry_t, - int *, int *, const char **); - -static void add_trivial_nfs4_acl(struct archive_entry *); -#endif - -#if HAVE_SUN_ACL -static int -sun_acl_is_trivial(void *, int, mode_t, int, int, int *); - -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 */ - -#if HAVE_POSIX_ACL || HAVE_NFS4_ACL -static int translate_acl(struct archive_read_disk *a, - struct archive_entry *entry, -#if HAVE_SUN_ACL - void *aclp, - int aclcnt, -#else - acl_t acl, -#endif - int archive_entry_acl_type); - -static int -setup_acls(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - const char *accpath; -#if HAVE_SUN_ACL - void *aclp; - int aclcnt; -#else - acl_t acl; -#endif - int r; - - accpath = NULL; - -#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_ACL_GET_FD_NP - if (*fd < 0) -#else - /* For default ACLs on Linux we need reachable accpath */ - if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) -#endif - { - accpath = archive_entry_sourcepath(entry); - if (accpath == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - accpath = archive_entry_pathname(entry); - if (accpath == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read ACLs"); - return (ARCHIVE_WARN); - } - if (a->tree != NULL && -#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_ACL_GET_FD_NP - *fd < 0 && -#endif - (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - accpath, O_RDONLY | O_NONBLOCK); - } - } - - archive_entry_acl_clear(entry); - -#if HAVE_SUN_ACL - aclp = NULL; -#else - acl = NULL; -#endif - -#if HAVE_NFS4_ACL - /* Try NFSv4 ACL first. */ - if (*fd >= 0) -#if HAVE_SUN_ACL - aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL); -#elif HAVE_ACL_GET_FD_NP - acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); -#else - acl = acl_get_fd(*fd); -#endif -#if HAVE_ACL_GET_LINK_NP - else if (!a->follow_symlinks) - acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); -#else - else if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) - /* We can't get the ACL of a symlink, so we assume it can't - have one. */ -#if HAVE_SUN_ACL - aclp = NULL; -#else - acl = NULL; -#endif -#endif /* !HAVE_ACL_GET_LINK_NP */ - else -#if HAVE_SUN_ACL - /* Solaris reads both POSIX.1e and NFSv4 ACLs here */ - aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath); -#else - acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); -#endif - - - /* Ignore "trivial" ACLs that just mirror the file mode. */ -#if HAVE_SUN_ACL - if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt, - archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)), - &r) == 0 && r == 1) { - free(aclp); - aclp = NULL; - return (ARCHIVE_OK); - } -#elif HAVE_ACL_IS_TRIVIAL_NP - if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) { - acl_free(acl); - acl = NULL; - return (ARCHIVE_OK); - } -#endif - -#if HAVE_SUN_ACL - if (aclp != NULL) -#else - if (acl != NULL) -#endif - { - r = translate_acl(a, entry, -#if HAVE_SUN_ACL - aclp, aclcnt, -#else - acl, -#endif - ARCHIVE_ENTRY_ACL_TYPE_NFS4); -#if HAVE_SUN_ACL - free(aclp); - aclp = NULL; -#else - acl_free(acl); - acl = NULL; -#endif - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate NFSv4 ACLs"); - } -#if HAVE_DARWIN_ACL - /* - * Because Mac OS doesn't support owner@, group@ and everyone@ - * ACLs we need to add NFSv4 ACLs mirroring the file mode to - * the archive entry. Otherwise extraction on non-Mac platforms - * would lead to an invalid file mode. - */ - if ((archive_entry_acl_types(entry) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) - add_trivial_nfs4_acl(entry); -#endif - return (r); - } -#endif /* HAVE_NFS4_ACL */ - -#if HAVE_POSIX_ACL || HAVE_SUN_ACL - /* This code path is skipped on MacOS */ - - /* Retrieve access ACL from file. */ - if (*fd >= 0) -#if HAVE_SUN_ACL - aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL); -#else - acl = acl_get_fd(*fd); -#endif -#if HAVE_ACL_GET_LINK_NP - else if (!a->follow_symlinks) - acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); -#else - else if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) - /* We can't get the ACL of a symlink, so we assume it can't - have one. */ -#if HAVE_SUN_ACL - aclp = NULL; -#else - acl = NULL; -#endif -#endif /* !HAVE_ACL_GET_LINK_NP */ - else -#if HAVE_SUN_ACL - aclp = sunacl_get(GETACL, &aclcnt, 0, accpath); -#else - acl = acl_get_file(accpath, ACL_TYPE_ACCESS); -#endif - - - /* Ignore "trivial" ACLs that just mirror the file mode. */ -#if HAVE_SUN_ACL - if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt, - archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)), - &r) == 0 && r == 1) { - free(aclp); - aclp = NULL; - } -#elif HAVE_ACL_IS_TRIVIAL_NP - if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) { - acl_free(acl); - acl = NULL; - } -#endif - -#if HAVE_SUN_ACL - if (aclp != NULL) -#else - if (acl != NULL) -#endif - { - r = translate_acl(a, entry, -#if HAVE_SUN_ACL - aclp, aclcnt, -#else - acl, -#endif - ARCHIVE_ENTRY_ACL_TYPE_ACCESS); -#if HAVE_SUN_ACL - free(aclp); - aclp = NULL; -#else - acl_free(acl); - acl = NULL; -#endif - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate access ACLs"); - return (r); - } - } - -#if !HAVE_SUN_ACL - /* Only directories can have default ACLs. */ - if (S_ISDIR(archive_entry_mode(entry))) { -#if HAVE_ACL_GET_FD_NP - if (*fd >= 0) - acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT); - else -#endif - acl = acl_get_file(accpath, ACL_TYPE_DEFAULT); - if (acl != NULL) { - r = translate_acl(a, entry, acl, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); - acl_free(acl); - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate default ACLs"); - return (r); - } - } - } -#endif /* !HAVE_SUN_ACL */ -#endif /* HAVE_POSIX_ACL || HAVE_SUN_ACL */ - return (ARCHIVE_OK); -} - -/* - * Translate system ACL permissions into libarchive internal structure - */ -static const struct { - const int archive_perm; - const int platform_perm; -} acl_perm_map[] = { -#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */ - {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE}, - {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE} -#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */ - {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER}, -#if HAVE_DECL_ACL_SYNCHRONIZE - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} -#endif -#else /* POSIX.1e ACL permissions */ - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE}, - {ARCHIVE_ENTRY_ACL_READ, ACL_READ}, -#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFSv4 ACL permissions */ - {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} -#endif -#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */ -}; - -#if HAVE_NFS4_ACL -/* - * Translate system NFSv4 inheritance flags into libarchive internal structure - */ -static const struct { - const int archive_inherit; - const int platform_inherit; -} acl_inherit_map[] = { -#if HAVE_SUN_NFS4_ACL /* Solaris ACL inheritance flags */ - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, - {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG}, -#ifdef ACE_INHERITED_ACE - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE} -#endif -#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */ - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT} -#else /* FreeBSD NFSv4 ACL inheritance flags */ - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}, - {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS}, - {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED} -#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */ -}; -#endif /* HAVE_NFS4_ACL */ - -#if HAVE_DARWIN_ACL -static int translate_guid(struct archive *a, acl_entry_t acl_entry, - int *ae_id, int *ae_tag, const char **ae_name) -{ - void *q; - uid_t ugid; - int r, idtype; - struct passwd *pwd; - struct group *grp; - - q = acl_get_qualifier(acl_entry); - if (q == NULL) - return (1); - r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype); - if (r != 0) { - acl_free(q); - return (1); - } - if (idtype == ID_TYPE_UID) { - *ae_tag = ARCHIVE_ENTRY_ACL_USER; - pwd = getpwuuid(q); - if (pwd == NULL) { - *ae_id = ugid; - *ae_name = NULL; - } else { - *ae_id = pwd->pw_uid; - *ae_name = archive_read_disk_uname(a, *ae_id); - } - } else if (idtype == ID_TYPE_GID) { - *ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - grp = getgruuid(q); - if (grp == NULL) { - *ae_id = ugid; - *ae_name = NULL; - } else { - *ae_id = grp->gr_gid; - *ae_name = archive_read_disk_gname(a, *ae_id); - } - } else - r = 1; - - acl_free(q); - return (r); -} - -/* - * Add trivial NFSv4 ACL entries from mode - */ -static void -add_trivial_nfs4_acl(struct archive_entry *entry) -{ - mode_t mode; - int i; - const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA; - const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA; - const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE; - const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE; - const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER; - - struct { - const int type; - const int tag; - int permset; - } tacl_entry[] = { - {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0}, - {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0}, - {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0}, - {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset}, - {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset}, - {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset} - }; - - mode = archive_entry_mode(entry); - - /* Permissions for everyone@ */ - if (mode & 0004) - tacl_entry[5].permset |= rperm; - if (mode & 0002) - tacl_entry[5].permset |= wperm; - if (mode & 0001) - tacl_entry[5].permset |= eperm; - - /* Permissions for group@ */ - if (mode & 0040) - tacl_entry[4].permset |= rperm; - else if (mode & 0004) - tacl_entry[2].permset |= rperm; - if (mode & 0020) - tacl_entry[4].permset |= wperm; - else if (mode & 0002) - tacl_entry[2].permset |= wperm; - if (mode & 0010) - tacl_entry[4].permset |= eperm; - else if (mode & 0001) - tacl_entry[2].permset |= eperm; - - /* Permissions for owner@ */ - if (mode & 0400) { - tacl_entry[3].permset |= rperm; - if (!(mode & 0040) && (mode & 0004)) - tacl_entry[0].permset |= rperm; - } else if ((mode & 0040) || (mode & 0004)) - tacl_entry[1].permset |= rperm; - if (mode & 0200) { - tacl_entry[3].permset |= wperm; - if (!(mode & 0020) && (mode & 0002)) - tacl_entry[0].permset |= wperm; - } else if ((mode & 0020) || (mode & 0002)) - tacl_entry[1].permset |= wperm; - if (mode & 0100) { - tacl_entry[3].permset |= eperm; - if (!(mode & 0010) && (mode & 0001)) - tacl_entry[0].permset |= eperm; - } else if ((mode & 0010) || (mode & 0001)) - tacl_entry[1].permset |= eperm; - - for (i = 0; i < 6; i++) { - if (tacl_entry[i].permset != 0) { - archive_entry_acl_add_entry(entry, - tacl_entry[i].type, tacl_entry[i].permset, - tacl_entry[i].tag, -1, NULL); - } - } - - return; -} -#elif HAVE_SUN_ACL -/* - * Check if acl is trivial - * This is a FreeBSD acl_is_trivial_np() implementation for Solaris - */ -static int -sun_acl_is_trivial(void *aclp, int aclcnt, mode_t mode, int is_nfs4, - int is_dir, int *trivialp) -{ - int i, p; -#if HAVE_SUN_NFS4_ACL - const uint32_t rperm = ACE_READ_DATA; - const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA; - const uint32_t eperm = ACE_EXECUTE; - const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | - ACE_READ_ACL | ACE_SYNCHRONIZE; - const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES | - ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER; - - ace_t *ace; - ace_t tace[6]; -#endif - - if (aclp == NULL || trivialp == NULL) - return (-1); - - *trivialp = 0; - - /* - * POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with - * FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries, - * including mask. - */ - if (!is_nfs4) { - if (aclcnt == 4) - *trivialp = 1; - return (0); - } - -#if HAVE_SUN_NFS4_ACL - /* - * Continue with checking NFSv4 ACLs - * - * Create list of trivial ace's to be compared - */ - - /* owner@ allow pre */ - tace[0].a_flags = ACE_OWNER; - tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - tace[0].a_access_mask = 0; - - /* owner@ deny */ - tace[1].a_flags = ACE_OWNER; - tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE; - tace[1].a_access_mask = 0; - - /* group@ deny */ - tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP; - tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE; - tace[2].a_access_mask = 0; - - /* owner@ allow */ - tace[3].a_flags = ACE_OWNER; - tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - tace[3].a_access_mask = ownset; - - /* group@ allow */ - tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP; - tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - tace[4].a_access_mask = pubset; - - /* everyone@ allow */ - tace[5].a_flags = ACE_EVERYONE; - tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - tace[5].a_access_mask = pubset; - - /* Permissions for everyone@ */ - if (mode & 0004) - tace[5].a_access_mask |= rperm; - if (mode & 0002) - tace[5].a_access_mask |= wperm; - if (mode & 0001) - tace[5].a_access_mask |= eperm; - - /* Permissions for group@ */ - if (mode & 0040) - tace[4].a_access_mask |= rperm; - else if (mode & 0004) - tace[2].a_access_mask |= rperm; - if (mode & 0020) - tace[4].a_access_mask |= wperm; - else if (mode & 0002) - tace[2].a_access_mask |= wperm; - if (mode & 0010) - tace[4].a_access_mask |= eperm; - else if (mode & 0001) - tace[2].a_access_mask |= eperm; - - /* Permissions for owner@ */ - if (mode & 0400) { - tace[3].a_access_mask |= rperm; - if (!(mode & 0040) && (mode & 0004)) - tace[0].a_access_mask |= rperm; - } else if ((mode & 0040) || (mode & 0004)) - tace[1].a_access_mask |= rperm; - if (mode & 0200) { - tace[3].a_access_mask |= wperm; - if (!(mode & 0020) && (mode & 0002)) - tace[0].a_access_mask |= wperm; - } else if ((mode & 0020) || (mode & 0002)) - tace[1].a_access_mask |= wperm; - if (mode & 0100) { - tace[3].a_access_mask |= eperm; - if (!(mode & 0010) && (mode & 0001)) - tace[0].a_access_mask |= eperm; - } else if ((mode & 0010) || (mode & 0001)) - tace[1].a_access_mask |= eperm; - - /* Check if the acl count matches */ - p = 3; - for (i = 0; i < 3; i++) { - if (tace[i].a_access_mask != 0) - p++; - } - if (aclcnt != p) - return (0); - - p = 0; - for (i = 0; i < 6; i++) { - if (tace[i].a_access_mask != 0) { - ace = &((ace_t *)aclp)[p]; - /* - * Illumos added ACE_DELETE_CHILD to write perms for - * directories. We have to check against that, too. - */ - if (ace->a_flags != tace[i].a_flags || - ace->a_type != tace[i].a_type || - (ace->a_access_mask != tace[i].a_access_mask && - (!is_dir || (tace[i].a_access_mask & wperm) == 0 || - ace->a_access_mask != - (tace[i].a_access_mask | ACE_DELETE_CHILD)))) - return (0); - p++; - } - } - - *trivialp = 1; -#else /* !HAVE_SUN_NFS4_ACL */ - (void)aclp; /* UNUSED */ -#endif /* !HAVE_SUN_NFS4_ACL */ - return (0); -} -#endif /* HAVE_SUN_ACL */ - -#if HAVE_SUN_ACL -/* - * Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL - */ -static int -translate_acl(struct archive_read_disk *a, - struct archive_entry *entry, void *aclp, int aclcnt, - int default_entry_acl_type) -{ - int e, i; - int ae_id, ae_tag, ae_perm; - int entry_acl_type; - const char *ae_name; - aclent_t *aclent; -#if HAVE_SUN_NFS4_ACL - ace_t *ace; -#endif - - if (aclcnt <= 0) - return (ARCHIVE_OK); - - for (e = 0; e < aclcnt; e++) { - ae_name = NULL; - ae_tag = 0; - ae_perm = 0; - -#if HAVE_SUN_NFS4_ACL - if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - ace = &((ace_t *)aclp)[e]; - ae_id = ace->a_who; - - switch(ace->a_type) { - case ACE_ACCESS_ALLOWED_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - break; - case ACE_ACCESS_DENIED_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - break; - case ACE_SYSTEM_AUDIT_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - break; - case ACE_SYSTEM_ALARM_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; - break; - default: - /* Unknown entry type, skip */ - continue; - } - - if ((ace->a_flags & ACE_OWNER) != 0) - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - else if ((ace->a_flags & ACE_GROUP) != 0) - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - else if ((ace->a_flags & ACE_EVERYONE) != 0) - ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE; - else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) { - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - ae_name = archive_read_disk_gname(&a->archive, - ae_id); - } else { - ae_tag = ARCHIVE_ENTRY_ACL_USER; - ae_name = archive_read_disk_uname(&a->archive, - ae_id); - } - - for (i = 0; i < (int)(sizeof(acl_inherit_map) / - sizeof(acl_inherit_map[0])); ++i) { - if ((ace->a_flags & - acl_inherit_map[i].platform_inherit) != 0) - ae_perm |= - acl_inherit_map[i].archive_inherit; - } - - for (i = 0; i < (int)(sizeof(acl_perm_map) / - sizeof(acl_perm_map[0])); ++i) { - if ((ace->a_access_mask & - acl_perm_map[i].platform_perm) != 0) - ae_perm |= - acl_perm_map[i].archive_perm; - } - } else -#endif /* HAVE_SUN_NFS4_ACL */ - if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) { - aclent = &((aclent_t *)aclp)[e]; - if ((aclent->a_type & ACL_DEFAULT) != 0) - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; - else - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - ae_id = aclent->a_id; - - switch(aclent->a_type) { - case DEF_USER: - case USER: - ae_name = archive_read_disk_uname(&a->archive, - ae_id); - ae_tag = ARCHIVE_ENTRY_ACL_USER; - break; - case DEF_GROUP: - case GROUP: - ae_name = archive_read_disk_gname(&a->archive, - ae_id); - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - break; - case DEF_CLASS_OBJ: - case CLASS_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_MASK; - break; - case DEF_USER_OBJ: - case USER_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - break; - case DEF_GROUP_OBJ: - case GROUP_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case DEF_OTHER_OBJ: - case OTHER_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_OTHER; - break; - default: - /* Unknown tag type, skip */ - continue; - } - - if ((aclent->a_perm & 1) != 0) - ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE; - if ((aclent->a_perm & 2) != 0) - ae_perm |= ARCHIVE_ENTRY_ACL_WRITE; - if ((aclent->a_perm & 4) != 0) - ae_perm |= ARCHIVE_ENTRY_ACL_READ; - } else - return (ARCHIVE_WARN); - - archive_entry_acl_add_entry(entry, entry_acl_type, - ae_perm, ae_tag, ae_id, ae_name); - } - return (ARCHIVE_OK); -} -#else /* !HAVE_SUN_ACL */ -/* - * Translate POSIX.1e (Linux), FreeBSD (both POSIX.1e and NFSv4) and - * MacOS (NFSv4 only) ACLs into libarchive internal structure - */ -static int -translate_acl(struct archive_read_disk *a, - struct archive_entry *entry, acl_t acl, int default_entry_acl_type) -{ - acl_tag_t acl_tag; -#if HAVE_FREEBSD_NFS4_ACL - acl_entry_type_t acl_type; - int brand; -#endif -#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL - acl_flagset_t acl_flagset; -#endif - acl_entry_t acl_entry; - acl_permset_t acl_permset; - int i, entry_acl_type; - int r, s, ae_id, ae_tag, ae_perm; -#if !HAVE_DARWIN_ACL - void *q; -#endif - const char *ae_name; - -#if HAVE_FREEBSD_NFS4_ACL - // FreeBSD "brands" ACLs as POSIX.1e or NFSv4 - // Make sure the "brand" on this ACL is consistent - // with the default_entry_acl_type bits provided. - if (acl_get_brand_np(acl, &brand) != 0) { - archive_set_error(&a->archive, errno, - "Failed to read ACL brand"); - return (ARCHIVE_WARN); - } - switch (brand) { - case ACL_BRAND_POSIX: - switch (default_entry_acl_type) { - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid ACL entry type for POSIX.1e ACL"); - return (ARCHIVE_WARN); - } - break; - case ACL_BRAND_NFS4: - if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid ACL entry type for NFSv4 ACL"); - return (ARCHIVE_WARN); - } - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Unknown ACL brand"); - return (ARCHIVE_WARN); - } -#endif - - s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get first ACL entry"); - return (ARCHIVE_WARN); - } - -#if HAVE_DARWIN_ACL - while (s == 0) -#else /* FreeBSD, Linux */ - while (s == 1) -#endif - { - ae_id = -1; - ae_name = NULL; - ae_perm = 0; - - if (acl_get_tag_type(acl_entry, &acl_tag) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL tag type"); - return (ARCHIVE_WARN); - } - switch (acl_tag) { -#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */ - case ACL_USER: - q = acl_get_qualifier(acl_entry); - if (q != NULL) { - ae_id = (int)*(uid_t *)q; - acl_free(q); - ae_name = archive_read_disk_uname(&a->archive, - ae_id); - } - ae_tag = ARCHIVE_ENTRY_ACL_USER; - break; - case ACL_GROUP: - q = acl_get_qualifier(acl_entry); - if (q != NULL) { - ae_id = (int)*(gid_t *)q; - acl_free(q); - ae_name = archive_read_disk_gname(&a->archive, - ae_id); - } - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - break; - case ACL_MASK: - ae_tag = ARCHIVE_ENTRY_ACL_MASK; - break; - case ACL_USER_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - break; - case ACL_GROUP_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case ACL_OTHER: - ae_tag = ARCHIVE_ENTRY_ACL_OTHER; - break; -#if HAVE_FREEBSD_NFS4_ACL - case ACL_EVERYONE: - ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE; - break; -#endif -#else /* HAVE_DARWIN_ACL */ - case ACL_EXTENDED_ALLOW: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - r = translate_guid(&a->archive, acl_entry, &ae_id, - &ae_tag, &ae_name); - break; - case ACL_EXTENDED_DENY: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - r = translate_guid(&a->archive, acl_entry, &ae_id, - &ae_tag, &ae_name); - break; -#endif /* HAVE_DARWIN_ACL */ - default: - /* Skip types that libarchive can't support. */ - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - continue; - } - -#if HAVE_DARWIN_ACL - /* Skip if translate_guid() above failed */ - if (r != 0) { - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - continue; - } -#endif - -#if !HAVE_DARWIN_ACL - // XXX acl_type maps to allow/deny/audit/YYYY bits - entry_acl_type = default_entry_acl_type; -#endif -#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL - if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { -#if HAVE_FREEBSD_NFS4_ACL - /* - * acl_get_entry_type_np() fails with non-NFSv4 ACLs - */ - if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) { - archive_set_error(&a->archive, errno, "Failed " - "to get ACL type from a NFSv4 ACL entry"); - return (ARCHIVE_WARN); - } - switch (acl_type) { - case ACL_ENTRY_TYPE_ALLOW: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - break; - case ACL_ENTRY_TYPE_DENY: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - break; - case ACL_ENTRY_TYPE_AUDIT: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT; - break; - case ACL_ENTRY_TYPE_ALARM: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; - break; - default: - archive_set_error(&a->archive, errno, - "Invalid NFSv4 ACL entry type"); - return (ARCHIVE_WARN); - } -#endif /* HAVE_FREEBSD_NFS4_ACL */ - - /* - * Libarchive stores "flag" (NFSv4 inheritance bits) - * in the ae_perm bitmap. - * - * acl_get_flagset_np() fails with non-NFSv4 ACLs - */ - if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get flagset from a NFSv4 ACL entry"); - return (ARCHIVE_WARN); - } - for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) { - r = acl_get_flag_np(acl_flagset, - acl_inherit_map[i].platform_inherit); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to check flag in a NFSv4 " - "ACL flagset"); - return (ARCHIVE_WARN); - } else if (r) - ae_perm |= acl_inherit_map[i].archive_inherit; - } - } -#endif /* HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL */ - - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL permission set"); - return (ARCHIVE_WARN); - } - for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) { - /* - * acl_get_perm() is spelled differently on different - * platforms; see above. - */ - r = ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to check permission in an ACL permission set"); - return (ARCHIVE_WARN); - } else if (r) - ae_perm |= acl_perm_map[i].archive_perm; - } - -#if HAVE_DARWIN_ACL && !HAVE_DECL_ACL_SYNCHRONIZE - /* On Mac OS X without ACL_SYNCHRONIZE assume it is set */ - ae_perm |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE; -#endif - - archive_entry_acl_add_entry(entry, entry_acl_type, - ae_perm, ae_tag, - ae_id, ae_name); - - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); -#if !HAVE_DARWIN_ACL - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get next ACL entry"); - return (ARCHIVE_WARN); - } -#endif - } - return (ARCHIVE_OK); -} -#endif /* !HAVE_SUN_ACL */ -#else /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */ -static int -setup_acls(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - (void)a; /* UNUSED */ - (void)entry; /* UNUSED */ - (void)fd; /* UNUSED */ - return (ARCHIVE_OK); -} -#endif /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */ - #if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \ HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \ (HAVE_FGETEA && HAVE_FLISTEA && HAVE_LISTEA) @@ -1623,21 +512,9 @@ setup_xattrs(struct archive_read_disk *a, path = NULL; if (*fd < 0) { - path = archive_entry_sourcepath(entry); - if (path == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - path = archive_entry_pathname(entry); - if (path == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read " - "extended attributes"); + path = archive_read_disk_entry_setup_path(a, entry, fd); + if (path == NULL) return (ARCHIVE_WARN); - } - if (a->tree != NULL && (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - path, O_RDONLY | O_NONBLOCK); - } } #if HAVE_FLISTXATTR @@ -1782,21 +659,9 @@ setup_xattrs(struct archive_read_disk *a, path = NULL; if (*fd < 0) { - path = archive_entry_sourcepath(entry); - if (path == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - path = archive_entry_pathname(entry); - if (path == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine file path to read " - "extended attributes"); + path = archive_read_disk_entry_setup_path(a, entry, fd); + if (path == NULL) return (ARCHIVE_WARN); - } - if (a->tree != NULL && (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, - path, O_RDONLY | O_NONBLOCK); - } } if (*fd >= 0) @@ -1897,6 +762,7 @@ setup_sparse_fiemap(struct archive_read_disk *a, int64_t size; int count, do_fiemap, iters; int exit_sts = ARCHIVE_OK; + const char *path; if (archive_entry_filetype(entry) != AE_IFREG || archive_entry_size(entry) <= 0 @@ -1904,11 +770,10 @@ setup_sparse_fiemap(struct archive_read_disk *a, return (ARCHIVE_OK); if (*fd < 0) { - const char *path; - - path = archive_entry_sourcepath(entry); + path = archive_read_disk_entry_setup_path(a, entry, NULL); if (path == NULL) - path = archive_entry_pathname(entry); + return (ARCHIVE_FAILED); + if (a->tree != NULL) *fd = a->open_on_current_dir(a->tree, path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); @@ -2004,6 +869,7 @@ setup_sparse(struct archive_read_disk *a, off_t off_s, off_e; int exit_sts = ARCHIVE_OK; int check_fully_sparse = 0; + const char *path; if (archive_entry_filetype(entry) != AE_IFREG || archive_entry_size(entry) <= 0 @@ -2011,19 +877,10 @@ setup_sparse(struct archive_read_disk *a, return (ARCHIVE_OK); /* Does filesystem support the reporting of hole ? */ - if (*fd < 0 && a->tree != NULL) { - const char *path; - - path = archive_entry_sourcepath(entry); + if (*fd < 0) { + path = archive_read_disk_entry_setup_path(a, entry, fd); if (path == NULL) - path = archive_entry_pathname(entry); - *fd = a->open_on_current_dir(a->tree, path, - O_RDONLY | O_NONBLOCK); - if (*fd < 0) { - archive_set_error(&a->archive, errno, - "Can't open `%s'", path); return (ARCHIVE_FAILED); - } } if (*fd >= 0) { @@ -2035,12 +892,6 @@ setup_sparse(struct archive_read_disk *a, if (initial_off != 0) lseek(*fd, 0, SEEK_SET); } else { - const char *path; - - path = archive_entry_sourcepath(entry); - if (path == NULL) - path = archive_entry_pathname(entry); - #ifdef _PC_MIN_HOLE_SIZE if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0) return (ARCHIVE_OK); diff --git a/contrib/libarchive/libarchive/archive_read_disk_private.h b/contrib/libarchive/libarchive/archive_read_disk_private.h index 3f55133ec3c6..34691fc1e5d2 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_private.h +++ b/contrib/libarchive/libarchive/archive_read_disk_private.h @@ -33,6 +33,8 @@ #ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED #define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED +#include "archive_platform_acl.h" + struct tree; struct archive_entry; @@ -86,4 +88,11 @@ struct archive_read_disk { void *excluded_cb_data; }; +const char * +archive_read_disk_entry_setup_path(struct archive_read_disk *, + struct archive_entry *, int *); + +int +archive_read_disk_entry_setup_acls(struct archive_read_disk *, + struct archive_entry *, int *); #endif diff --git a/contrib/libarchive/libarchive/archive_read_open.3 b/contrib/libarchive/libarchive/archive_read_open.3 index 02494560da4d..2278ebc330c3 100644 --- a/contrib/libarchive/libarchive/archive_read_open.3 +++ b/contrib/libarchive/libarchive/archive_read_open.3 @@ -67,7 +67,7 @@ Streaming Archive Library (libarchive, -larchive) .Fa "size_t block_size" .Fc .Ft int -.Fn archive_read_open_memory "struct archive *" "void *buff" "size_t size" +.Fn archive_read_open_memory "struct archive *" "const void *buff" "size_t size" .Sh DESCRIPTION .Bl -tag -compact -width indent .It Fn archive_read_open diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c index eb695f8b10fe..bc3c0b1976e4 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c @@ -1857,33 +1857,38 @@ mtree_atol8(char **p) * Note that this implementation does not (and should not!) obey * locale settings; you cannot simply substitute strtol here, since * it does obey locale. + * + * Convert the number pointed to by 'p' into a 64-bit signed integer. + * On return, 'p' points to the first non-digit following the number. + * On overflow, the function returns INT64_MIN or INT64_MAX. */ static int64_t mtree_atol10(char **p) { - int64_t l, limit, last_digit_limit; - int base, digit, sign; - - base = 10; + const int base = 10; + const int64_t limit = INT64_MAX / base; + const int64_t last_digit_limit = INT64_MAX % base; + int64_t l; + int sign; if (**p == '-') { sign = -1; - limit = ((uint64_t)(INT64_MAX) + 1) / base; - last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base; ++(*p); } else { sign = 1; - limit = INT64_MAX / base; - last_digit_limit = INT64_MAX % base; } l = 0; - digit = **p - '0'; - while (digit >= 0 && digit < base) { - if (l > limit || (l == limit && digit > last_digit_limit)) + while (**p >= '0' && **p < '0' + base) { + int digit = **p - '0'; + if (l > limit || (l == limit && digit > last_digit_limit)) { + while (**p >= '0' && **p < '0' + base) { + ++(*p); + } return (sign < 0) ? INT64_MIN : INT64_MAX; + } l = (l * base) + digit; - digit = *++(*p) - '0'; + ++(*p); } return (sign < 0) ? -l : l; } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libarchive/libarchive/archive_read_support_format_tar.c index fa63d2f4f391..e956f40cd6ad 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_tar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_tar.c @@ -155,6 +155,7 @@ struct tar { int compat_2x; int process_mac_extensions; int read_concatenated_archives; + int realsize_override; }; static int archive_block_is_null(const char *p); @@ -527,6 +528,7 @@ archive_read_format_tar_read_header(struct archive_read *a, tar->entry_offset = 0; gnu_clear_sparse_list(tar); tar->realsize = -1; /* Mark this as "unset" */ + tar->realsize_override = 0; /* Setup default string conversion. */ tar->sconv = tar->opt_sconv; @@ -1896,6 +1898,7 @@ pax_attribute(struct archive_read *a, struct tar *tar, if (strcmp(key, "GNU.sparse.size") == 0) { tar->realsize = tar_atol10(value, strlen(value)); archive_entry_set_size(entry, tar->realsize); + tar->realsize_override = 1; } /* GNU "0.1" sparse pax format. */ @@ -1927,6 +1930,7 @@ pax_attribute(struct archive_read *a, struct tar *tar, if (strcmp(key, "GNU.sparse.realsize") == 0) { tar->realsize = tar_atol10(value, strlen(value)); archive_entry_set_size(entry, tar->realsize); + tar->realsize_override = 1; } break; case 'L': @@ -1979,6 +1983,7 @@ pax_attribute(struct archive_read *a, struct tar *tar, tar_atol10(value, strlen(value))); } else if (strcmp(key, "SCHILY.realsize") == 0) { tar->realsize = tar_atol10(value, strlen(value)); + tar->realsize_override = 1; archive_entry_set_size(entry, tar->realsize); } else if (strncmp(key, "SCHILY.xattr.", 13) == 0) { pax_attribute_schily_xattr(entry, key, value, @@ -2057,14 +2062,12 @@ pax_attribute(struct archive_read *a, struct tar *tar, tar->entry_bytes_remaining = tar_atol10(value, strlen(value)); /* - * But, "size" is not necessarily the size of - * the file on disk; if this is a sparse file, - * the disk size may have already been set from - * GNU.sparse.realsize or GNU.sparse.size or - * an old GNU header field or SCHILY.realsize - * or .... + * The "size" pax header keyword always overrides the + * "size" field in the tar header. + * GNU.sparse.realsize, GNU.sparse.size and + * SCHILY.realsize override this value. */ - if (tar->realsize < 0) { + if (!tar->realsize_override) { archive_entry_set_size(entry, tar->entry_bytes_remaining); tar->realsize @@ -2208,6 +2211,7 @@ header_gnutar(struct archive_read *a, struct tar *tar, tar->realsize = tar_atol(header->realsize, sizeof(header->realsize)); archive_entry_set_size(entry, tar->realsize); + tar->realsize_override = 1; } if (header->sparse[0].offset[0] != 0) { diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c index 10dc14dfaee5..960cbe39fb6a 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c @@ -2407,7 +2407,7 @@ read_eocd(struct zip *zip, const char *p, int64_t current_offset) * Examine Zip64 EOCD locator: If it's valid, store the information * from it. */ -static void +static int read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p) { int64_t eocd64_offset; @@ -2417,35 +2417,37 @@ read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p) /* Central dir must be on first volume. */ if (archive_le32dec(p + 4) != 0) - return; + return 0; /* Must be only a single volume. */ if (archive_le32dec(p + 16) != 1) - return; + return 0; /* Find the Zip64 EOCD record. */ eocd64_offset = archive_le64dec(p + 8); if (__archive_read_seek(a, eocd64_offset, SEEK_SET) < 0) - return; + return 0; if ((p = __archive_read_ahead(a, 56, NULL)) == NULL) - return; + return 0; /* Make sure we can read all of it. */ eocd64_size = archive_le64dec(p + 4) + 12; if (eocd64_size < 56 || eocd64_size > 16384) - return; + return 0; if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL) - return; + return 0; /* Sanity-check the EOCD64 */ if (archive_le32dec(p + 16) != 0) /* Must be disk #0 */ - return; + return 0; if (archive_le32dec(p + 20) != 0) /* CD must be on disk #0 */ - return; + return 0; /* CD can't be split. */ if (archive_le64dec(p + 24) != archive_le64dec(p + 32)) - return; + return 0; /* Save the central directory offset for later use. */ zip->central_directory_offset = archive_le64dec(p + 48); + + return 32; } static int @@ -2483,15 +2485,14 @@ archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid) if (memcmp(p + i, "PK\005\006", 4) == 0) { int ret = read_eocd(zip, p + i, current_offset + i); - if (ret > 0) { - /* Zip64 EOCD locator precedes - * regular EOCD if present. */ - if (i >= 20 - && memcmp(p + i - 20, "PK\006\007", 4) == 0) { - read_zip64_eocd(a, zip, p + i - 20); - } - return (ret); + /* Zip64 EOCD locator precedes + * regular EOCD if present. */ + if (i >= 20 && memcmp(p + i - 20, "PK\006\007", 4) == 0) { + int ret_zip64 = read_zip64_eocd(a, zip, p + i - 20); + if (ret_zip64 > ret) + ret = ret_zip64; } + return (ret); } i -= 4; break; diff --git a/contrib/libarchive/libarchive/archive_util.c b/contrib/libarchive/libarchive/archive_util.c index 05f17c5b6de7..183bcf25da9b 100644 --- a/contrib/libarchive/libarchive/archive_util.c +++ b/contrib/libarchive/libarchive/archive_util.c @@ -89,88 +89,6 @@ archive_version_string(void) return (ARCHIVE_VERSION_STRING); } -const char * -archive_version_details(void) -{ - static struct archive_string str; - static int init = 0; - const char *zlib = archive_zlib_version(); - const char *liblzma = archive_liblzma_version(); - const char *bzlib = archive_bzlib_version(); - const char *liblz4 = archive_liblz4_version(); - - if (!init) { - archive_string_init(&str); - - archive_strcat(&str, ARCHIVE_VERSION_STRING); - if (zlib != NULL) { - archive_strcat(&str, " zlib/"); - archive_strcat(&str, zlib); - } - if (liblzma) { - archive_strcat(&str, " liblzma/"); - archive_strcat(&str, liblzma); - } - if (bzlib) { - const char *p = bzlib; - const char *sep = strchr(p, ','); - if (sep == NULL) - sep = p + strlen(p); - archive_strcat(&str, " bz2lib/"); - archive_strncat(&str, p, sep - p); - } - if (liblz4) { - archive_strcat(&str, " liblz4/"); - archive_strcat(&str, liblz4); - } - } - return str.s; -} - -const char * -archive_zlib_version(void) -{ -#ifdef HAVE_ZLIB_H - return ZLIB_VERSION; -#else - return NULL; -#endif -} - -const char * -archive_liblzma_version(void) -{ -#ifdef HAVE_LZMA_H - return LZMA_VERSION_STRING; -#else - return NULL; -#endif -} - -const char * -archive_bzlib_version(void) -{ -#ifdef HAVE_BZLIB_H - return BZ2_bzlibVersion(); -#else - return NULL; -#endif -} - -const char * -archive_liblz4_version(void) -{ -#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4) -#define str(s) #s -#define NUMBER(x) str(x) - return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE); -#undef NUMBER -#undef str -#else - return NULL; -#endif -} - int archive_errno(struct archive *a) { diff --git a/contrib/libarchive/libarchive/archive_version_details.c b/contrib/libarchive/libarchive/archive_version_details.c new file mode 100644 index 000000000000..e10b83e5b7e4 --- /dev/null +++ b/contrib/libarchive/libarchive/archive_version_details.c @@ -0,0 +1,133 @@ +/*- + * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA + * Copyright (c) 2003-2007 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 "archive_platform.h" +__FBSDID("$FreeBSD$"); + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#ifdef HAVE_ZLIB_H +#include <zlib.h> +#endif +#ifdef HAVE_LZMA_H +#include <lzma.h> +#endif +#ifdef HAVE_BZLIB_H +#include <bzlib.h> +#endif +#ifdef HAVE_LZ4_H +#include <lz4.h> +#endif + +#include "archive.h" +#include "archive_private.h" +#include "archive_string.h" + +const char * +archive_version_details(void) +{ + static struct archive_string str; + static int init = 0; + const char *zlib = archive_zlib_version(); + const char *liblzma = archive_liblzma_version(); + const char *bzlib = archive_bzlib_version(); + const char *liblz4 = archive_liblz4_version(); + + if (!init) { + archive_string_init(&str); + + archive_strcat(&str, ARCHIVE_VERSION_STRING); + if (zlib != NULL) { + archive_strcat(&str, " zlib/"); + archive_strcat(&str, zlib); + } + if (liblzma) { + archive_strcat(&str, " liblzma/"); + archive_strcat(&str, liblzma); + } + if (bzlib) { + const char *p = bzlib; + const char *sep = strchr(p, ','); + if (sep == NULL) + sep = p + strlen(p); + archive_strcat(&str, " bz2lib/"); + archive_strncat(&str, p, sep - p); + } + if (liblz4) { + archive_strcat(&str, " liblz4/"); + archive_strcat(&str, liblz4); + } + } + return str.s; +} + +const char * +archive_zlib_version(void) +{ +#ifdef HAVE_ZLIB_H + return ZLIB_VERSION; +#else + return NULL; +#endif +} + +const char * +archive_liblzma_version(void) +{ +#ifdef HAVE_LZMA_H + return LZMA_VERSION_STRING; +#else + return NULL; +#endif +} + +const char * +archive_bzlib_version(void) +{ +#ifdef HAVE_BZLIB_H + return BZ2_bzlibVersion(); +#else + return NULL; +#endif +} + +const char * +archive_liblz4_version(void) +{ +#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4) +#define str(s) #s +#define NUMBER(x) str(x) + return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE); +#undef NUMBER +#undef str +#else + return NULL; +#endif +} diff --git a/contrib/libarchive/libarchive/archive_write_disk_acl.c b/contrib/libarchive/libarchive/archive_write_disk_acl.c deleted file mode 100644 index 643f3c3a0733..000000000000 --- a/contrib/libarchive/libarchive/archive_write_disk_acl.c +++ /dev/null @@ -1,697 +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 - * in this position and unchanged. - * 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 "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 05:35:40Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include <sys/acl.h> -#endif -#if HAVE_DARWIN_ACL -#include <membership.h> -#endif -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_acl_private.h" -#include "archive_write_disk_private.h" - -#if !HAVE_POSIX_ACL && !HAVE_NFS4_ACL -/* Default empty function body to satisfy mainline code. */ -int -archive_write_disk_set_acls(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl) -{ - (void)a; /* UNUSED */ - (void)fd; /* UNUSED */ - (void)name; /* UNUSED */ - (void)abstract_acl; /* UNUSED */ - return (ARCHIVE_OK); -} - -#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */ - -#if HAVE_DARWIN_ACL -#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED -#elif HAVE_FREEBSD_NFS4_ACL -#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4 -#endif - -static int set_acl(struct archive *, int fd, const char *, - struct archive_acl *, -#if !HAVE_SUN_ACL - acl_type_t, -#endif - int archive_entry_acl_type, const char *tn); - -int -archive_write_disk_set_acls(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl) -{ - int ret = ARCHIVE_OK; - -#if !HAVE_DARWIN_ACL - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { -#if HAVE_SUN_ACL - /* Solaris writes POSIX.1e access and default ACLs together */ - ret = set_acl(a, fd, name, abstract_acl, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e"); -#else /* HAVE_POSIX_ACL */ - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - ret = set_acl(a, fd, name, abstract_acl, - ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - "access"); - if (ret != ARCHIVE_OK) - return (ret); - } - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) - ret = set_acl(a, fd, name, abstract_acl, - ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, - "default"); -#endif /* !HAVE_SUN_ACL */ - /* Simultaneous POSIX.1e and NFSv4 is not supported */ - return (ret); - } -#endif /* !HAVE_DARWIN_ACL */ -#if HAVE_NFS4_ACL - if ((archive_acl_types(abstract_acl) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - ret = set_acl(a, fd, name, abstract_acl, -#if !HAVE_SUN_ACL - ARCHIVE_PLATFORM_ACL_TYPE_NFS4, -#endif - ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4"); - } -#endif /* HAVE_NFS4_ACL */ - return (ret); -} - -#if !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL -/* - * Translate system ACL permissions into libarchive internal structure - */ -static const struct { - const int archive_perm; - const int platform_perm; -} acl_perm_map[] = { -#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */ - {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE}, - {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE} -#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */ - {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER}, -#if HAVE_DECL_ACL_SYNCHRONIZE - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} -#endif -#else /* POSIX.1e ACL permissions */ - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE}, - {ARCHIVE_ENTRY_ACL_READ, ACL_READ}, -#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFSv4 ACL permissions */ - {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} -#endif -#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */ -}; -#endif /* !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL */ - -#if HAVE_NFS4_ACL -/* - * Translate system NFSv4 inheritance flags into libarchive internal structure - */ -static const struct { - const int archive_inherit; - const int platform_inherit; -} acl_inherit_map[] = { -#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 inheritance flags */ - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, - {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG}, -#ifdef ACE_INHERITED_ACE - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE} -#endif -#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */ - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT} -#else /* FreeBSD NFSv4 ACL inheritance flags */ - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}, - {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS}, - {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED} -#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */ -}; -#endif /* HAVE_NFS4_ACL */ - -static int -set_acl(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, -#if !HAVE_SUN_ACL - acl_type_t acl_type, -#endif - int ae_requested_type, const char *tname) -{ -#if HAVE_SUN_ACL - aclent_t *aclent; -#if HAVE_SUN_NFS4_ACL - ace_t *ace; -#endif - int cmd, e, r; - void *aclp; -#else - acl_t acl; - acl_entry_t acl_entry; - acl_permset_t acl_permset; -#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL - acl_flagset_t acl_flagset; -#endif -#endif /* HAVE_SUN_ACL */ -#if HAVE_FREEBSD_NFS4_ACL - int r; -#endif - int ret; - int ae_type, ae_permset, ae_tag, ae_id; -#if HAVE_DARWIN_ACL - uuid_t ae_uuid; -#endif - uid_t ae_uid; - gid_t ae_gid; - const char *ae_name; - int entries; - int i; - - ret = ARCHIVE_OK; - entries = archive_acl_reset(abstract_acl, ae_requested_type); - if (entries == 0) - return (ARCHIVE_OK); - -#if HAVE_SUN_ACL - switch (ae_requested_type) { - case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E: - cmd = SETACL; - aclp = malloc(entries * sizeof(aclent_t)); - break; -#if HAVE_SUN_NFS4_ACL - case ARCHIVE_ENTRY_ACL_TYPE_NFS4: - cmd = ACE_SETACL; - aclp = malloc(entries * sizeof(ace_t)); - break; -#endif - default: - errno = ENOENT; - archive_set_error(a, errno, "Invalid ACL type"); - return (ARCHIVE_FAILED); - } - - if (aclp == NULL) { - archive_set_error(a, errno, - "Can't allocate memory for acl buffer"); - return (ARCHIVE_FAILED); - } -#else /* !HAVE_SUN_ACL */ - acl = acl_init(entries); - if (acl == (acl_t)NULL) { - archive_set_error(a, errno, - "Failed to initialize ACL working storage"); - return (ARCHIVE_FAILED); - } -#endif /* !HAVE_SUN_ACL */ -#if HAVE_SUN_ACL - e = 0; -#endif - while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, - &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { -#if HAVE_SUN_ACL - aclent = NULL; -#if HAVE_SUN_NFS4_ACL - ace = NULL; -#endif - if (cmd == SETACL) { - aclent = &((aclent_t *)aclp)[e]; - aclent->a_id = -1; - aclent->a_type = 0; - aclent->a_perm = 0; - } -#if HAVE_SUN_NFS4_ACL - else { /* cmd == ACE_SETACL */ - ace = &((ace_t *)aclp)[e]; - ace->a_who = -1; - ace->a_access_mask = 0; - ace->a_flags = 0; - } -#endif /* HAVE_SUN_NFS4_ACL */ -#else /* !HAVE_SUN_ACL */ -#if HAVE_DARWIN_ACL - /* - * Mac OS doesn't support NFSv4 ACLs for - * owner@, group@ and everyone@. - * We skip any of these ACLs found. - */ - if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ || - ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ || - ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE) - continue; -#endif - if (acl_create_entry(&acl, &acl_entry) != 0) { - archive_set_error(a, errno, - "Failed to create a new ACL entry"); - ret = ARCHIVE_FAILED; - goto exit_free; - } -#endif /* !HAVE_SUN_ACL */ -#if HAVE_DARWIN_ACL - switch (ae_type) { - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW); - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY); - break; - default: - /* We don't support any other types on MacOS */ - continue; - } -#endif - switch (ae_tag) { -#if HAVE_SUN_ACL - case ARCHIVE_ENTRY_ACL_USER: - ae_uid = archive_write_disk_uid(a, ae_name, ae_id); - if (aclent != NULL) { - aclent->a_id = ae_uid; - aclent->a_type |= USER; - } -#if HAVE_SUN_NFS4_ACL - else { - ace->a_who = ae_uid; - } -#endif - break; - case ARCHIVE_ENTRY_ACL_GROUP: - ae_gid = archive_write_disk_gid(a, ae_name, ae_id); - if (aclent != NULL) { - aclent->a_id = ae_gid; - aclent->a_type |= GROUP; - } -#if HAVE_SUN_NFS4_ACL - else { - ace->a_who = ae_gid; - ace->a_flags |= ACE_IDENTIFIER_GROUP; - } -#endif - break; - case ARCHIVE_ENTRY_ACL_USER_OBJ: - if (aclent != NULL) - aclent->a_type |= USER_OBJ; -#if HAVE_SUN_NFS4_ACL - else { - ace->a_flags |= ACE_OWNER; - } -#endif - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - if (aclent != NULL) - aclent->a_type |= GROUP_OBJ; -#if HAVE_SUN_NFS4_ACL - else { - ace->a_flags |= ACE_GROUP; - ace->a_flags |= ACE_IDENTIFIER_GROUP; - } - -#endif - break; - case ARCHIVE_ENTRY_ACL_MASK: - if (aclent != NULL) - aclent->a_type |= CLASS_OBJ; - break; - case ARCHIVE_ENTRY_ACL_OTHER: - if (aclent != NULL) - aclent->a_type |= OTHER_OBJ; - break; -#if HAVE_SUN_NFS4_ACL - case ARCHIVE_ENTRY_ACL_EVERYONE: - if (ace != NULL) - ace->a_flags |= ACE_EVERYONE; - break; -#endif -#else /* !HAVE_SUN_ACL */ - case ARCHIVE_ENTRY_ACL_USER: - ae_uid = archive_write_disk_uid(a, ae_name, ae_id); -#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */ - acl_set_tag_type(acl_entry, ACL_USER); - acl_set_qualifier(acl_entry, &ae_uid); -#else /* MacOS */ - if (mbr_identifier_to_uuid(ID_TYPE_UID, &ae_uid, - sizeof(uid_t), ae_uuid) != 0) - continue; - if (acl_set_qualifier(acl_entry, &ae_uuid) != 0) - continue; -#endif /* HAVE_DARWIN_ACL */ - break; - case ARCHIVE_ENTRY_ACL_GROUP: - ae_gid = archive_write_disk_gid(a, ae_name, ae_id); -#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */ - acl_set_tag_type(acl_entry, ACL_GROUP); - acl_set_qualifier(acl_entry, &ae_gid); -#else /* MacOS */ - if (mbr_identifier_to_uuid(ID_TYPE_GID, &ae_gid, - sizeof(gid_t), ae_uuid) != 0) - continue; - if (acl_set_qualifier(acl_entry, &ae_uuid) != 0) - continue; -#endif /* HAVE_DARWIN_ACL */ - break; -#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */ - case ARCHIVE_ENTRY_ACL_USER_OBJ: - acl_set_tag_type(acl_entry, ACL_USER_OBJ); - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - acl_set_tag_type(acl_entry, ACL_GROUP_OBJ); - break; - case ARCHIVE_ENTRY_ACL_MASK: - acl_set_tag_type(acl_entry, ACL_MASK); - break; - case ARCHIVE_ENTRY_ACL_OTHER: - acl_set_tag_type(acl_entry, ACL_OTHER); - break; -#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD only */ - case ARCHIVE_ENTRY_ACL_EVERYONE: - acl_set_tag_type(acl_entry, ACL_EVERYONE); - break; -#endif -#endif /* !HAVE_DARWIN_ACL */ -#endif /* !HAVE_SUN_ACL */ - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unknown ACL tag"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - -#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL - r = 0; - switch (ae_type) { -#if HAVE_SUN_ACL -#if HAVE_SUN_NFS4_ACL - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - if (ace != NULL) - ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - else - r = -1; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - if (ace != NULL) - ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE; - else - r = -1; - break; - case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: - if (ace != NULL) - ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE; - else - r = -1; - break; - case ARCHIVE_ENTRY_ACL_TYPE_ALARM: - if (ace != NULL) - ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE; - else - r = -1; - break; -#endif - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - if (aclent == NULL) - r = -1; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - if (aclent != NULL) - aclent->a_type |= ACL_DEFAULT; - else - r = -1; - break; -#else /* !HAVE_SUN_ACL */ - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW); - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY); - break; - case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: - r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT); - break; - case ARCHIVE_ENTRY_ACL_TYPE_ALARM: - r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM); - break; - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - // These don't translate directly into the system ACL. - break; -#endif /* !HAVE_SUN_ACL */ - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL entry type"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - if (r != 0) { -#if HAVE_SUN_ACL - errno = EINVAL; -#endif - archive_set_error(a, errno, - "Failed to set ACL entry type"); - ret = ARCHIVE_FAILED; - goto exit_free; - } -#endif /* HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL */ - -#if HAVE_SUN_ACL - if (aclent != NULL) { - if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE) - aclent->a_perm |= 1; - if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE) - aclent->a_perm |= 2; - if (ae_permset & ARCHIVE_ENTRY_ACL_READ) - aclent->a_perm |= 4; - } -#if HAVE_SUN_NFS4_ACL - else /* falls through to for statement below, ace != NULL */ -#endif -#else - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to get ACL permission set"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - if (acl_clear_perms(acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to clear ACL permissions"); - ret = ARCHIVE_FAILED; - goto exit_free; - } -#endif /* !HAVE_SUN_ACL */ -#if HAVE_POSIX_ACL || HAVE_NFS4_ACL - for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) { - if (ae_permset & acl_perm_map[i].archive_perm) { -#if HAVE_SUN_ACL - ace->a_access_mask |= - acl_perm_map[i].platform_perm; -#else - if (acl_add_perm(acl_permset, - acl_perm_map[i].platform_perm) != 0) { - archive_set_error(a, errno, - "Failed to add ACL permission"); - ret = ARCHIVE_FAILED; - goto exit_free; - } -#endif - } - } -#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */ - -#if HAVE_NFS4_ACL -#if HAVE_SUN_NFS4_ACL - if (ace != NULL) -#elif HAVE_DARWIN_ACL - if (acl_type == ACL_TYPE_EXTENDED) -#else /* FreeBSD */ - if (acl_type == ACL_TYPE_NFS4) -#endif - { -#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL - /* - * acl_get_flagset_np() fails with non-NFSv4 ACLs - */ - if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { - archive_set_error(a, errno, - "Failed to get flagset from an NFSv4 ACL entry"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - if (acl_clear_flags_np(acl_flagset) != 0) { - archive_set_error(a, errno, - "Failed to clear flags from an NFSv4 ACL flagset"); - ret = ARCHIVE_FAILED; - goto exit_free; - } -#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */ - for (i = 0; i < (int)(sizeof(acl_inherit_map) /sizeof(acl_inherit_map[0])); ++i) { - if (ae_permset & acl_inherit_map[i].archive_inherit) { -#if HAVE_SUN_ACL - ace->a_flags |= - acl_inherit_map[i].platform_inherit; -#else /* !HAVE_SUN_ACL */ - if (acl_add_flag_np(acl_flagset, - acl_inherit_map[i].platform_inherit) != 0) { - archive_set_error(a, errno, - "Failed to add flag to NFSv4 ACL flagset"); - ret = ARCHIVE_FAILED; - goto exit_free; - } -#endif /* HAVE_SUN_ACL */ - } - } - } -#endif /* HAVE_NFS4_ACL */ -#if HAVE_SUN_ACL - e++; -#endif - } - -#if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL - /* Try restoring the ACL through 'fd' if we can. */ -#if HAVE_SUN_ACL || HAVE_ACL_SET_FD_NP - if (fd >= 0) -#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */ - if (fd >= 0 && acl_type == ACL_TYPE_ACCESS) -#endif - { -#if HAVE_SUN_ACL - if (facl(fd, cmd, entries, aclp) == 0) -#elif HAVE_ACL_SET_FD_NP - if (acl_set_fd_np(fd, acl, acl_type) == 0) -#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */ - if (acl_set_fd(fd, acl) == 0) -#endif - ret = ARCHIVE_OK; - else { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, - "Failed to set %s acl on fd", tname); - } - } - } else -#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */ -#if HAVE_SUN_ACL - if (acl(name, cmd, entries, aclp) != 0) -#elif HAVE_ACL_SET_LINK_NP - if (acl_set_link_np(name, acl_type, acl) != 0) -#else - /* TODO: Skip this if 'name' is a symlink. */ - if (acl_set_file(name, acl_type, acl) != 0) -#endif - { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, "Failed to set %s acl", - tname); - ret = ARCHIVE_WARN; - } - } -exit_free: -#if HAVE_SUN_ACL - free(aclp); -#else - acl_free(acl); -#endif - return (ret); -} -#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */ diff --git a/contrib/libarchive/libarchive/archive_write_disk_acl_freebsd.c b/contrib/libarchive/libarchive/archive_write_disk_acl_freebsd.c new file mode 100644 index 000000000000..29e64adf0f33 --- /dev/null +++ b/contrib/libarchive/libarchive/archive_write_disk_acl_freebsd.c @@ -0,0 +1,321 @@ +/*- + * 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 + * in this position and unchanged. + * 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 "archive_platform.h" +__FBSDID("$FreeBSD$"); + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif +#ifdef HAVE_SYS_ACL_H +#define _ACL_PRIVATE /* For debugging */ +#include <sys/acl.h> +#endif + +#include "archive.h" +#include "archive_entry.h" +#include "archive_write_disk_private.h" +#include "archive_acl_maps.h" + +static int +set_acl(struct archive *a, int fd, const char *name, + struct archive_acl *abstract_acl, + int ae_requested_type, const char *tname) +{ + int acl_type = 0; + acl_t acl; + acl_entry_t acl_entry; + acl_permset_t acl_permset; +#if ARCHIVE_ACL_FREEBSD_NFS4 + acl_flagset_t acl_flagset; + int r; +#endif + int ret; + int ae_type, ae_permset, ae_tag, ae_id; + int perm_map_size; + const acl_perm_map_t *perm_map; + uid_t ae_uid; + gid_t ae_gid; + const char *ae_name; + int entries; + int i; + + ret = ARCHIVE_OK; + entries = archive_acl_reset(abstract_acl, ae_requested_type); + if (entries == 0) + return (ARCHIVE_OK); + + + switch (ae_requested_type) { + case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: + acl_type = ACL_TYPE_ACCESS; + break; + case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: + acl_type = ACL_TYPE_DEFAULT; + break; +#if ARCHIVE_ACL_FREEBSD_NFS4 + case ARCHIVE_ENTRY_ACL_TYPE_NFS4: + acl_type = ACL_TYPE_NFS4; + break; +#endif + default: + errno = ENOENT; + archive_set_error(a, errno, "Unsupported ACL type"); + return (ARCHIVE_FAILED); + } + + acl = acl_init(entries); + if (acl == (acl_t)NULL) { + archive_set_error(a, errno, + "Failed to initialize ACL working storage"); + return (ARCHIVE_FAILED); + } + + while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, + &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { + if (acl_create_entry(&acl, &acl_entry) != 0) { + archive_set_error(a, errno, + "Failed to create a new ACL entry"); + ret = ARCHIVE_FAILED; + goto exit_free; + } + switch (ae_tag) { + case ARCHIVE_ENTRY_ACL_USER: + ae_uid = archive_write_disk_uid(a, ae_name, ae_id); + acl_set_tag_type(acl_entry, ACL_USER); + acl_set_qualifier(acl_entry, &ae_uid); + break; + case ARCHIVE_ENTRY_ACL_GROUP: + ae_gid = archive_write_disk_gid(a, ae_name, ae_id); + acl_set_tag_type(acl_entry, ACL_GROUP); + acl_set_qualifier(acl_entry, &ae_gid); + break; + case ARCHIVE_ENTRY_ACL_USER_OBJ: + acl_set_tag_type(acl_entry, ACL_USER_OBJ); + break; + case ARCHIVE_ENTRY_ACL_GROUP_OBJ: + acl_set_tag_type(acl_entry, ACL_GROUP_OBJ); + break; + case ARCHIVE_ENTRY_ACL_MASK: + acl_set_tag_type(acl_entry, ACL_MASK); + break; + case ARCHIVE_ENTRY_ACL_OTHER: + acl_set_tag_type(acl_entry, ACL_OTHER); + break; +#if ARCHIVE_ACL_FREEBSD_NFS4 + case ARCHIVE_ENTRY_ACL_EVERYONE: + acl_set_tag_type(acl_entry, ACL_EVERYONE); + break; +#endif + default: + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Unsupported ACL tag"); + ret = ARCHIVE_FAILED; + goto exit_free; + } + +#if ARCHIVE_ACL_FREEBSD_NFS4 + r = 0; + switch (ae_type) { + case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: + r = acl_set_entry_type_np(acl_entry, + ACL_ENTRY_TYPE_ALLOW); + break; + case ARCHIVE_ENTRY_ACL_TYPE_DENY: + r = acl_set_entry_type_np(acl_entry, + ACL_ENTRY_TYPE_DENY); + break; + case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: + r = acl_set_entry_type_np(acl_entry, + ACL_ENTRY_TYPE_AUDIT); + break; + case ARCHIVE_ENTRY_ACL_TYPE_ALARM: + r = acl_set_entry_type_np(acl_entry, + ACL_ENTRY_TYPE_ALARM); + break; + case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: + case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: + // These don't translate directly into the system ACL. + break; + default: + archive_set_error(a, ARCHIVE_ERRNO_MISC, + "Unsupported ACL entry type"); + ret = ARCHIVE_FAILED; + goto exit_free; + } + + if (r != 0) { + archive_set_error(a, errno, + "Failed to set ACL entry type"); + ret = ARCHIVE_FAILED; + goto exit_free; + } +#endif + + if (acl_get_permset(acl_entry, &acl_permset) != 0) { + archive_set_error(a, errno, + "Failed to get ACL permission set"); + ret = ARCHIVE_FAILED; + goto exit_free; + } + if (acl_clear_perms(acl_permset) != 0) { + archive_set_error(a, errno, + "Failed to clear ACL permissions"); + ret = ARCHIVE_FAILED; + goto exit_free; + } +#if ARCHIVE_ACL_FREEBSD_NFS4 + if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { + perm_map_size = acl_nfs4_perm_map_size; + perm_map = acl_nfs4_perm_map; + } else { +#endif + perm_map_size = acl_posix_perm_map_size; + perm_map = acl_posix_perm_map; +#if ARCHIVE_ACL_FREEBSD_NFS4 + } +#endif + + for (i = 0; i < perm_map_size; ++i) { + if (ae_permset & perm_map[i].a_perm) { + if (acl_add_perm(acl_permset, + perm_map[i].p_perm) != 0) { + archive_set_error(a, errno, + "Failed to add ACL permission"); + ret = ARCHIVE_FAILED; + goto exit_free; + } + } + } + +#if ARCHIVE_ACL_FREEBSD_NFS4 + if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { + /* + * acl_get_flagset_np() fails with non-NFSv4 ACLs + */ + if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { + archive_set_error(a, errno, + "Failed to get flagset from an NFSv4 " + "ACL entry"); + ret = ARCHIVE_FAILED; + goto exit_free; + } + if (acl_clear_flags_np(acl_flagset) != 0) { + archive_set_error(a, errno, + "Failed to clear flags from an NFSv4 " + "ACL flagset"); + ret = ARCHIVE_FAILED; + goto exit_free; + } + for (i = 0; i < acl_nfs4_flag_map_size; ++i) { + if (ae_permset & acl_nfs4_flag_map[i].a_perm) { + if (acl_add_flag_np(acl_flagset, + acl_nfs4_flag_map[i].p_perm) != 0) { + archive_set_error(a, errno, + "Failed to add flag to " + "NFSv4 ACL flagset"); + ret = ARCHIVE_FAILED; + goto exit_free; + } + } + } + } +#endif + } + + /* Try restoring the ACL through 'fd' if we can. */ + if (fd >= 0) { + if (acl_set_fd_np(fd, acl, acl_type) == 0) + ret = ARCHIVE_OK; + else { + if (errno == EOPNOTSUPP) { + /* Filesystem doesn't support ACLs */ + ret = ARCHIVE_OK; + } else { + archive_set_error(a, errno, + "Failed to set acl on fd: %s", tname); + ret = ARCHIVE_WARN; + } + } + } +#if HAVE_ACL_SET_LINK_NP + else if (acl_set_link_np(name, acl_type, acl) != 0) +#else + /* FreeBSD older than 8.0 */ + else if (acl_set_file(name, acl_type, acl) != 0) +#endif + { + if (errno == EOPNOTSUPP) { + /* Filesystem doesn't support ACLs */ + ret = ARCHIVE_OK; + } else { + archive_set_error(a, errno, "Failed to set acl: %s", + tname); + ret = ARCHIVE_WARN; + } + } +exit_free: + acl_free(acl); + return (ret); +} + +int +archive_write_disk_set_acls(struct archive *a, int fd, const char *name, + struct archive_acl *abstract_acl, __LA_MODE_T mode) +{ + int ret = ARCHIVE_OK; + + (void)mode; /* UNUSED */ + + if ((archive_acl_types(abstract_acl) + & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { + if ((archive_acl_types(abstract_acl) + & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { + ret = set_acl(a, fd, name, abstract_acl, + ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access"); + if (ret != ARCHIVE_OK) + return (ret); + } + if ((archive_acl_types(abstract_acl) + & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) + ret = set_acl(a, fd, name, abstract_acl, + ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default"); + + /* Simultaneous POSIX.1e and NFSv4 is not supported */ + return (ret); + } +#if ARCHIVE_ACL_FREEBSD_NFS4 + else if ((archive_acl_types(abstract_acl) & + ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { + ret = set_acl(a, fd, name, abstract_acl, + ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4"); + } +#endif + return (ret); +} diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c index f6c24d1288b6..119503f2f979 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c @@ -575,10 +575,55 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) if (a->flags & ARCHIVE_EXTRACT_TIME) a->todo |= TODO_TIMES; if (a->flags & ARCHIVE_EXTRACT_ACL) { +#if ARCHIVE_ACL_DARWIN + /* + * On MacOS, platform ACLs get stored in mac_metadata, too. + * If we intend to extract mac_metadata and it is present + * we skip extracting libarchive NFSv4 ACLs. + */ + size_t metadata_size; + + if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 || + archive_entry_mac_metadata(a->entry, + &metadata_size) == NULL || metadata_size == 0) +#endif +#if ARCHIVE_ACL_LIBRICHACL + /* + * RichACLs are stored in an extended attribute. + * If we intend to extract extended attributes and have this + * attribute we skip extracting libarchive NFSv4 ACLs. + */ + short extract_acls = 1; + if (a->flags & ARCHIVE_EXTRACT_XATTR && ( + archive_entry_acl_types(a->entry) & + ARCHIVE_ENTRY_ACL_TYPE_NFS4)) { + const char *attr_name; + const void *attr_value; + size_t attr_size; + int i = archive_entry_xattr_reset(a->entry); + while (i--) { + archive_entry_xattr_next(a->entry, &attr_name, + &attr_value, &attr_size); + if (attr_name != NULL && attr_value != NULL && + attr_size > 0 && strcmp(attr_name, + "trusted.richacl") == 0) { + extract_acls = 0; + break; + } + } + } + if (extract_acls) +#endif +#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL + { +#endif if (archive_entry_filetype(a->entry) == AE_IFDIR) a->deferred |= TODO_ACLS; else a->todo |= TODO_ACLS; +#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL + } +#endif } if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) { if (archive_entry_filetype(a->entry) == AE_IFDIR) @@ -1703,25 +1748,11 @@ _archive_write_disk_finish_entry(struct archive *_a) */ if (a->todo & TODO_ACLS) { int r2; -#ifdef HAVE_DARWIN_ACL - /* - * On Mac OS, platform ACLs are stored also in mac_metadata by - * the operating system. If mac_metadata is present it takes - * precedence and we skip extracting libarchive NFSv4 ACLs - */ - const void *metadata; - size_t metadata_size; - metadata = archive_entry_mac_metadata(a->entry, &metadata_size); - if ((a->todo & TODO_MAC_METADATA) == 0 || - metadata == NULL || metadata_size == 0) { -#endif r2 = archive_write_disk_set_acls(&a->archive, a->fd, archive_entry_pathname(a->entry), - archive_entry_acl(a->entry)); + archive_entry_acl(a->entry), + archive_entry_mode(a->entry)); if (r2 < ret) ret = r2; -#ifdef HAVE_DARWIN_ACL - } -#endif } finish_metadata: @@ -2293,13 +2324,8 @@ _archive_write_disk_close(struct archive *_a) if (p->fixup & TODO_MODE_BASE) chmod(p->name, p->mode); if (p->fixup & TODO_ACLS) -#ifdef HAVE_DARWIN_ACL - if ((p->fixup & TODO_MAC_METADATA) == 0 || - p->mac_metadata == NULL || - p->mac_metadata_size == 0) -#endif - archive_write_disk_set_acls(&a->archive, - -1, p->name, &p->acl); + archive_write_disk_set_acls(&a->archive, -1, p->name, + &p->acl, p->mode); if (p->fixup & TODO_FFLAGS) set_fflags_platform(a, -1, p->name, p->mode, p->fflags_set, 0); @@ -4239,5 +4265,19 @@ older(struct stat *st, struct archive_entry *entry) return (0); } +#ifndef ARCHIVE_ACL_SUPPORT +int +archive_write_disk_set_acls(struct archive *a, int fd, const char *name, + struct archive_acl *abstract_acl, __LA_MODE_T mode) +{ + (void)a; /* UNUSED */ + (void)fd; /* UNUSED */ + (void)name; /* UNUSED */ + (void)abstract_acl; /* UNUSED */ + (void)mode; /* UNUSED */ + return (ARCHIVE_OK); +} +#endif + #endif /* !_WIN32 || __CYGWIN__ */ diff --git a/contrib/libarchive/libarchive/archive_write_disk_private.h b/contrib/libarchive/libarchive/archive_write_disk_private.h index d4a9a5b90564..d4c9535d8ab3 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_private.h +++ b/contrib/libarchive/libarchive/archive_write_disk_private.h @@ -33,11 +33,13 @@ #ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED #define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED +#include "archive_platform_acl.h" #include "archive_acl_private.h" +#include "archive_entry.h" struct archive_write_disk; -int -archive_write_disk_set_acls(struct archive *, int /* fd */, const char * /* pathname */, struct archive_acl *); +int archive_write_disk_set_acls(struct archive *, int, const char *, + struct archive_acl *, __LA_MODE_T); #endif diff --git a/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c b/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c index c8854082ab1b..a3868a627eea 100644 --- a/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c +++ b/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c @@ -26,15 +26,18 @@ #include "test.h" __FBSDID("$FreeBSD$"); -#if HAVE_POSIX_ACL || HAVE_NFS4_ACL +#if ARCHIVE_ACL_NFS4 +#if HAVE_SYS_ACL_H #define _ACL_PRIVATE #include <sys/acl.h> -#if HAVE_DARWIN_ACL -#include <membership.h> #endif +#if HAVE_SYS_RICHACL_H +#include <sys/richacl.h> +#endif +#if HAVE_MEMBERSHIP_H +#include <membership.h> #endif -#if HAVE_NFS4_ACL struct myacl_t { int type; int permset; @@ -44,7 +47,7 @@ struct myacl_t { }; static struct myacl_t acls_reg[] = { -#if !HAVE_DARWIN_ACL +#if !ARCHIVE_ACL_DARWIN /* 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, @@ -91,7 +94,7 @@ static struct myacl_t acls_reg[] = { // ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" }, -#if !HAVE_DARWIN_ACL +#if !ARCHIVE_ACL_DARWIN { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, @@ -134,7 +137,7 @@ static const int acls_reg_cnt = (int)(sizeof(acls_reg)/sizeof(acls_reg[0])); static struct myacl_t acls_dir[] = { /* For this test, we need to be able to read and write the ACL. */ -#if !HAVE_DARWIN_ACL +#if !ARCHIVE_ACL_DARWIN { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL, ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""}, #endif @@ -180,13 +183,17 @@ static struct myacl_t acls_dir[] = { { 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_READ_DATA | + ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT | + 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_READ_DATA | + ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT | + ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_USER, 304, "user304" }, +#if !defined(ARCHIVE_ACL_SUNOS_NFS4) || defined(ACE_INHERITED_ACE) { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ARCHIVE_ENTRY_ACL_USER, 305, "user305" }, @@ -207,7 +214,7 @@ static struct myacl_t acls_dir[] = { ARCHIVE_ENTRY_ACL_USER, 501, "user501" }, { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" }, -#if !HAVE_DARWIN_ACL +#if !ARCHIVE_ACL_DARWIN { 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, @@ -254,7 +261,7 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end) int i; archive_entry_acl_clear(ae); -#if !HAVE_DARWIN_ACL +#if !ARCHIVE_ACL_DARWIN if (start > 0) { assertEqualInt(ARCHIVE_OK, archive_entry_acl_add_entry(ae, @@ -271,78 +278,96 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end) } static int -#ifdef HAVE_SUN_NFS4_ACL -acl_permset_to_bitmap(uint32_t a_access_mask) +#if ARCHIVE_ACL_SUNOS_NFS4 +acl_permset_to_bitmap(uint32_t mask) +#elif ARCHIVE_ACL_LIBRICHACL +acl_permset_to_bitmap(unsigned int mask) #else acl_permset_to_bitmap(acl_permset_t opaque_ps) #endif { - static struct { int machine; int portable; } perms[] = { -#ifdef HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */ - {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} -#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL permissions */ - {ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA}, - {ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY}, - {ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA}, - {ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE}, - {ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE}, - {ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE}, - {ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA}, - {ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY}, - {ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD}, - {ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES}, - {ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES}, - {ACL_READ_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS}, - {ACL_WRITE_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS}, - {ACL_READ_SECURITY, ARCHIVE_ENTRY_ACL_READ_ACL}, - {ACL_WRITE_SECURITY, ARCHIVE_ENTRY_ACL_WRITE_ACL}, - {ACL_CHANGE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER}, + static struct { int portable; int machine; } perms[] = { +#ifdef ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL permissions */ + {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE}, + {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA}, + {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY}, + {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE}, + {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY}, + {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS}, + {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS}, + {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD}, + {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE}, + {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL}, + {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL}, + {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER}, + {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE} +#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL permissions */ + {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, + {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, + {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, + {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, + {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, + {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, + {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, + {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY}, + {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY}, + {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER}, #if HAVE_DECL_ACL_SYNCHRONIZE - {ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}, + {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} #endif +#elif ARCHIVE_ACL_LIBRICHACL + {ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE}, + {ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA}, + {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY}, + {ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE}, + {ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY}, + {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS}, + {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS}, + {ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD}, + {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE}, + {ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL}, + {ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL}, + {ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER}, + {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE} #else /* FreeBSD NFSv4 ACL permissions */ - {ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE}, - {ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE}, - {ACL_READ, ARCHIVE_ENTRY_ACL_READ}, - {ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA}, - {ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY}, - {ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA}, - {ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE}, - {ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA}, - {ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY}, - {ACL_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS}, - {ACL_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS}, - {ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD}, - {ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES}, - {ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES}, - {ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE}, - {ACL_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL}, - {ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL}, - {ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER}, - {ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE} + {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, + {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, + {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, + {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, + {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, + {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, + {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, + {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, + {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, + {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, + {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, + {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL}, + {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL}, + {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER}, + {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} #endif }; int i, permset = 0; for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i) -#if HAVE_SUN_NFS4_ACL - if (a_access_mask & perms[i].machine) +#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL + if (mask & perms[i].machine) #else if (acl_get_perm_np(opaque_ps, perms[i].machine)) #endif @@ -351,90 +376,70 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps) } static int -#if HAVE_SUN_NFS4_ACL -acl_flagset_to_bitmap(uint16_t a_flags) +#if ARCHIVE_ACL_SUNOS_NFS4 +acl_flagset_to_bitmap(uint16_t flags) +#elif ARCHIVE_ACL_LIBRICHACL +acl_flagset_to_bitmap(int flags) #else acl_flagset_to_bitmap(acl_flagset_t opaque_fs) #endif { - static struct { int machine; int portable; } flags[] = { -#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL inheritance 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}, + static struct { int portable; int machine; } perms[] = { +#if ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL inheritance flags */ + {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE}, + {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE}, + {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE}, + {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE}, + {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, + {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG}, #ifdef ACE_INHERITED_ACE - {ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED} -#endif -#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL inheritance flags */ - {ACL_ENTRY_INHERITED, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}, - {ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT}, - {ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT}, - {ACL_ENTRY_LIMIT_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT}, - {ACL_ENTRY_ONLY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY} + {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE} +#endif +#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL inheritance flags */ + {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, + {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT} +#elif ARCHIVE_ACL_LIBRICHACL + {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE}, + {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE}, + {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE}, + {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE}, + {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE} #else /* FreeBSD NFSv4 ACL inheritance flags */ - {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}, + {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, + {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, + {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS}, + {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS}, + {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY} #endif }; int i, flagset = 0; - for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i) -#if HAVE_SUN_NFS4_ACL - if (a_flags & flags[i].machine) + for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i) +#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL + if (flags & perms[i].machine) #else - if (acl_get_flag_np(opaque_fs, flags[i].machine)) + if (acl_get_flag_np(opaque_fs, perms[i].machine)) #endif - flagset |= flags[i].portable; + flagset |= perms[i].portable; return flagset; } +#if ARCHIVE_ACL_SUNOS_NFS4 static int -#if HAVE_SUN_NFS4_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_NFS4_ACL -#if HAVE_DARWIN_ACL - void *q; - uid_t ugid; - int r, idtype; -#else - gid_t g, *gp; - uid_t u, *up; - acl_entry_type_t entry_type; -#endif /* !HAVE_DARWIN_ACL */ - acl_tag_t tag_type; - acl_permset_t opaque_ps; - acl_flagset_t opaque_fs; -#endif /* !HAVE_SUN_NFS4_ACL */ int perms; -#if HAVE_SUN_NFS4_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); -#if !HAVE_DARWIN_ACL - acl_get_entry_type_np(aclent, &entry_type); -#endif - /* 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_NFS4_ACL switch (ace->a_type) { case ACE_ACCESS_ALLOWED_ACE_TYPE: if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) @@ -476,7 +481,85 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl) if ((uid_t)myacl->qual != ace->a_who) return (0); } -#elif HAVE_DARWIN_ACL + return (1); +} +#elif ARCHIVE_ACL_LIBRICHACL +static int +acl_match(struct richace *richace, struct myacl_t *myacl) +{ + int perms; + + perms = acl_permset_to_bitmap(richace->e_mask) | + acl_flagset_to_bitmap(richace->e_flags); + + if (perms != myacl->permset) + return (0); + + switch (richace->e_type) { + case RICHACE_ACCESS_ALLOWED_ACE_TYPE: + if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) + return (0); + break; + case RICHACE_ACCESS_DENIED_ACE_TYPE: + if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) + return (0); + break; + default: + return (0); + } + + if (richace->e_flags & RICHACE_SPECIAL_WHO) { + switch (richace->e_id) { + case RICHACE_OWNER_SPECIAL_ID: + if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) + return (0); + break; + case RICHACE_GROUP_SPECIAL_ID: + if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) + return (0); + break; + case RICHACE_EVERYONE_SPECIAL_ID: + if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) + return (0); + break; + default: + /* Invalid e_id */ + return (0); + } + } else if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) { + if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) + return (0); + if ((gid_t)myacl->qual != richace->e_id) + return (0); + } else { + if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) + return (0); + if ((uid_t)myacl->qual != richace->e_id) + return (0); + } + return (1); +} +#elif ARCHIVE_ACL_DARWIN +static int +acl_match(acl_entry_t aclent, struct myacl_t *myacl) +{ + void *q; + uid_t ugid; + int r, idtype; + acl_tag_t tag_type; + acl_permset_t opaque_ps; + acl_flagset_t opaque_fs; + int perms; + + 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); + if (perms != myacl->permset) + return (0); + r = 0; switch (tag_type) { case ACL_EXTENDED_ALLOW: @@ -513,7 +596,30 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl) default: return (0); } -#else /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */ + return (1); +} +#else /* ARCHIVE_ACL_FREEBSD_NFS4 */ +static int +acl_match(acl_entry_t aclent, struct myacl_t *myacl) +{ + gid_t g, *gp; + uid_t u, *up; + acl_entry_type_t entry_type; + acl_tag_t tag_type; + acl_permset_t opaque_ps; + acl_flagset_t opaque_fs; + int perms; + + acl_get_tag_type(aclent, &tag_type); + acl_get_entry_type_np(aclent, &entry_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); + if (perms != myacl->permset) + return (0); + switch (entry_type) { case ACL_ENTRY_TYPE_ALLOW: if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) @@ -565,15 +671,17 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl) if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0); break; } -#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */ return (1); } +#endif /* various ARCHIVE_ACL_NFS4 implementations */ static void compare_acls( -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 void *aclp, int aclcnt, +#elif ARCHIVE_ACL_LIBRICHACL + struct richacl *richacl, #else acl_t acl, #endif @@ -582,19 +690,40 @@ compare_acls( int *marker; int matched; int i, n; -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 int e; ace_t *acl_entry; +#elif ARCHIVE_ACL_LIBRICHACL + int e; + struct richace *acl_entry; + int aclcnt; #else int entry_id = ACL_FIRST_ENTRY; acl_entry_t acl_entry; +#if ARCHIVE_ACL_DARWIN + const int acl_get_entry_ret = 0; +#else + const int acl_get_entry_ret = 1; +#endif +#endif + +#if ARCHIVE_ACL_SUNOS_NFS4 + if (aclp == NULL) + return; +#elif ARCHIVE_ACL_LIBRICHACL + if (richacl == NULL) + return; + aclcnt = richacl->a_count; +#else + if (acl == NULL) + return; #endif n = end - start; marker = malloc(sizeof(marker[0]) * (n + 1)); for (i = 0; i < n; i++) marker[i] = i + start; -#if !HAVE_DARWIN_ACL +#if !ARCHIVE_ACL_DARWIN /* Always include the first ACE. */ if (start > 0) { marker[n] = 0; @@ -606,16 +735,16 @@ compare_acls( * Iterate over acls in system acl object, try to match each * one with an item in the myacls array. */ -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL for (e = 0; e < aclcnt; e++) -#elif HAVE_DARWIN_ACL - while (0 == acl_get_entry(acl, entry_id, &acl_entry)) #else - while (1 == acl_get_entry(acl, entry_id, &acl_entry)) + while (acl_get_entry_ret == acl_get_entry(acl, entry_id, &acl_entry)) #endif { -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 acl_entry = &((ace_t *)aclp)[e]; +#elif ARCHIVE_ACL_LIBRICHACL + acl_entry = &(richacl->a_entries[e]); #else /* After the first time... */ entry_id = ACL_NEXT_ENTRY; @@ -708,7 +837,7 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char } free(marker); } -#endif /* HAVE_NFS4_ACL */ +#endif /* ARCHIVE_ACL_NFS4 */ /* * Verify ACL restore-to-disk. This test is Platform-specific. @@ -716,25 +845,27 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char DEFINE_TEST(test_acl_platform_nfs4) { -#if !HAVE_NFS4_ACL +#if !ARCHIVE_ACL_NFS4 skipping("NFS4 ACLs are not supported on this platform"); -#else +#else /* ARCHIVE_ACL_NFS4 */ char buff[64]; int i; struct stat st; struct archive *a; struct archive_entry *ae; -#if HAVE_DARWIN_ACL /* On MacOS we skip trivial ACLs in some tests */ +#if ARCHIVE_ACL_DARWIN /* On MacOS we skip trivial ACLs in some tests */ const int regcnt = acls_reg_cnt - 4; const int dircnt = acls_dir_cnt - 4; #else const int regcnt = acls_reg_cnt; const int dircnt = acls_dir_cnt; #endif -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 void *aclp; int aclcnt; -#else /* !HAVE_SUN_NFS4_ACL */ +#elif ARCHIVE_ACL_LIBRICHACL + struct richacl *richacl; +#else /* !ARCHIVE_ACL_SUNOS_NFS4 */ acl_t acl; #endif @@ -790,23 +921,33 @@ DEFINE_TEST(test_acl_platform_nfs4) /* Verify the data on disk. */ assertEqualInt(0, stat("testall", &st)); assertEqualInt(st.st_mtime, 123456); -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "testall"); - failure("acl(): errno = %d (%s)", errno, strerror(errno)); + failure("acl(\"%s\"): errno = %d (%s)", "testall", errno, + strerror(errno)); assert(aclp != NULL); +#elif ARCHIVE_ACL_LIBRICHACL + richacl = richacl_get_file("testall"); + failure("richacl_get_file(\"%s\"): errno = %d (%s)", "testall", errno, + strerror(errno)); + assert(richacl != NULL); #else -#if HAVE_DARWIN_ACL +#if ARCHIVE_ACL_DARWIN acl = acl_get_file("testall", ACL_TYPE_EXTENDED); #else acl = acl_get_file("testall", ACL_TYPE_NFS4); #endif - failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno)); + failure("acl_get_file(\"%s\"): errno = %d (%s)", "testall", errno, + strerror(errno)); assert(acl != (acl_t)NULL); #endif -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 compare_acls(aclp, aclcnt, acls_reg, "testall", 0, regcnt); free(aclp); aclp = NULL; +#elif ARCHIVE_ACL_LIBRICHACL + compare_acls(richacl, acls_reg, "testall", 0, regcnt); + richacl_free(richacl); #else compare_acls(acl, acls_reg, "testall", 0, regcnt); acl_free(acl); @@ -818,24 +959,37 @@ DEFINE_TEST(test_acl_platform_nfs4) sprintf(buff, "dir%d", i); assertEqualInt(0, stat(buff, &st)); assertEqualInt(st.st_mtime, 123456 + i); -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, buff); - failure("acl(): errno = %d (%s)", errno, strerror(errno)); + failure("acl(\"%s\"): errno = %d (%s)", buff, errno, + strerror(errno)); assert(aclp != NULL); +#elif ARCHIVE_ACL_LIBRICHACL + richacl = richacl_get_file(buff); + /* First and last two dir do not return a richacl */ + if ((i == 0 || i >= dircnt - 2) && richacl == NULL && + errno == ENODATA) + continue; + failure("richacl_get_file(\"%s\"): errno = %d (%s)", buff, + errno, strerror(errno)); + assert(richacl != NULL); #else -#if HAVE_DARWIN_ACL +#if ARCHIVE_ACL_DARWIN acl = acl_get_file(buff, ACL_TYPE_EXTENDED); #else acl = acl_get_file(buff, ACL_TYPE_NFS4); #endif - failure("acl_get_file(): errno = %d (%s)", errno, + failure("acl_get_file(\"%s\"): errno = %d (%s)", buff, errno, strerror(errno)); assert(acl != (acl_t)NULL); #endif -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 compare_acls(aclp, aclcnt, acls_dir, buff, i, i + 1); free(aclp); aclp = NULL; +#elif ARCHIVE_ACL_LIBRICHACL + compare_acls(richacl, acls_dir, buff, i, i + 1); + richacl_free(richacl); #else compare_acls(acl, acls_dir, buff, i, i + 1); acl_free(acl); @@ -845,23 +999,33 @@ DEFINE_TEST(test_acl_platform_nfs4) /* Verify "dirall" on disk. */ assertEqualInt(0, stat("dirall", &st)); assertEqualInt(st.st_mtime, 123456); -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "dirall"); - failure("acl(): errno = %d (%s)", errno, strerror(errno)); + failure("acl(\"%s\"): errno = %d (%s)", "dirall", errno, + strerror(errno)); assert(aclp != NULL); +#elif ARCHIVE_ACL_LIBRICHACL + richacl = richacl_get_file("dirall"); + failure("richacl_get_file(\"%s\"): errno = %d (%s)", "dirall", + errno, strerror(errno)); + assert(richacl != NULL); #else -#if HAVE_DARWIN_ACL +#if ARCHIVE_ACL_DARWIN acl = acl_get_file("dirall", ACL_TYPE_EXTENDED); #else acl = acl_get_file("dirall", ACL_TYPE_NFS4); #endif - failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno)); + failure("acl_get_file(\"%s\"): errno = %d (%s)", "dirall", errno, + strerror(errno)); assert(acl != (acl_t)NULL); #endif -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 compare_acls(aclp, aclcnt, acls_dir, "dirall", 0, dircnt); free(aclp); aclp = NULL; +#elif ARCHIVE_ACL_LIBRICHACL + compare_acls(richacl, acls_dir, "dirall", 0, dircnt); + richacl_free(richacl); #else compare_acls(acl, acls_dir, "dirall", 0, dircnt); acl_free(acl); @@ -890,5 +1054,5 @@ DEFINE_TEST(test_acl_platform_nfs4) compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt); archive_entry_free(ae); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -#endif /* HAVE_NFS4_ACL */ +#endif /* ARCHIVE_ACL_NFS4 */ } diff --git a/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c b/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c index 0224a57f1c23..801a7acfc85e 100644 --- a/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c +++ b/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c @@ -26,7 +26,7 @@ #include "test.h" __FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $"); -#if HAVE_POSIX_ACL || HAVE_SUN_ACL +#if ARCHIVE_ACL_POSIX1E #include <sys/acl.h> #if HAVE_ACL_GET_PERM #include <acl/libacl.h> @@ -55,18 +55,18 @@ static struct archive_test_acl_t acls2[] = { }; static int -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS acl_entry_get_perm(aclent_t *aclent) #else acl_entry_get_perm(acl_entry_t aclent) #endif { int permset = 0; -#if HAVE_POSIX_ACL +#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL acl_permset_t opaque_ps; #endif -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS if (aclent->a_perm & 1) permset |= ARCHIVE_ENTRY_ACL_EXECUTE; if (aclent->a_perm & 2) @@ -127,114 +127,108 @@ acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_ta } #endif +#if ARCHIVE_ACL_SUNOS static int -#if HAVE_SUN_ACL acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl) -#else +{ + + 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; + 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); +} + +#else /* ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL */ +static int 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) -#endif - { -#if HAVE_SUN_ACL - case DEF_USER_OBJ: - case USER_OBJ: -#else + switch (tag_type) { 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; } return (1); } +#endif static void -#if HAVE_SUN_ACL -compare_acls(void *aclp, int aclcnt, struct archive_test_acl_t *myacls, int n) +compare_acls( +#if ARCHIVE_ACL_SUNOS + void *aclp, int aclcnt, #else -compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n) + acl_t acl, #endif + struct archive_test_acl_t *myacls, int n) { int *marker; int matched; int i; -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS int e; aclent_t *acl_entry; #else @@ -253,7 +247,7 @@ 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 +#if ARCHIVE_ACL_SUNOS for(e = 0; e < aclcnt; e++) { acl_entry = &((aclent_t *)aclp)[e]; #else @@ -288,23 +282,21 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n) } free(marker); } - #endif - /* * Verify ACL restore-to-disk. This test is Platform-specific. */ DEFINE_TEST(test_acl_platform_posix1e_restore) { -#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL +#if !ARCHIVE_ACL_POSIX1E skipping("POSIX.1e ACLs are not supported on this platform"); -#else /* HAVE_SUN_ACL || HAVE_POSIX_ACL */ +#else /* ARCHIVE_ACL_POSIX1E */ struct stat st; struct archive *a; struct archive_entry *ae; -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS void *aclp; int aclcnt; #else @@ -340,7 +332,7 @@ DEFINE_TEST(test_acl_platform_posix1e_restore) /* Verify the data on disk. */ assertEqualInt(0, stat("test0", &st)); assertEqualInt(st.st_mtime, 123456); -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS aclp = sunacl_get(GETACL, &aclcnt, 0, "test0"); failure("acl(): errno = %d (%s)", errno, strerror(errno)); assert(aclp != NULL); @@ -349,7 +341,7 @@ DEFINE_TEST(test_acl_platform_posix1e_restore) failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno)); assert(acl != (acl_t)NULL); #endif -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS compare_acls(aclp, aclcnt, acls2, sizeof(acls2)/sizeof(acls2[0])); free(aclp); aclp = NULL; @@ -358,7 +350,7 @@ DEFINE_TEST(test_acl_platform_posix1e_restore) acl_free(acl); #endif -#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */ +#endif /* ARCHIVE_ACL_POSIX1E */ } /* @@ -366,15 +358,15 @@ DEFINE_TEST(test_acl_platform_posix1e_restore) */ DEFINE_TEST(test_acl_platform_posix1e_read) { -#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL +#if !ARCHIVE_ACL_POSIX1E skipping("POSIX.1e ACLs are not supported on this platform"); -#else +#else /* ARCHIVE_ACL_POSIX1E */ struct archive *a; struct archive_entry *ae; int n, fd, flags, dflags; char *func, *acl_text; const char *acl1_text, *acl2_text, *acl3_text; -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS void *aclp; int aclcnt; #else @@ -388,7 +380,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read) */ /* Create a test file f1 with acl1 */ -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS acl1_text = "user::rwx," "group::rwx," "other:rwx," @@ -417,12 +409,12 @@ DEFINE_TEST(test_acl_platform_posix1e_read) fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777); failure("Could not create test file?!"); if (!assert(fd >= 0)) { -#if !HAVE_SUN_ACL +#if !ARCHIVE_ACL_SUNOS acl_free(acl1); #endif return; } -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS /* Check if Solaris filesystem supports POSIX.1e ACLs */ aclp = sunacl_get(GETACL, &aclcnt, fd, NULL); if (aclp == 0) @@ -440,12 +432,12 @@ DEFINE_TEST(test_acl_platform_posix1e_read) func = "acl_set_fd()"; n = acl_set_fd(fd, acl1); #endif -#if !HAVE_SUN_ACL +#if !ARCHIVE_ACL_SUNOS acl_free(acl1); #endif if (n != 0) { -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS if (errno == ENOSYS || errno == ENOTSUP) #else if (errno == EOPNOTSUPP || errno == EINVAL) @@ -474,7 +466,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read) * to read ACLs, resulting in reading the ACL from a like-named * file in the wrong directory. */ -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS acl2_text = "user::rwx," "group::rwx," "other:---," @@ -503,12 +495,12 @@ DEFINE_TEST(test_acl_platform_posix1e_read) fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777); failure("Could not create test file?!"); if (!assert(fd >= 0)) { -#if !HAVE_SUN_ACL +#if !ARCHIVE_ACL_SUNOS acl_free(acl2); #endif return; } -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS func = "facl()"; n = facl(fd, SETACL, (int)(sizeof(aclp2) / sizeof(aclp2[0])), aclp2); #else @@ -525,7 +517,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read) /* Create nested directory d2 with default ACLs */ assertMakeDir("d/d2", 0755); -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS acl3_text = "user::rwx," "group::r-x," "other:r-x," @@ -564,7 +556,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read) assert((void *)acl3 != NULL); #endif -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS func = "acl()"; n = acl("d/d2", SETACL, (int)(sizeof(aclp3) / sizeof(aclp3[0])), aclp3); #else @@ -580,7 +572,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read) assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); assert(NULL != (ae = archive_entry_new())); -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS; @@ -610,5 +602,5 @@ DEFINE_TEST(test_acl_platform_posix1e_read) archive_entry_free(ae); assertEqualInt(ARCHIVE_OK, archive_free(a)); -#endif +#endif /* ARCHIVE_ACL_POSIX1E */ } diff --git a/contrib/libarchive/tar/bsdtar.1 b/contrib/libarchive/tar/bsdtar.1 index 3e7abe884126..0537bf36b20d 100644 --- a/contrib/libarchive/tar/bsdtar.1 +++ b/contrib/libarchive/tar/bsdtar.1 @@ -640,7 +640,7 @@ This option suppresses these behaviors. (x mode only) Preserve file permissions. Attempt to restore the full permissions, including owner, file modes, ACLs, -extended atributes and extended file flags, if available, for each item +extended attributes and extended file flags, if available, for each item extracted from the archive. This is te reverse of .Fl Fl no-same-permissions and the default if diff --git a/contrib/libarchive/tar/test/test_option_acls.c b/contrib/libarchive/tar/test/test_option_acls.c index 5c3fbfd156c8..bfe2b994bde5 100644 --- a/contrib/libarchive/tar/test/test_option_acls.c +++ b/contrib/libarchive/tar/test/test_option_acls.c @@ -73,8 +73,6 @@ static const acl_perm_t acl_perms[] = { #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, diff --git a/contrib/libarchive/test_utils/test_common.h b/contrib/libarchive/test_utils/test_common.h index 0078054178f0..43cbc5edda3b 100644 --- a/contrib/libarchive/test_utils/test_common.h +++ b/contrib/libarchive/test_utils/test_common.h @@ -127,43 +127,11 @@ #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 -#if HAVE_DECL_ACL_USER -#define HAVE_POSIX_ACL 1 -#elif HAVE_DECL_ACL_TYPE_EXTENDED -#define HAVE_DARWIN_ACL 1 -#endif -#if HAVE_DECL_ACL_TYPE_NFS4 -#define HAVE_FREEBSD_NFS4_ACL 1 -#endif -#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 && HAVE_FACL && HAVE_ACLENT_T && \ - HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL -#define HAVE_SUN_ACL 1 -#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \ - HAVE_DECL_ACE_SETACL -#define HAVE_SUN_NFS4_ACL 1 -#endif -#endif - -/* Define if platform supports NFSv4 ACLs */ -#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL -#define HAVE_NFS4_ACL 1 -#endif - +#include "archive_platform_acl.h" #define ARCHIVE_TEST_ACL_TYPE_POSIX1E 1 #define ARCHIVE_TEST_ACL_TYPE_NFS4 2 + /* * Redefine DEFINE_TEST for use in defining the test functions. */ @@ -378,7 +346,7 @@ 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 +#if ARCHIVE_ACL_SUNOS /* Fetch ACLs on Solaris using acl() or facl() */ void *sunacl_get(int cmd, int *aclcnt, int fd, const char *path); #endif diff --git a/contrib/libarchive/test_utils/test_main.c b/contrib/libarchive/test_utils/test_main.c index 86ab5f1a489f..0ef6d6fcf7f0 100644 --- a/contrib/libarchive/test_utils/test_main.c +++ b/contrib/libarchive/test_utils/test_main.c @@ -56,7 +56,8 @@ #include <stdarg.h> #include <time.h> -/* ACL support */ +#ifdef HAVE_SIGNAL_H +#endif #ifdef HAVE_ACL_LIBACL_H #include <acl/libacl.h> #endif @@ -66,7 +67,10 @@ #ifdef HAVE_SYS_ACL_H #include <sys/acl.h> #endif -#if HAVE_DARWIN_ACL +#ifdef HAVE_SYS_RICHACL_H +#include <sys/richacl.h> +#endif +#if HAVE_MEMBERSHIP_H #include <membership.h> #endif @@ -2436,7 +2440,7 @@ canNodump(void) return (0); } -#if HAVE_SUN_ACL +#if ARCHIVE_ACL_SUNOS /* Fetch ACLs on Solaris using acl() or facl() */ void * sunacl_get(int cmd, int *aclcnt, int fd, const char *path) @@ -2449,7 +2453,7 @@ sunacl_get(int cmd, int *aclcnt, int fd, const char *path) cntcmd = GETACLCNT; size = sizeof(aclent_t); } -#if HAVE_SUN_NFS4_ACL +#if ARCHIVE_ACL_SUNOS_NFS4 else if (cmd == ACE_GETACL) { cntcmd = ACE_GETACLCNT; size = sizeof(ace_t); @@ -2492,7 +2496,7 @@ sunacl_get(int cmd, int *aclcnt, int fd, const char *path) *aclcnt = cnt; return (aclp); } -#endif /* HAVE_SUN_ACL */ +#endif /* ARCHIVE_ACL_SUNOS */ /* * Set test ACLs on a path @@ -2504,19 +2508,22 @@ sunacl_get(int cmd, int *aclcnt, int fd, const char *path) int setTestAcl(const char *path) { -#if HAVE_POSIX_ACL || HAVE_NFS4_ACL +#if ARCHIVE_ACL_SUPPORT int r = 1; -#if !HAVE_SUN_ACL +#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_DARWIN acl_t acl; #endif -#if HAVE_POSIX_ACL /* Linux, FreeBSD POSIX.1e */ +#if ARCHIVE_ACL_LIBRICHACL + struct richacl *richacl; +#endif +#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_FREEBSD 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 */ +#elif ARCHIVE_ACL_SUNOS /* Solaris POSIX.1e */ aclent_t aclp_posix1e[] = { { USER_OBJ, -1, 4 | 2 | 1 }, { USER, 1, 4 | 2 }, @@ -2526,13 +2533,22 @@ setTestAcl(const char *path) { OTHER_OBJ, -1, 4 | 2 | 1 } }; #endif -#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFS4 */ +#if ARCHIVE_ACL_FREEBSD /* 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 */ +#elif ARCHIVE_ACL_LIBRICHACL + const char *acltext_nfs4 = "owner:rwpxaARWcCoS::mask," + "group:rwpxaRcS::mask," + "other:rxaRcS::mask," + "user:1:rwpaRcS::allow," + "group:15:rxaRcS::allow," + "owner@:rwpxaARWcCoS::allow," + "group@:rwpxaRcS::allow," + "everyone@:rxaRcS::allow"; +#elif ARCHIVE_ACL_SUNOS_NFS4 /* 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 | @@ -2553,7 +2569,7 @@ setTestAcl(const char *path) ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE, ACE_EVERYONE, ACE_ACCESS_ALLOWED_ACE_TYPE } }; -#elif HAVE_DARWIN_ACL /* Mac OS X */ +#elif ARCHIVE_ACL_DARWIN /* Mac OS X */ acl_entry_t aclent; acl_permset_t permset; const uid_t uid = 1; @@ -2571,14 +2587,19 @@ setTestAcl(const char *path) ACL_SYNCHRONIZE #endif }; -#endif /* HAVE_DARWIN_ACL */ +#endif /* ARCHIVE_ACL_DARWIN */ -#if HAVE_FREEBSD_NFS4_ACL +#if ARCHIVE_ACL_FREEBSD 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 +#elif ARCHIVE_ACL_LIBRICHACL + richacl = richacl_from_text(acltext_nfs4, NULL, NULL); + failure("richacl_from_text() error: %s", strerror(errno)); + if (assert(richacl != NULL) == 0) + return (0); +#elif ARCHIVE_ACL_DARWIN acl = acl_init(1); failure("acl_init() error: %s", strerror(errno)); if (assert(acl != NULL) == 0) @@ -2605,33 +2626,36 @@ setTestAcl(const char *path) 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)); + r = mbr_uid_to_uuid(uid, uuid); + failure("mbr_uid_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 */ +#endif /* ARCHIVE_ACL_DARWIN */ -#if HAVE_NFS4_ACL -#if HAVE_FREEBSD_NFS4_ACL +#if ARCHIVE_ACL_NFS4 +#if ARCHIVE_ACL_FREEBSD r = acl_set_file(path, ACL_TYPE_NFS4, acl); acl_free(acl); -#elif HAVE_SUN_NFS4_ACL +#elif ARCHIVE_ACL_LIBRICHACL + r = richacl_set_file(path, richacl); + richacl_free(richacl); +#elif ARCHIVE_ACL_SUNOS_NFS4 r = acl(path, ACE_SETACL, (int)(sizeof(aclp_nfs4)/sizeof(aclp_nfs4[0])), aclp_nfs4); -#elif HAVE_DARWIN_ACL +#elif ARCHIVE_ACL_DARWIN 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 */ +#endif /* ARCHIVE_ACL_NFS4 */ -#if HAVE_POSIX_ACL || HAVE_SUN_ACL -#if HAVE_POSIX_ACL +#if ARCHIVE_ACL_POSIX1E +#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL acl = acl_from_text(acltext_posix1e); failure("acl_from_text() error: %s", strerror(errno)); if (assert(acl != NULL) == 0) @@ -2639,7 +2663,7 @@ setTestAcl(const char *path) r = acl_set_file(path, ACL_TYPE_ACCESS, acl); acl_free(acl); -#elif HAVE_SUN_ACL +#elif ARCHIVE_ACL_SUNOS r = acl(path, SETACL, (int)(sizeof(aclp_posix1e)/sizeof(aclp_posix1e[0])), aclp_posix1e); #endif @@ -2647,12 +2671,12 @@ setTestAcl(const char *path) return (ARCHIVE_TEST_ACL_TYPE_POSIX1E); else return (0); -#endif /* HAVE_POSIX_ACL || HAVE_SUN_ACL */ -#if HAVE_DARWIN_ACL +#endif /* ARCHIVE_ACL_POSIX1E */ +#if ARCHIVE_ACL_DARWIN testacl_free: acl_free(acl); #endif -#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */ +#endif /* ARCHIVE_ACL_SUPPORT */ (void)path; /* UNUSED */ return (0); } |