Author: mm
Date: Mon Mar 20 13:02:27 2017
New Revision: 315636
URL: https://svnweb.freebsd.org/changeset/base/315636

Log:
  MFV r315633, 315635:
  
  Sync libarchive with vendor
  
  Vendor changes/bugfixes (FreeBSD-related):
    PR 867 (bsdcpio): show numeric uid/gid when names are not found
    PR 870 (seekable zip): accept files with valid ZIP64 EOCD headers
    PR 880 (pax): Fix handling of "size" pax header keyword
    PR 887 (crypto): Discard 3072 bytes instead of 1024 of first keystream
    OSS-Fuzz issue 806 (mtree): rework mtree_atol10 integer parser
    Break ACL read/write code into platform-specific source files
    Unbreak static dependency on libbz2
  
  MFC after:    1 week

Added:
  head/contrib/libarchive/libarchive/archive_acl_maps.h
     - copied, changed from r315633, 
vendor/libarchive/dist/libarchive/archive_acl_maps.h
  head/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c
     - copied, changed from r315633, 
vendor/libarchive/dist/libarchive/archive_acl_maps_freebsd.c
  head/contrib/libarchive/libarchive/archive_platform_acl.h
     - copied unchanged from r315633, 
vendor/libarchive/dist/libarchive/archive_platform_acl.h
  head/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c
     - copied unchanged from r315633, 
vendor/libarchive/dist/libarchive/archive_read_disk_acl_freebsd.c
  head/contrib/libarchive/libarchive/archive_version_details.c
     - copied unchanged from r315633, 
vendor/libarchive/dist/libarchive/archive_version_details.c
  head/contrib/libarchive/libarchive/archive_write_disk_acl_freebsd.c
     - copied unchanged from r315633, 
vendor/libarchive/dist/libarchive/archive_write_disk_acl_freebsd.c
Deleted:
  head/contrib/libarchive/libarchive/archive_write_disk_acl.c
Modified:
  head/contrib/libarchive/NEWS
  head/contrib/libarchive/cpio/cpio.c
  head/contrib/libarchive/libarchive/archive_entry.3
  head/contrib/libarchive/libarchive/archive_entry_acl.3
  head/contrib/libarchive/libarchive/archive_platform.h
  head/contrib/libarchive/libarchive/archive_random.c
  head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
  head/contrib/libarchive/libarchive/archive_read_disk_private.h
  head/contrib/libarchive/libarchive/archive_read_open.3
  head/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
  head/contrib/libarchive/libarchive/archive_read_support_format_tar.c
  head/contrib/libarchive/libarchive/archive_read_support_format_zip.c
  head/contrib/libarchive/libarchive/archive_util.c
  head/contrib/libarchive/libarchive/archive_write_disk_posix.c
  head/contrib/libarchive/libarchive/archive_write_disk_private.h
  head/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
  head/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
  head/contrib/libarchive/tar/bsdtar.1
  head/contrib/libarchive/tar/test/test_option_acls.c
  head/contrib/libarchive/test_utils/test_common.h
  head/contrib/libarchive/test_utils/test_main.c
  head/lib/libarchive/Makefile
  head/lib/libarchive/config_freebsd.h
  head/usr.bin/bsdcat/tests/Makefile
  head/usr.bin/cpio/tests/Makefile
  head/usr.bin/tar/tests/Makefile
Directory Properties:
  head/contrib/libarchive/   (props changed)

Modified: head/contrib/libarchive/NEWS
==============================================================================
--- head/contrib/libarchive/NEWS        Mon Mar 20 11:55:03 2017        
(r315635)
+++ head/contrib/libarchive/NEWS        Mon Mar 20 13:02:27 2017        
(r315636)
@@ -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

