Author: mm
Date: Mon Jul 30 14:47:35 2012
New Revision: 238909
URL: http://svn.freebsd.org/changeset/base/238909

Log:
  Backport NFSv4 ACL fix from libarchive master branch.
  
  Source:
  https://github.com/libarchive/libarchive/commit/f67370d5
  
  Obtained from:        libarchive (master branch)

Added:
  head/contrib/libarchive/libarchive/archive_write_disk_acl.c
  head/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c
  head/contrib/libarchive/libarchive/test/test_acl_freebsd_posix1e.c
Modified:
  head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
  head/contrib/libarchive/libarchive/archive_write_disk_posix.c
  head/contrib/libarchive/libarchive/archive_write_disk_private.h
  head/contrib/libarchive/tar/test/test_basic.c
  head/lib/libarchive/Makefile
  head/lib/libarchive/config_freebsd.h
  head/lib/libarchive/test/Makefile

Modified: head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c      
Mon Jul 30 14:34:30 2012        (r238908)
+++ head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c      
Mon Jul 30 14:47:35 2012        (r238909)
@@ -114,7 +114,7 @@ __FBSDID("$FreeBSD$");
 #define        ACL_GET_PERM acl_get_perm_np
 #endif
 
-static int setup_acls_posix1e(struct archive_read_disk *,
+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);
@@ -168,15 +168,16 @@ archive_read_disk_entry_from_file(struct
                        st = &s;
                }
                archive_entry_copy_stat(entry, st);
-               /* Lookup uname/gname */
-               name = archive_read_disk_uname(_a, archive_entry_uid(entry));
-               if (name != NULL)
-                       archive_entry_copy_uname(entry, name);
-               name = archive_read_disk_gname(_a, archive_entry_gid(entry));
-               if (name != NULL)
-                       archive_entry_copy_gname(entry, name);
        }
 
+       /* Lookup uname/gname */
+       name = archive_read_disk_uname(_a, archive_entry_uid(entry));
+       if (name != NULL)
+               archive_entry_copy_uname(entry, name);
+       name = archive_read_disk_gname(_a, archive_entry_gid(entry));
+       if (name != NULL)
+               archive_entry_copy_gname(entry, name);
+
 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
        /* On FreeBSD, we get flags for free with the stat. */
        /* TODO: Does this belong in copy_stat()? */
@@ -244,7 +245,7 @@ archive_read_disk_entry_from_file(struct
        }
 #endif /* HAVE_READLINK || HAVE_READLINKAT */
 
-       r = setup_acls_posix1e(a, entry, &fd);
+       r = setup_acls(a, entry, &fd);
        r1 = setup_xattrs(a, entry, &fd);
        if (r1 < r)
                r = r1;
@@ -388,15 +389,16 @@ setup_mac_metadata(struct archive_read_d
 
 
 #ifdef HAVE_POSIX_ACL
-static void setup_acl_posix1e(struct archive_read_disk *a,
+static int translate_acl(struct archive_read_disk *a,
     struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
 
 static int
-setup_acls_posix1e(struct archive_read_disk *a,
+setup_acls(struct archive_read_disk *a,
     struct archive_entry *entry, int *fd)
 {
        const char      *accpath;
        acl_t            acl;
+       int             r;
 
        accpath = archive_entry_sourcepath(entry);
        if (accpath == NULL)
@@ -404,15 +406,33 @@ setup_acls_posix1e(struct archive_read_d
 
        archive_entry_acl_clear(entry);
 
-       if (*fd < 0 && a->tree != NULL &&
-           (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)){
-               *fd = a->open_on_current_dir(a->tree, accpath,
-                               O_RDONLY | O_NONBLOCK);
-               if (*fd < 0) {
-                       archive_set_error(&a->archive, errno,
-                           "Couldn't access %s", accpath);
-                       return (ARCHIVE_FAILED);
-               }
+       /* Try NFS4 ACL first. */
+       if (*fd >= 0)
+               acl = acl_get_fd(*fd);
+#if HAVE_ACL_GET_LINK_NP
+       else if (!a->follow_symlinks)
+               acl = acl_get_link_np(accpath, 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. */
+               acl = NULL;
+#endif
+       else
+               acl = acl_get_file(accpath, ACL_TYPE_NFS4);
+#if HAVE_ACL_IS_TRIVIAL_NP
+       /* Ignore "trivial" ACLs that just mirror the file mode. */
+       acl_is_trivial_np(acl, &r);
+       if (r) {
+               acl_free(acl);
+               acl = NULL;
+       }
+#endif
+       if (acl != NULL) {
+               translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
+               acl_free(acl);
+               return (ARCHIVE_OK);
        }
 
        /* Retrieve access ACL from file. */
@@ -431,7 +451,7 @@ setup_acls_posix1e(struct archive_read_d
        else
                acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
        if (acl != NULL) {
-               setup_acl_posix1e(a, entry, acl,
+               translate_acl(a, entry, acl,
                    ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
                acl_free(acl);
        }
@@ -440,7 +460,7 @@ setup_acls_posix1e(struct archive_read_d
        if (S_ISDIR(archive_entry_mode(entry))) {
                acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
                if (acl != NULL) {
-                       setup_acl_posix1e(a, entry, acl,
+                       translate_acl(a, entry, acl,
                            ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
                        acl_free(acl);
                }
@@ -449,70 +469,182 @@ setup_acls_posix1e(struct archive_read_d
 }
 
 /*
- * Translate POSIX.1e ACL into libarchive internal structure.
+ * Translate system ACL into libarchive internal structure.
  */
-static void
-setup_acl_posix1e(struct archive_read_disk *a,
-    struct archive_entry *entry, acl_t acl, int archive_entry_acl_type)
+
+static struct {
+        int archive_perm;
+        int platform_perm;
+} acl_perm_map[] = {
+        {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
+        {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
+        {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+        {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}
+};
+
+static struct {
+        int archive_inherit;
+        int platform_inherit;
+} acl_inherit_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}
+};
+
+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;
+       acl_entry_type_t acl_type;
+       acl_flagset_t    acl_flagset;
        acl_entry_t      acl_entry;
        acl_permset_t    acl_permset;
+       int              brand, i, r, entry_acl_type;
        int              s, ae_id, ae_tag, ae_perm;
        const char      *ae_name;
 
+
+       // 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.
+       acl_get_brand_np(acl, &brand);
+       switch (brand) {
+       case ACL_BRAND_POSIX:
+               switch (default_entry_acl_type) {
+               case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+               case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+                       entry_acl_type = default_entry_acl_type;
+                       break;
+               default:
+                       // XXX set warning message?
+                       return ARCHIVE_FAILED;
+               }
+               break;
+       case ACL_BRAND_NFS4:
+               if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+                       // XXX set warning message?
+                       return ARCHIVE_FAILED;
+               }
+               break;
+       default:
+               // XXX set warning message?
+               return ARCHIVE_FAILED;
+               break;
+       }
+
+
        s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
        while (s == 1) {
                ae_id = -1;
                ae_name = NULL;
+               ae_perm = 0;
 
                acl_get_tag_type(acl_entry, &acl_tag);
-               if (acl_tag == ACL_USER) {
+               switch (acl_tag) {
+               case ACL_USER:
                        ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
                        ae_name = archive_read_disk_uname(&a->archive, ae_id);
                        ae_tag = ARCHIVE_ENTRY_ACL_USER;
-               } else if (acl_tag == ACL_GROUP) {
+                       break;
+               case ACL_GROUP:
                        ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
                        ae_name = archive_read_disk_gname(&a->archive, ae_id);
                        ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
-               } else if (acl_tag == ACL_MASK) {
+                       break;
+               case ACL_MASK:
                        ae_tag = ARCHIVE_ENTRY_ACL_MASK;
-               } else if (acl_tag == ACL_USER_OBJ) {
+                       break;
+               case ACL_USER_OBJ:
                        ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
-               } else if (acl_tag == ACL_GROUP_OBJ) {
+                       break;
+               case ACL_GROUP_OBJ:
                        ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
-               } else if (acl_tag == ACL_OTHER) {
+                       break;
+               case ACL_OTHER:
                        ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
-               } else {
+                       break;
+               case ACL_EVERYONE:
+                       ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
+                       break;
+               default:
                        /* Skip types that libarchive can't support. */
                        s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
                        continue;
                }
 
-               acl_get_permset(acl_entry, &acl_permset);
-               ae_perm = 0;
+               // XXX acl type maps to allow/deny/audit/YYYY bits
+               // XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
+               // non-NFSv4 ACLs
+               entry_acl_type = default_entry_acl_type;
+               r = acl_get_entry_type_np(acl_entry, &acl_type);
+               if (r == 0) {
+                       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;
+                       }
+               }
+
                /*
-                * acl_get_perm() is spelled differently on different
-                * platforms; see above.
+                * Libarchive stores "flag" (NFSv4 inheritance bits)
+                * in the ae_perm bitmap.
                 */
-               if (ACL_GET_PERM(acl_permset, ACL_EXECUTE))
-                       ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
-               if (ACL_GET_PERM(acl_permset, ACL_READ))
-                       ae_perm |= ARCHIVE_ENTRY_ACL_READ;
-               if (ACL_GET_PERM(acl_permset, ACL_WRITE))
-                       ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
-
-               archive_entry_acl_add_entry(entry,
-                   archive_entry_acl_type, ae_perm, ae_tag,
-                   ae_id, ae_name);
+               acl_get_flagset_np(acl_entry, &acl_flagset);
+                for (i = 0; i < (int)(sizeof(acl_inherit_map) / 
sizeof(acl_inherit_map[0])); ++i) {
+                       if (acl_get_flag_np(acl_flagset,
+                                           
acl_inherit_map[i].platform_inherit))
+                               ae_perm |= acl_inherit_map[i].archive_inherit;
+
+                }
+
+               acl_get_permset(acl_entry, &acl_permset);
+                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.
+                        */
+                       if (ACL_GET_PERM(acl_permset, 
acl_perm_map[i].platform_perm))
+                               ae_perm |= acl_perm_map[i].archive_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);
        }
+       return (ARCHIVE_OK);
 }
 #else
 static int
-setup_acls_posix1e(struct archive_read_disk *a,
-    struct archive_entry *entry, int *fd)
+setup_acls(struct archive_read_disk *a,
+    struct archive_entry *entry, int fd)
 {
        (void)a;      /* UNUSED */
        (void)entry;  /* UNUSED */

Added: head/contrib/libarchive/libarchive/archive_write_disk_acl.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/contrib/libarchive/libarchive/archive_write_disk_acl.c Mon Jul 30 
14:47:35 2012        (r238909)
@@ -0,0 +1,249 @@
+/*-
+ * 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
+#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"
+
+#ifndef HAVE_POSIX_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
+
+static int     set_acl(struct archive *, int fd, const char *,
+                       struct archive_acl *,
+                       acl_type_t, int archive_entry_acl_type, const char *tn);
+
+/*
+ * XXX TODO: What about ACL types other than ACCESS and DEFAULT?
+ */
+int
+archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
+        struct archive_acl *abstract_acl)
+{
+       int              ret;
+
+       if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) > 
0) {
+               ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
+                   ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
+               if (ret != ARCHIVE_OK)
+                       return (ret);
+               ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
+                   ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
+               return (ret);
+       } else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) 
> 0) {
+               ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
+               return (ret);
+       } else
+               return ARCHIVE_OK;
+}
+
+static struct {
+       int archive_perm;
+       int platform_perm;
+} acl_perm_map[] = {
+       {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
+       {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
+       {ARCHIVE_ENTRY_ACL_READ, ACL_READ},
+       {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}
+};
+
+static struct {
+       int archive_inherit;
+       int platform_inherit;
+} acl_inherit_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}
+};
+
+static int
+set_acl(struct archive *a, int fd, const char *name,
+    struct archive_acl *abstract_acl,
+    acl_type_t acl_type, int ae_requested_type, const char *tname)
+{
+       acl_t            acl;
+       acl_entry_t      acl_entry;
+       acl_permset_t    acl_permset;
+       acl_flagset_t    acl_flagset;
+       int              ret;
+       int              ae_type, ae_permset, ae_tag, ae_id;
+       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);
+       acl = acl_init(entries);
+       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
+                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
+               acl_create_entry(&acl, &acl_entry);
+
+               switch (ae_tag) {
+               case ARCHIVE_ENTRY_ACL_USER:
+                       acl_set_tag_type(acl_entry, ACL_USER);
+                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
+                       acl_set_qualifier(acl_entry, &ae_uid);
+                       break;
+               case ARCHIVE_ENTRY_ACL_GROUP:
+                       acl_set_tag_type(acl_entry, ACL_GROUP);
+                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
+                       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;
+               case ARCHIVE_ENTRY_ACL_EVERYONE:
+                       acl_set_tag_type(acl_entry, ACL_EVERYONE);
+                       break;
+               default:
+                       /* XXX */
+                       break;
+               }
+
+               switch (ae_type) {
+               case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+                       acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
+                       break;
+               case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+                       acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
+                       break;
+               case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+                       acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
+                       break;
+               case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+                       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:
+                       // XXX error handling here.
+                       break;
+               }
+
+               acl_get_permset(acl_entry, &acl_permset);
+               acl_clear_perms(acl_permset);
+
+               for (i = 0; i < (int)(sizeof(acl_perm_map) / 
sizeof(acl_perm_map[0])); ++i) {
+                       if (ae_permset & acl_perm_map[i].archive_perm)
+                               acl_add_perm(acl_permset,
+                                            acl_perm_map[i].platform_perm);
+               }
+
+               acl_get_flagset_np(acl_entry, &acl_flagset);
+               acl_clear_flags_np(acl_flagset);
+               for (i = 0; i < (int)(sizeof(acl_inherit_map) / 
sizeof(acl_inherit_map[0])); ++i) {
+                       if (ae_permset & acl_inherit_map[i].archive_inherit)
+                               acl_add_flag_np(acl_flagset,
+                                               
acl_inherit_map[i].platform_inherit);
+               }
+       }
+
+       /* Try restoring the ACL through 'fd' if we can. */
+#if HAVE_ACL_SET_FD
+       if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0)
+               ret = ARCHIVE_OK;
+       else
+#else
+#if HAVE_ACL_SET_FD_NP
+       if (fd >= 0 && acl_set_fd_np(fd, acl, acl_type) == 0)
+               ret = ARCHIVE_OK;
+       else
+#endif
+#endif
+#if HAVE_ACL_SET_LINK_NP
+         if (acl_set_link_np(name, acl_type, acl) != 0) {
+               archive_set_error(a, errno, "Failed to set %s acl", tname);
+               ret = ARCHIVE_WARN;
+         }
+#else
+       /* TODO: Skip this if 'name' is a symlink. */
+       if (acl_set_file(name, acl_type, acl) != 0) {
+               archive_set_error(a, errno, "Failed to set %s acl", tname);
+               ret = ARCHIVE_WARN;
+       }
+#endif
+       acl_free(acl);
+       return (ret);
+}
+#endif

Modified: head/contrib/libarchive/libarchive/archive_write_disk_posix.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_disk_posix.c       Mon Jul 
30 14:34:30 2012        (r238908)
+++ head/contrib/libarchive/libarchive/archive_write_disk_posix.c       Mon Jul 
30 14:47:35 2012        (r238909)
@@ -32,9 +32,6 @@ __FBSDID("$FreeBSD$");
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#ifdef HAVE_SYS_ACL_H
-#include <sys/acl.h>
-#endif
 #ifdef HAVE_SYS_EXTATTR_H
 #include <sys/extattr.h>
 #endif
@@ -129,6 +126,7 @@ __FBSDID("$FreeBSD$");
 #include "archive_string.h"
 #include "archive_entry.h"
 #include "archive_private.h"
+#include "archive_write_disk_private.h"
 
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -267,11 +265,6 @@ static int create_dir(struct archive_wri
 static int     create_parent_dir(struct archive_write_disk *, char *);
 static int     older(struct stat *, struct archive_entry *);
 static int     restore_entry(struct archive_write_disk *);
-#ifdef HAVE_POSIX_ACL
-static int     set_acl(struct archive_write_disk *, int fd, const char *, 
struct archive_acl *,
-                   acl_type_t, int archive_entry_acl_type, const char *tn);
-#endif
-static int     set_acls(struct archive_write_disk *, int fd, const char *, 
struct archive_acl *);
 static int     set_mac_metadata(struct archive_write_disk *, const char *,
                                 const void *, size_t);
 static int     set_xattrs(struct archive_write_disk *);
@@ -570,6 +563,7 @@ _archive_write_disk_header(struct archiv
 
        if (a->deferred & TODO_ACLS) {
                fe = current_fixup(a, archive_entry_pathname(entry));
+               fe->fixup |= TODO_ACLS;
                archive_acl_copy(&fe->acl, archive_entry_acl(entry));
        }
 
@@ -878,7 +872,7 @@ _archive_write_disk_finish_entry(struct 
         * ACLs that prevent attribute changes (including time).
         */
        if (a->todo & TODO_ACLS) {
-               int r2 = set_acls(a, a->fd,
+               int r2 = archive_write_disk_set_acls(&a->archive, a->fd,
                                  archive_entry_pathname(a->entry),
                                  archive_entry_acl(a->entry));
                if (r2 < ret) ret = r2;
@@ -950,12 +944,12 @@ archive_write_disk_gid(struct archive *_
 int64_t
 archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
 {
-       struct archive_write_disk *a = (struct archive_write_disk *)_a;
-       archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
-           ARCHIVE_STATE_ANY, "archive_write_disk_uid");
-       if (a->lookup_uid)
-               return (a->lookup_uid)(a->lookup_uid_data, name, id);
-       return (id);
+       struct archive_write_disk *a = (struct archive_write_disk *)_a;
+       archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+           ARCHIVE_STATE_ANY, "archive_write_disk_uid");
+       if (a->lookup_uid)
+               return (a->lookup_uid)(a->lookup_uid_data, name, id);
+       return (id);
 }
 
 /*
@@ -1381,7 +1375,8 @@ _archive_write_disk_close(struct archive
                if (p->fixup & TODO_MODE_BASE)
                        chmod(p->name, p->mode);
                if (p->fixup & TODO_ACLS)
-                       set_acls(a, -1, p->name, &p->acl);
+                       archive_write_disk_set_acls(&a->archive,
+                                                   -1, p->name, &p->acl);
                if (p->fixup & TODO_FFLAGS)
                        set_fflags_platform(a, -1, p->name,
                            p->mode, p->fflags_set, 0);
@@ -2543,131 +2538,6 @@ set_mac_metadata(struct archive_write_di
 }
 #endif
 
-#ifndef HAVE_POSIX_ACL
-/* Default empty function body to satisfy mainline code. */
-static int
-set_acls(struct archive_write_disk *a, int fd, const char *name,
-        struct archive_acl *aacl)
-{
-       (void)a; /* UNUSED */
-       (void)fd; /* UNUSED */
-       (void)name; /* UNUSED */
-       (void)aacl; /* UNUSED */
-       return (ARCHIVE_OK);
-}
-
-#else
-
-/*
- * XXX TODO: What about ACL types other than ACCESS and DEFAULT?
- */
-static int
-set_acls(struct archive_write_disk *a, int fd, const char *name,
-        struct archive_acl *abstract_acl)
-{
-       int              ret;
-
-       ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
-           ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
-       if (ret != ARCHIVE_OK)
-               return (ret);
-       ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
-           ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
-       return (ret);
-}
-
-
-static int
-set_acl(struct archive_write_disk *a, int fd, const char *name,
-    struct archive_acl *abstract_acl,
-    acl_type_t acl_type, int ae_requested_type, const char *tname)
-{
-       acl_t            acl;
-       acl_entry_t      acl_entry;
-       acl_permset_t    acl_permset;
-       int              ret, r;
-       int              ae_type, ae_permset, ae_tag, ae_id;
-       uid_t            ae_uid;
-       gid_t            ae_gid;
-       const char      *ae_name;
-       int              entries;
-
-       ret = ARCHIVE_OK;
-       entries = archive_acl_reset(abstract_acl, ae_requested_type);
-       if (entries == 0)
-               return (ARCHIVE_OK);
-       acl = acl_init(entries);
-       while ((r = archive_acl_next(&a->archive, abstract_acl,
-           ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id,
-           &ae_name)) == ARCHIVE_OK) {
-               acl_create_entry(&acl, &acl_entry);
-
-               switch (ae_tag) {
-               case ARCHIVE_ENTRY_ACL_USER:
-                       acl_set_tag_type(acl_entry, ACL_USER);
-                       ae_uid = archive_write_disk_uid(&a->archive,
-                           ae_name, ae_id);
-                       acl_set_qualifier(acl_entry, &ae_uid);
-                       break;
-               case ARCHIVE_ENTRY_ACL_GROUP:
-                       acl_set_tag_type(acl_entry, ACL_GROUP);
-                       ae_gid = archive_write_disk_gid(&a->archive,
-                           ae_name, ae_id);
-                       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;
-               default:
-                       /* XXX */
-                       break;
-               }
-
-               acl_get_permset(acl_entry, &acl_permset);
-               acl_clear_perms(acl_permset);
-               if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
-                       acl_add_perm(acl_permset, ACL_EXECUTE);
-               if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
-                       acl_add_perm(acl_permset, ACL_WRITE);
-               if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
-                       acl_add_perm(acl_permset, ACL_READ);
-       }
-       if (r == ARCHIVE_FATAL) {
-               acl_free(acl);
-               archive_set_error(&a->archive, errno,
-                   "Failed to archive_acl_next");
-               return (r);
-       }
-
-       /* Try restoring the ACL through 'fd' if we can. */
-#if HAVE_ACL_SET_FD
-       if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0)
-               ret = ARCHIVE_OK;
-       else
-#else
-#if HAVE_ACL_SET_FD_NP
-       if (fd >= 0 && acl_set_fd_np(fd, acl, acl_type) == 0)
-               ret = ARCHIVE_OK;
-       else
-#endif
-#endif
-       if (acl_set_file(name, acl_type, acl) != 0) {
-               archive_set_error(&a->archive, errno, "Failed to set %s acl", 
tname);
-               ret = ARCHIVE_WARN;
-       }
-       acl_free(acl);
-       return (ret);
-}
-#endif
 
 #if HAVE_LSETXATTR || HAVE_LSETEA
 /*

Modified: head/contrib/libarchive/libarchive/archive_write_disk_private.h
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_disk_private.h     Mon Jul 
30 14:34:30 2012        (r238908)
+++ head/contrib/libarchive/libarchive/archive_write_disk_private.h     Mon Jul 
30 14:47:35 2012        (r238909)
@@ -33,6 +33,11 @@
 #ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
 #define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
 
+#include "archive_acl_private.h"
+
 struct archive_write_disk;
 
+int
+archive_write_disk_set_acls(struct archive *, int /* fd */, const char * /* 
pathname */, struct archive_acl *);
+
 #endif

Added: head/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c     Mon Jul 
30 14:47:35 2012        (r238909)
@@ -0,0 +1,1094 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#if defined(__FreeBSD__) && __FreeBSD__ >= 8
+#define _ACL_PRIVATE
+#include <sys/acl.h>
+
+struct myacl_t {
+       int type;
+       int permset;
+       int tag;
+       int qual; /* GID or UID of user/group, depending on tag. */
+       const char *name; /* Name of user/group, depending on tag. */
+};
+
+static struct myacl_t acls_reg[] = {
+       /* For this test, we need the file owner to be able to read and write 
the ACL. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | 
ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | 
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
+         ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
+
+       /* An entry for each type. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+         ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
+       { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
+         ARCHIVE_ENTRY_ACL_USER, 109, "user109" },
+
+       /* An entry for each permission. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+         ARCHIVE_ENTRY_ACL_USER, 112, "user112" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA,
+         ARCHIVE_ENTRY_ACL_USER, 113, "user113" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA,
+         ARCHIVE_ENTRY_ACL_USER, 115, "user115" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA,
+         ARCHIVE_ENTRY_ACL_USER, 117, "user117" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
+         ARCHIVE_ENTRY_ACL_USER, 119, "user119" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
+         ARCHIVE_ENTRY_ACL_USER, 120, "user120" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
+         ARCHIVE_ENTRY_ACL_USER, 122, "user122" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
+         ARCHIVE_ENTRY_ACL_USER, 123, "user123" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
+         ARCHIVE_ENTRY_ACL_USER, 124, "user124" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
+         ARCHIVE_ENTRY_ACL_USER, 125, "user125" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
+         ARCHIVE_ENTRY_ACL_USER, 126, "user126" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
+         ARCHIVE_ENTRY_ACL_USER, 127, "user127" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+         ARCHIVE_ENTRY_ACL_USER, 128, "user128" },
+
+       /* One entry for each qualifier. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+         ARCHIVE_ENTRY_ACL_USER, 135, "user135" },
+//     { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+//       ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+         ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+         ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
+         ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
+};
+
+
+static struct myacl_t acls_dir[] = {
+       /* For this test, we need to be able to read and write the ACL. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
+         ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
+
+       /* An entry for each type. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+         ARCHIVE_ENTRY_ACL_USER, 101, "user101" },
+       { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+         ARCHIVE_ENTRY_ACL_USER, 102, "user102" },
+
+       /* An entry for each permission. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+         ARCHIVE_ENTRY_ACL_USER, 201, "user201" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE,
+         ARCHIVE_ENTRY_ACL_USER, 202, "user202" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
+         ARCHIVE_ENTRY_ACL_USER, 203, "user203" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
+         ARCHIVE_ENTRY_ACL_USER, 204, "user204" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
+         ARCHIVE_ENTRY_ACL_USER, 205, "user205" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD,
+         ARCHIVE_ENTRY_ACL_USER, 206, "user206" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
+         ARCHIVE_ENTRY_ACL_USER, 207, "user207" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
+         ARCHIVE_ENTRY_ACL_USER, 208, "user208" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
+         ARCHIVE_ENTRY_ACL_USER, 209, "user209" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
+         ARCHIVE_ENTRY_ACL_USER, 210, "user210" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
+         ARCHIVE_ENTRY_ACL_USER, 211, "user211" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
+         ARCHIVE_ENTRY_ACL_USER, 212, "user212" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
+         ARCHIVE_ENTRY_ACL_USER, 213, "user213" },
+
+       /* One entry with each inheritance value. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT,
+         ARCHIVE_ENTRY_ACL_USER, 301, "user301" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+         ARCHIVE_ENTRY_ACL_READ_DATA | 
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
+         ARCHIVE_ENTRY_ACL_USER, 302, "user302" },
+#if 0
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+         ARCHIVE_ENTRY_ACL_READ_DATA | 
ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
+         ARCHIVE_ENTRY_ACL_USER, 303, "user303" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
+         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
+         ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
+#endif
+
+#if 0
+       /* FreeBSD does not support audit entries. */
+       { ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+         ARCHIVE_ENTRY_ACL_READ_DATA | 
ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS,
+         ARCHIVE_ENTRY_ACL_USER, 401, "user401" },
+       { ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
+         ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS,
+         ARCHIVE_ENTRY_ACL_USER, 402, "user402" },
+#endif
+
+       /* One entry for each qualifier. */
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+         ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+         ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+         ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
+       { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
+         ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
+};
+
+static void
+set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
+{
+       int i;
+
+       archive_entry_acl_clear(ae);
+       if (start > 0) {
+               assertEqualInt(ARCHIVE_OK,
+                       archive_entry_acl_add_entry(ae,
+                           acls[0].type, acls[0].permset, acls[0].tag,
+                           acls[0].qual, acls[0].name));
+       }
+       for (i = start; i < end; i++) {
+               assertEqualInt(ARCHIVE_OK,
+                   archive_entry_acl_add_entry(ae,
+                       acls[i].type, acls[i].permset, acls[i].tag,
+                       acls[i].qual, acls[i].name));
+       }

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

Reply via email to