Modified: head/contrib/libarchive/cpio/cpio.c
==============================================================================
--- head/contrib/libarchive/cpio/cpio.c Mon Mar 20 11:55:03 2017        
(r315635)
+++ head/contrib/libarchive/cpio/cpio.c Mon Mar 20 13:02:27 2017        
(r315636)
@@ -1344,23 +1344,23 @@ lookup_name(struct cpio *cpio, struct na
                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, c
        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, c
        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;
 }
 
 /*

Copied and modified: head/contrib/libarchive/libarchive/archive_acl_maps.h 
(from r315633, vendor/libarchive/dist/libarchive/archive_acl_maps.h)
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_acl_maps.h        Mon Mar 20 
11:12:31 2017        (r315633, copy source)
+++ head/contrib/libarchive/libarchive/archive_acl_maps.h       Mon Mar 20 
13:02:27 2017        (r315636)
@@ -37,7 +37,6 @@ typedef struct {
        const int p_perm;       /* Platform permission or flag */
 } acl_perm_map_t;
 
-#ifndef _ARCHIVE_ACL_MAPS_DEFS
 #if ARCHIVE_ACL_POSIX1E
 extern const acl_perm_map_t acl_posix_perm_map[];
 extern const int acl_posix_perm_map_size;
@@ -48,5 +47,4 @@ 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_DEFS */
 #endif /* ARCHIVE_ACL_MAPS_H_INCLUDED */

Copied and modified: 
head/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c (from r315633, 
vendor/libarchive/dist/libarchive/archive_acl_maps_freebsd.c)
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_acl_maps_freebsd.c        Mon Mar 
20 11:12:31 2017        (r315633, copy source)
+++ head/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c       Mon Mar 
20 13:02:27 2017        (r315636)
@@ -36,7 +36,6 @@
 #include "archive_entry.h"
 #include "archive_private.h"
 #include "archive_read_disk_private.h"
-#define _ARCHIVE_ACL_MAPS_DEFS
 #include "archive_acl_maps.h"
 
 const acl_perm_map_t acl_posix_perm_map[] = {

Modified: head/contrib/libarchive/libarchive/archive_entry.3
==============================================================================
--- head/contrib/libarchive/libarchive/archive_entry.3  Mon Mar 20 11:55:03 
2017        (r315635)
+++ head/contrib/libarchive/libarchive/archive_entry.3  Mon Mar 20 13:02:27 
2017        (r315636)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Feburary 2, 2012
+.Dd February 2, 2012
 .Dt ARCHIVE_ENTRY 3
 .Os
 .Sh NAME

Modified: head/contrib/libarchive/libarchive/archive_entry_acl.3
==============================================================================
--- head/contrib/libarchive/libarchive/archive_entry_acl.3      Mon Mar 20 
11:55:03 2017        (r315635)
+++ head/contrib/libarchive/libarchive/archive_entry_acl.3      Mon Mar 20 
13:02:27 2017        (r315636)
@@ -267,7 +267,7 @@ Only inherit, do not apply the permissio
 .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

Modified: head/contrib/libarchive/libarchive/archive_platform.h
==============================================================================
--- head/contrib/libarchive/libarchive/archive_platform.h       Mon Mar 20 
11:55:03 2017        (r315635)
+++ head/contrib/libarchive/libarchive/archive_platform.h       Mon Mar 20 
13:02:27 2017        (r315636)
@@ -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.
  */

Copied: head/contrib/libarchive/libarchive/archive_platform_acl.h (from 
r315633, vendor/libarchive/dist/libarchive/archive_platform_acl.h)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/contrib/libarchive/libarchive/archive_platform_acl.h   Mon Mar 20 
13:02:27 2017        (r315636, copy of r315633, 
vendor/libarchive/dist/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 */

Modified: head/contrib/libarchive/libarchive/archive_random.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_random.c Mon Mar 20 11:55:03 
2017        (r315635)
+++ head/contrib/libarchive/libarchive/archive_random.c Mon Mar 20 13:02:27 
2017        (r315636)
@@ -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;
 }

Copied: head/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c 
(from r315633, 
vendor/libarchive/dist/libarchive/archive_read_disk_acl_freebsd.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c  Mon Mar 
20 13:02:27 2017        (r315636, copy of r315633, 
vendor/libarchive/dist/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);
+}

Modified: head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c      
Mon Mar 20 11:55:03 2017        (r315635)
+++ head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c      
Mon Mar 20 13:02:27 2017        (r315636)
@@ -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 ar
     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
 
        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_d
        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_d
 }
 #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

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to