]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Unify platform ACL code in single files.
authorMartin Matuska <martin@matuska.org>
Tue, 28 Mar 2017 00:52:21 +0000 (02:52 +0200)
committerMartin Matuska <martin@matuska.org>
Tue, 28 Mar 2017 00:52:21 +0000 (02:52 +0200)
Declare map constants static for better optimization.

15 files changed:
Makefile.am
libarchive/CMakeLists.txt
libarchive/archive_acl_maps.h [deleted file]
libarchive/archive_acl_maps_darwin.c [deleted file]
libarchive/archive_acl_maps_freebsd.c [deleted file]
libarchive/archive_acl_maps_linux.c [deleted file]
libarchive/archive_acl_maps_sunos.c [deleted file]
libarchive/archive_disk_acl_darwin.c [moved from libarchive/archive_read_disk_acl_darwin.c with 57% similarity]
libarchive/archive_disk_acl_freebsd.c [moved from libarchive/archive_read_disk_acl_freebsd.c with 51% similarity]
libarchive/archive_disk_acl_linux.c [moved from libarchive/archive_write_disk_acl_linux.c with 51% similarity]
libarchive/archive_disk_acl_sunos.c [moved from libarchive/archive_read_disk_acl_sunos.c with 57% similarity]
libarchive/archive_read_disk_acl_linux.c [deleted file]
libarchive/archive_write_disk_acl_darwin.c [deleted file]
libarchive/archive_write_disk_acl_freebsd.c [deleted file]
libarchive/archive_write_disk_acl_sunos.c [deleted file]

index 6d2f1d3e245da95b561f58eb21e4124dff2d66d4..cc6f6befbed778263af989a64dcc4e5b2a9650a3 100644 (file)
@@ -250,32 +250,16 @@ libarchive_la_SOURCES+= \
 endif
 
 if INC_LINUX_ACL
-libarchive_la_SOURCES+= \
-       libarchive/archive_acl_maps.h \
-       libarchive/archive_acl_maps_linux.c \
-       libarchive/archive_read_disk_acl_linux.c \
-       libarchive/archive_write_disk_acl_linux.c
+libarchive_la_SOURCES+= libarchive/archive_disk_acl_linux.c
 else
 if INC_SUNOS_ACL
-libarchive_la_SOURCES+= \
-       libarchive/archive_acl_maps.h \
-       libarchive/archive_acl_maps_sunos.c \
-       libarchive/archive_read_disk_acl_sunos.c \
-       libarchive/archive_write_disk_acl_sunos.c
+libarchive_la_SOURCES+= libarchive/archive_disk_acl_sunos.c
 else
 if INC_DARWIN_ACL
-libarchive_la_SOURCES+= \
-       libarchive/archive_acl_maps.h \
-       libarchive/archive_acl_maps_darwin.c \
-       libarchive/archive_read_disk_acl_darwin.c \
-       libarchive/archive_write_disk_acl_darwin.c
+libarchive_la_SOURCES+= libarchive/archive_disk_acl_darwin.c
 else
 if INC_FREEBSD_ACL
-libarchive_la_SOURCES+= \
-       libarchive/archive_acl_maps.h \
-       libarchive/archive_acl_maps_freebsd.c \
-       libarchive/archive_read_disk_acl_freebsd.c \
-       libarchive/archive_write_disk_acl_freebsd.c
+libarchive_la_SOURCES+= libarchive/archive_disk_acl_freebsd.c
 endif
 endif
 endif
index 44ffd453f3480a87b5aa461613b60aed2ac3430d..5e958da1c538c4968ff65a9e6ec00118c4c200d8 100644 (file)
@@ -214,25 +214,13 @@ IF(WIN32 AND NOT CYGWIN)
 ENDIF(WIN32 AND NOT CYGWIN)
 
 IF(ARCHIVE_ACL_DARWIN)
-  LIST(APPEND libarchive_SOURCES archive_acl_maps.h)
-  LIST(APPEND libarchive_SOURCES archive_acl_maps_darwin.c)
-  LIST(APPEND libarchive_SOURCES archive_read_disk_acl_darwin.c)
-  LIST(APPEND libarchive_SOURCES archive_write_disk_acl_darwin.c)
+  LIST(APPEND libarchive_SOURCES archive_disk_acl_darwin.c)
 ELSEIF(ARCHIVE_ACL_FREEBSD)
-  LIST(APPEND libarchive_SOURCES archive_acl_maps.h)
-  LIST(APPEND libarchive_SOURCES archive_acl_maps_freebsd.c)
-  LIST(APPEND libarchive_SOURCES archive_read_disk_acl_freebsd.c)
-  LIST(APPEND libarchive_SOURCES archive_write_disk_acl_freebsd.c)
+  LIST(APPEND libarchive_SOURCES archive_disk_acl_freebsd.c)
 ELSEIF(ARCHIVE_ACL_LIBACL)
-  LIST(APPEND libarchive_SOURCES archive_acl_maps.h)
-  LIST(APPEND libarchive_SOURCES archive_acl_maps_linux.c)
-  LIST(APPEND libarchive_SOURCES archive_read_disk_acl_linux.c)
-  LIST(APPEND libarchive_SOURCES archive_write_disk_acl_linux.c)
+  LIST(APPEND libarchive_SOURCES archive_disk_acl_linux.c)
 ELSEIF(ARCHIVE_ACL_SUNOS)
-  LIST(APPEND libarchive_SOURCES archive_acl_maps.h)
-  LIST(APPEND libarchive_SOURCES archive_acl_maps_sunos.c)
-  LIST(APPEND libarchive_SOURCES archive_read_disk_acl_sunos.c)
-  LIST(APPEND libarchive_SOURCES archive_write_disk_acl_sunos.c)
+  LIST(APPEND libarchive_SOURCES archive_disk_acl_sunos.c)
 ENDIF()
 
 # Libarchive is a shared library
diff --git a/libarchive/archive_acl_maps.h b/libarchive/archive_acl_maps.h
deleted file mode 100644 (file)
index e3f4408..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * 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/libarchive/archive_acl_maps_darwin.c b/libarchive/archive_acl_maps_darwin.c
deleted file mode 100644 (file)
index af0f4c3..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*-
- * 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_nfs4_perm_map[] = {
-       {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
-};
-
-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_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}
-};
-
-const int acl_nfs4_flag_map_size =
-    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
diff --git a/libarchive/archive_acl_maps_freebsd.c b/libarchive/archive_acl_maps_freebsd.c
deleted file mode 100644 (file)
index 17b1e95..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*-
- * 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/libarchive/archive_acl_maps_linux.c b/libarchive/archive_acl_maps_linux.c
deleted file mode 100644 (file)
index 04f630e..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * 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
-#ifdef HAVE_SYS_RICHACL_H
-#include <sys/richacl.h>
-#endif
-
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_disk_private.h"
-#include "archive_acl_maps.h"
-
-#if ARCHIVE_ACL_LIBACL
-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]));
-#endif /* ARCHIVE_ACL_LIBACL */
-
-#if ARCHIVE_ACL_LIBRICHACL
-const acl_perm_map_t acl_nfs4_perm_map[] = {
-       {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}
-};
-
-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, 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}
-};
-
-const int acl_nfs4_flag_map_size =
-    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
-#endif /* ARCHIVE_ACL_LIBRICHACL */
diff --git a/libarchive/archive_acl_maps_sunos.c b/libarchive/archive_acl_maps_sunos.c
deleted file mode 100644 (file)
index bdc869d..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-
- * 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, S_IXOTH },
-       {ARCHIVE_ENTRY_ACL_WRITE, S_IWOTH },
-       {ARCHIVE_ENTRY_ACL_READ, S_IROTH }
-};
-
-const int acl_posix_perm_map_size =
-    (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
-
-#if ARCHIVE_ACL_SUNOS_NFS4
-const acl_perm_map_t acl_nfs4_perm_map[] = {
-       {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}
-};
-
-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, 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
-};
-
-const int acl_nfs4_flag_map_size =
-    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
-
-#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
similarity index 57%
rename from libarchive/archive_read_disk_acl_darwin.c
rename to libarchive/archive_disk_acl_darwin.c
index 8de33b91473fbb097a5fa9fde8b1f71342646784..0d3bc4e9861f55562aec270d9a76e55ba6efe409 100644 (file)
 #include "archive_entry.h"
 #include "archive_private.h"
 #include "archive_read_disk_private.h"
-#include "archive_acl_maps.h"
+#include "archive_write_disk_private.h"
+
+typedef struct {
+       const int a_perm;       /* Libarchive permission or flag */
+       const int p_perm;       /* Platform permission or flag */
+} acl_perm_map_t;
+
+static const acl_perm_map_t acl_nfs4_perm_map[] = {
+       {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
+};
 
+static const int acl_nfs4_perm_map_size =
+    (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
+
+static const acl_perm_map_t acl_nfs4_flag_map[] = {
+       {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}
+};
+
+static const int acl_nfs4_flag_map_size =
+    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
 
-/*
- * Darwin-specific ACL functions and helper functions
- *
- * Exported functions:
- * none
- */
 static int translate_guid(struct archive *a, acl_entry_t acl_entry,
     int *ae_id, int *ae_tag, const char **ae_name)
 {
@@ -84,9 +118,6 @@ static int translate_guid(struct archive *a, acl_entry_t acl_entry,
        return (r);
 }
 
-/*
- * Add trivial NFSv4 ACL entries from mode
- */
 static void
 add_trivial_nfs4_acl(struct archive_entry *entry)
 {
@@ -284,6 +315,178 @@ translate_acl(struct archive_read_disk *a,
        return (ARCHIVE_OK);
 }
 
+static int
+set_acl(struct archive *a, int fd, const char *name,
+    struct archive_acl *abstract_acl,
+    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;
+       uuid_t           ae_uuid;
+       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 (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+               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) {
+               /*
+                * 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;
+
+               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_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;
+               }
+
+               switch (ae_tag) {
+               case ARCHIVE_ENTRY_ACL_USER:
+                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
+                       if (mbr_uid_to_uuid(ae_uid, ae_uuid) != 0)
+                               continue;
+                       if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
+                               continue;
+                       break;
+               case ARCHIVE_ENTRY_ACL_GROUP:
+                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
+                       if (mbr_gid_to_uuid(ae_gid, ae_uuid) != 0)
+                               continue;
+                       if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
+                               continue;
+                       break;
+               default:
+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
+                           "Unsupported ACL tag");
+                       ret = ARCHIVE_FAILED;
+                       goto exit_free;
+               }
+
+               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;
+               }
+
+               for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
+                       if (ae_permset & acl_nfs4_perm_map[i].a_perm) {
+                               if (acl_add_perm(acl_permset,
+                                   acl_nfs4_perm_map[i].p_perm) != 0) {
+                                       archive_set_error(a, errno,
+                                           "Failed to add ACL permission");
+                                       ret = ARCHIVE_FAILED;
+                                       goto exit_free;
+                               }
+                       }
+               }
+
+               /*
+                * 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;
+                               }
+                       }
+               }
+       }
+
+       if (fd >= 0) {
+               if (acl_set_fd_np(fd, acl, ACL_TYPE_EXTENDED) == 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;
+                       }
+               }
+       } else if (acl_set_link_np(name, ACL_TYPE_EXTENDED, acl) != 0) {
+               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_read_disk_entry_setup_acls(struct archive_read_disk *a,
     struct archive_entry *entry, int *fd)
@@ -335,3 +538,19 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
        }
        return (ARCHIVE_OK);
 }
+
+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_NFS4) != 0) {
+               ret = set_acl(a, fd, name, abstract_acl,
+                   ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
+       }
+       return (ret);
+}
similarity index 51%
rename from libarchive/archive_read_disk_acl_freebsd.c
rename to libarchive/archive_disk_acl_freebsd.c
index c09c3e1c2b51dc9fd69e640121cd65ea50f969b3..04a3fc065e1f61f4f646a680164bb484005d3507 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  * Copyright (c) 2003-2009 Tim Kientzle
  * Copyright (c) 2010-2012 Michihiro NAKAJIMA
- * Copyright (c) 2016-2017 Martin Matuska
+ * Copyright (c) 2017 Martin Matuska
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "archive_entry.h"
 #include "archive_private.h"
 #include "archive_read_disk_private.h"
-#include "archive_acl_maps.h"
+#include "archive_write_disk_private.h"
+
+typedef struct {
+       const int a_perm;       /* Libarchive permission or flag */
+       const int p_perm;       /* Platform permission or flag */
+} acl_perm_map_t;
+
+static 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},
+};
+
+static const int acl_posix_perm_map_size =
+    (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+static 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}
+};
+
+static const int acl_nfs4_perm_map_size =
+    (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
+
+static 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}
+};
+
+static const int acl_nfs4_flag_map_size =
+    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
+#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */
 
-/*
- * 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)
@@ -264,6 +313,248 @@ translate_acl(struct archive_read_disk *a,
        return (ARCHIVE_OK);
 }
 
+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_read_disk_entry_setup_acls(struct archive_read_disk *a,
     struct archive_entry *entry, int *fd)
@@ -369,3 +660,38 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
        }
        return (ARCHIVE_OK);
 }
+
+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);
+}
similarity index 51%
rename from libarchive/archive_write_disk_acl_linux.c
rename to libarchive/archive_disk_acl_linux.c
index 2239df6c10f70b4f482b8493b89135b2acdedd80..e9c5391fe5d52765aecae313b6c45cdac2ab1072 100644 (file)
@@ -1,13 +1,12 @@
 /*-
- * Copyright (c) 2003-2010 Tim Kientzle
+ * 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
- *    in this position and unchanged.
+ *    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.
 #ifdef HAVE_SYS_ACL_H
 #include <sys/acl.h>
 #endif
-#if HAVE_SYS_RICHACL_H
+#ifdef HAVE_SYS_RICHACL_H
 #include <sys/richacl.h>
 #endif
 
-#include "archive.h"
 #include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
 #include "archive_write_disk_private.h"
-#include "archive_acl_maps.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_LIBACL
+static 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},
+};
+
+static const int acl_posix_perm_map_size =
+    (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
+#endif /* ARCHIVE_ACL_LIBACL */
+
+#if ARCHIVE_ACL_LIBRICHACL
+static const acl_perm_map_t acl_nfs4_perm_map[] = {
+       {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}
+};
+
+static const int acl_nfs4_perm_map_size =
+    (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
+
+static const acl_perm_map_t acl_nfs4_flag_map[] = {
+       {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}
+};
+
+static const int acl_nfs4_flag_map_size =
+    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
+#endif /* ARCHIVE_ACL_LIBRICHACL */
+
+#if ARCHIVE_ACL_LIBACL
+/*
+ * Translate POSIX.1e 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;
+       acl_entry_t      acl_entry;
+       acl_permset_t    acl_permset;
+       int              i, entry_acl_type;
+       int              r, s, ae_id, ae_tag, ae_perm;
+       void            *q;
+       const char      *ae_name;
+
+       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;
+               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 (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 < acl_posix_perm_map_size; ++i) {
+                       r = acl_get_perm(acl_permset,
+                           acl_posix_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 |= acl_posix_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);
+}
+#endif /* ARCHIVE_ACL_LIBACL */
+
+#if ARCHIVE_ACL_LIBRICHACL
+/*
+ * Translate RichACL into libarchive internal ACL
+ */
+static int
+translate_richacl(struct archive_read_disk *a, struct archive_entry *entry,
+    struct richacl *richacl)
+{
+       int ae_id, ae_tag, ae_perm;
+       int entry_acl_type, i;
+       const char *ae_name;
+
+       struct richace *richace;
+
+       richacl_for_each_entry(richace, richacl) {
+               ae_name = NULL;
+               ae_tag = 0;
+               ae_perm = 0;
+               ae_id = -1;
+
+               switch (richace->e_type) {
+               case RICHACE_ACCESS_ALLOWED_ACE_TYPE:
+                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
+                       break;
+               case RICHACE_ACCESS_DENIED_ACE_TYPE:
+                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
+                       break;
+               default: /* Unknown entry type, skip */
+                       continue;
+               }
+
+               /* Unsupported */
+               if (richace->e_flags & RICHACE_UNMAPPED_WHO)
+                       continue;
+
+               if (richace->e_flags & RICHACE_SPECIAL_WHO) {
+                       switch (richace->e_id) {
+                       case RICHACE_OWNER_SPECIAL_ID:
+                               ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+                               break;
+                       case RICHACE_GROUP_SPECIAL_ID:
+                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+                               break;
+                       case RICHACE_EVERYONE_SPECIAL_ID:
+                               ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
+                               break;
+                       default: /* Unknown special ID type */
+                               continue;
+                       }
+               } else {
+                       ae_id = richace->e_id;
+                       if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) {
+                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+                               ae_name = archive_read_disk_gname(&a->archive,
+                                   (gid_t)(richace->e_id));
+                       } else {
+                               ae_tag = ARCHIVE_ENTRY_ACL_USER;
+                               ae_name = archive_read_disk_uname(&a->archive,
+                                   (uid_t)(richace->e_id));
+                       }
+               }
+               for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+                       if ((richace->e_flags &
+                           acl_nfs4_flag_map[i].p_perm) != 0)
+                               ae_perm |= acl_nfs4_flag_map[i].a_perm;
+               }
+               for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
+                       if ((richace->e_mask &
+                           acl_nfs4_perm_map[i].p_perm) != 0)
+                               ae_perm |=
+                                   acl_nfs4_perm_map[i].a_perm;
+               }
+
+               archive_entry_acl_add_entry(entry, entry_acl_type,
+                   ae_perm, ae_tag, ae_id, ae_name);
+       }
+       return (ARCHIVE_OK);
+}
+#endif /* ARCHIVE_ACL_LIBRICHACL */
 
 #if ARCHIVE_ACL_LIBRICHACL
 static int
@@ -348,6 +587,117 @@ exit_free:
 }
 #endif /* ARCHIVE_ACL_LIBACL */
 
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
+    struct archive_entry *entry, int *fd)
+{
+       const char      *accpath;
+       int             r;
+#if ARCHIVE_ACL_LIBACL
+       acl_t           acl;
+#endif
+#if ARCHIVE_ACL_LIBRICHACL
+       struct richacl *richacl;
+       mode_t          mode;
+#endif
+
+       accpath = NULL;
+       r = ARCHIVE_OK;
+
+       /* For default ACLs we need reachable accpath */
+       if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) {
+               accpath = archive_read_disk_entry_setup_path(a, entry, fd);
+               if (accpath == NULL)
+                       return (ARCHIVE_WARN);
+       }
+
+       archive_entry_acl_clear(entry);
+
+#if ARCHIVE_ACL_LIBACL
+       acl = NULL;
+#endif
+#if ARCHIVE_ACL_LIBRICHACL
+       richacl = NULL;
+#endif
+
+#if ARCHIVE_ACL_LIBRICHACL
+       /* Try NFSv4 ACL first. */
+       if (*fd >= 0)
+               richacl = richacl_get_fd(*fd);
+       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 */
+               richacl = NULL;
+       else
+               richacl = richacl_get_file(accpath);
+
+       /* Ignore "trivial" ACLs that just mirror the file mode. */
+       if (richacl != NULL) {
+               mode = archive_entry_mode(entry);
+               if (richacl_equiv_mode(richacl, &mode) == 0) {
+                       richacl_free(richacl);
+                       richacl = NULL;
+                       return (ARCHIVE_OK);
+               }
+       }
+
+       if (richacl != NULL) {
+               r = translate_richacl(a, entry, richacl);
+               richacl_free(richacl);
+               richacl = NULL;
+
+               if (r != ARCHIVE_OK) {
+                       archive_set_error(&a->archive, errno,
+                       "Couldn't translate NFSv4 ACLs");
+               }
+
+               return (r);
+       }
+#endif /* ARCHIVE_ACL_LIBRICHACL */
+
+#if ARCHIVE_ACL_LIBACL
+       /* Retrieve access ACL from file. */
+       if (*fd >= 0)
+               acl = acl_get_fd(*fd);
+       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;
+       else
+               acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
+
+       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))) {
+               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 /* ARCHIVE_ACL_LIBACL */
+       return (r);
+}
+
 int
 archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
     struct archive_acl *abstract_acl, __LA_MODE_T mode)
similarity index 57%
rename from libarchive/archive_read_disk_acl_sunos.c
rename to libarchive/archive_disk_acl_sunos.c
index 066c30371b562f239f8a23c50d4d9a8e11551448..7d806b016f90635fe6879a718728d3b95fdc429f 100644 (file)
 #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"
+#include "archive_write_disk_private.h"
+
+typedef struct {
+       const int a_perm;       /* Libarchive permission or flag */
+       const int p_perm;       /* Platform permission or flag */
+} acl_perm_map_t;
+
+static const acl_perm_map_t acl_posix_perm_map[] = {
+       {ARCHIVE_ENTRY_ACL_EXECUTE, S_IXOTH },
+       {ARCHIVE_ENTRY_ACL_WRITE, S_IWOTH },
+       {ARCHIVE_ENTRY_ACL_READ, S_IROTH }
+};
+
+static const int acl_posix_perm_map_size =
+    (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0]));
+
+#if ARCHIVE_ACL_SUNOS_NFS4
+static const acl_perm_map_t acl_nfs4_perm_map[] = {
+       {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}
+};
+
+static const int acl_nfs4_perm_map_size =
+    (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0]));
+
+static const acl_perm_map_t acl_nfs4_flag_map[] = {
+       {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
+};
+
+const int acl_nfs4_flag_map_size =
+    (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0]));
+
+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
 
-/*
- * Solaris-specific ACL functions and helper functions
- *
- * Exported functions:
- * translate_acl()
- */
 static void *
 sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
 {
@@ -391,6 +441,265 @@ translate_acl(struct archive_read_disk *a,
        return (ARCHIVE_OK);
 }
 
+static int
+set_acl(struct archive *a, int fd, const char *name,
+    struct archive_acl *abstract_acl,
+    int ae_requested_type, const char *tname)
+{
+       aclent_t         *aclent;
+#if ARCHIVE_ACL_SUNOS_NFS4
+       ace_t            *ace;
+#endif
+       int              cmd, e, r;
+       void             *aclp;
+       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_POSIX1E:
+               cmd = SETACL;
+               aclp = malloc(entries * sizeof(aclent_t));
+               break;
+#if ARCHIVE_ACL_SUNOS_NFS4
+       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, "Unsupported ACL type");
+               return (ARCHIVE_FAILED);
+       }
+
+       if (aclp == NULL) {
+               archive_set_error(a, errno,
+                   "Can't allocate memory for acl buffer");
+               return (ARCHIVE_FAILED);
+       }
+
+       e = 0;
+
+       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
+                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
+               aclent = NULL;
+#if ARCHIVE_ACL_SUNOS_NFS4
+               ace = NULL;
+#endif
+               if (cmd == SETACL) {
+                       aclent = &((aclent_t *)aclp)[e];
+                       aclent->a_id = -1;
+                       aclent->a_type = 0;
+                       aclent->a_perm = 0;
+               }
+#if ARCHIVE_ACL_SUNOS_NFS4
+               else {  /* cmd == ACE_SETACL */
+                       ace = &((ace_t *)aclp)[e];
+                       ace->a_who = -1;
+                       ace->a_access_mask = 0;
+                       ace->a_flags = 0;
+               }
+#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
+
+               switch (ae_tag) {
+               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 ARCHIVE_ACL_SUNOS_NFS4
+                       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 ARCHIVE_ACL_SUNOS_NFS4
+                       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 ARCHIVE_ACL_SUNOS_NFS4
+                       else {
+                               ace->a_flags |= ACE_OWNER;
+                       }
+#endif
+                       break;
+               case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+                       if (aclent != NULL)
+                               aclent->a_type |= GROUP_OBJ;
+#if ARCHIVE_ACL_SUNOS_NFS4
+                       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 ARCHIVE_ACL_SUNOS_NFS4
+               case ARCHIVE_ENTRY_ACL_EVERYONE:
+                       if (ace != NULL)
+                               ace->a_flags |= ACE_EVERYONE;
+                       break;
+#endif
+               default:
+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
+                           "Unsupported ACL tag");
+                       ret = ARCHIVE_FAILED;
+                       goto exit_free;
+               }
+
+               r = 0;
+               switch (ae_type) {
+#if ARCHIVE_ACL_SUNOS_NFS4
+               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;
+               default:
+                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
+                           "Unsupported ACL entry type");
+                       ret = ARCHIVE_FAILED;
+                       goto exit_free;
+               }
+
+               if (r != 0) {
+                       errno = EINVAL;
+                       archive_set_error(a, errno,
+                           "Failed to set ACL entry type");
+                       ret = ARCHIVE_FAILED;
+                       goto exit_free;
+               }
+
+#if ARCHIVE_ACL_SUNOS_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_SUNOS_NFS4
+               }
+#endif
+               for (i = 0; i < perm_map_size; ++i) {
+                       if (ae_permset & perm_map[i].a_perm) {
+#if ARCHIVE_ACL_SUNOS_NFS4
+                               if (ae_requested_type ==
+                                   ARCHIVE_ENTRY_ACL_TYPE_NFS4)
+                                       ace->a_access_mask |=
+                                           perm_map[i].p_perm;
+                               else
+#endif
+                                       aclent->a_perm |= perm_map[i].p_perm;
+                       }
+               }
+
+#if ARCHIVE_ACL_SUNOS_NFS4
+               if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+                       for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+                               if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
+                                       ace->a_flags |=
+                                           acl_nfs4_flag_map[i].p_perm;
+                               }
+                       }
+               }
+#endif
+       e++;
+       }
+
+       /* Try restoring the ACL through 'fd' if we can. */
+       if (fd >= 0) {
+               if (facl(fd, cmd, entries, aclp) == 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;
+                       }
+               }
+       } else if (acl(name, cmd, entries, aclp) != 0) {
+               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:
+       free(aclp);
+       return (ret);
+}
+
 int
 archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
     struct archive_entry *entry, int *fd)
@@ -480,3 +789,30 @@ archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
 
        return (ARCHIVE_OK);
 }
+
+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) {
+               /* Solaris writes POSIX.1e access and default ACLs together */
+               ret = set_acl(a, fd, name, abstract_acl,
+                   ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
+
+               /* Simultaneous POSIX.1e and NFSv4 is not supported */
+               return (ret);
+       }
+#if ARCHIVE_ACL_SUNOS_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/libarchive/archive_read_disk_acl_linux.c b/libarchive/archive_read_disk_acl_linux.c
deleted file mode 100644 (file)
index 033e68a..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*-
- * 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
-#if HAVE_ACL_LIBACL_H
-#include <acl/libacl.h>
-#endif
-#ifdef HAVE_SYS_ACL_H
-#include <sys/acl.h>
-#endif
-#if HAVE_SYS_RICHACL_H
-#include <sys/richacl.h>
-#endif
-
-#include "archive_entry.h"
-#include "archive_private.h"
-#include "archive_read_disk_private.h"
-#include "archive_acl_maps.h"
-
-#if HAVE_LIBACL
-#include <acl/libacl.h>
-#endif
-
-#if ARCHIVE_ACL_LIBACL
-/*
- * Translate POSIX.1e 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;
-       acl_entry_t      acl_entry;
-       acl_permset_t    acl_permset;
-       int              i, entry_acl_type;
-       int              r, s, ae_id, ae_tag, ae_perm;
-       void            *q;
-       const char      *ae_name;
-
-       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;
-               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 (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 < acl_posix_perm_map_size; ++i) {
-                       r = acl_get_perm(acl_permset,
-                           acl_posix_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 |= acl_posix_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);
-}
-#endif /* ARCHIVE_ACL_LIBACL */
-
-#if ARCHIVE_ACL_LIBRICHACL
-/*
- * Translate RichACL into libarchive internal ACL
- */
-static int
-translate_richacl(struct archive_read_disk *a, struct archive_entry *entry,
-    struct richacl *richacl)
-{
-       int ae_id, ae_tag, ae_perm;
-       int entry_acl_type, i;
-       const char *ae_name;
-
-       struct richace *richace;
-
-       richacl_for_each_entry(richace, richacl) {
-               ae_name = NULL;
-               ae_tag = 0;
-               ae_perm = 0;
-               ae_id = -1;
-
-               switch (richace->e_type) {
-               case RICHACE_ACCESS_ALLOWED_ACE_TYPE:
-                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
-                       break;
-               case RICHACE_ACCESS_DENIED_ACE_TYPE:
-                       entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
-                       break;
-               default: /* Unknown entry type, skip */
-                       continue;
-               }
-
-               /* Unsupported */
-               if (richace->e_flags & RICHACE_UNMAPPED_WHO)
-                       continue;
-
-               if (richace->e_flags & RICHACE_SPECIAL_WHO) {
-                       switch (richace->e_id) {
-                       case RICHACE_OWNER_SPECIAL_ID:
-                               ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
-                               break;
-                       case RICHACE_GROUP_SPECIAL_ID:
-                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
-                               break;
-                       case RICHACE_EVERYONE_SPECIAL_ID:
-                               ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
-                               break;
-                       default: /* Unknown special ID type */
-                               continue;
-                       }
-               } else {
-                       ae_id = richace->e_id;
-                       if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) {
-                               ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
-                               ae_name = archive_read_disk_gname(&a->archive,
-                                   (gid_t)(richace->e_id));
-                       } else {
-                               ae_tag = ARCHIVE_ENTRY_ACL_USER;
-                               ae_name = archive_read_disk_uname(&a->archive,
-                                   (uid_t)(richace->e_id));
-                       }
-               }
-               for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
-                       if ((richace->e_flags &
-                           acl_nfs4_flag_map[i].p_perm) != 0)
-                               ae_perm |= acl_nfs4_flag_map[i].a_perm;
-               }
-               for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
-                       if ((richace->e_mask &
-                           acl_nfs4_perm_map[i].p_perm) != 0)
-                               ae_perm |=
-                                   acl_nfs4_perm_map[i].a_perm;
-               }
-
-               archive_entry_acl_add_entry(entry, entry_acl_type,
-                   ae_perm, ae_tag, ae_id, ae_name);
-       }
-       return (ARCHIVE_OK);
-}
-#endif /* ARCHIVE_ACL_LIBRICHACL */
-
-int
-archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
-    struct archive_entry *entry, int *fd)
-{
-       const char      *accpath;
-       int             r;
-#if ARCHIVE_ACL_LIBACL
-       acl_t           acl;
-#endif
-#if ARCHIVE_ACL_LIBRICHACL
-       struct richacl *richacl;
-       mode_t          mode;
-#endif
-
-       accpath = NULL;
-       r = ARCHIVE_OK;
-
-       /* For default ACLs we need reachable accpath */
-       if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) {
-               accpath = archive_read_disk_entry_setup_path(a, entry, fd);
-               if (accpath == NULL)
-                       return (ARCHIVE_WARN);
-       }
-
-       archive_entry_acl_clear(entry);
-
-#if ARCHIVE_ACL_LIBACL
-       acl = NULL;
-#endif
-#if ARCHIVE_ACL_LIBRICHACL
-       richacl = NULL;
-#endif
-
-#if ARCHIVE_ACL_LIBRICHACL
-       /* Try NFSv4 ACL first. */
-       if (*fd >= 0)
-               richacl = richacl_get_fd(*fd);
-       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 */
-               richacl = NULL;
-       else
-               richacl = richacl_get_file(accpath);
-
-       /* Ignore "trivial" ACLs that just mirror the file mode. */
-       if (richacl != NULL) {
-               mode = archive_entry_mode(entry);
-               if (richacl_equiv_mode(richacl, &mode) == 0) {
-                       richacl_free(richacl);
-                       richacl = NULL;
-                       return (ARCHIVE_OK);
-               }
-       }
-
-       if (richacl != NULL) {
-               r = translate_richacl(a, entry, richacl);
-               richacl_free(richacl);
-               richacl = NULL;
-
-               if (r != ARCHIVE_OK) {
-                       archive_set_error(&a->archive, errno,
-                       "Couldn't translate NFSv4 ACLs");
-               }
-
-               return (r);
-       }
-#endif /* ARCHIVE_ACL_LIBRICHACL */
-
-#if ARCHIVE_ACL_LIBACL
-       /* Retrieve access ACL from file. */
-       if (*fd >= 0)
-               acl = acl_get_fd(*fd);
-       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;
-       else
-               acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
-
-       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))) {
-               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 /* ARCHIVE_ACL_LIBACL */
-       return (r);
-}
diff --git a/libarchive/archive_write_disk_acl_darwin.c b/libarchive/archive_write_disk_acl_darwin.c
deleted file mode 100644 (file)
index 4ffdd66..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/*-
- * 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
- *    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"
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#if HAVE_MEMBERSHIP_H
-#include <membership.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)
-{
-       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;
-       uuid_t           ae_uuid;
-       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 (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
-               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) {
-               /*
-                * 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;
-
-               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_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;
-               }
-
-               switch (ae_tag) {
-               case ARCHIVE_ENTRY_ACL_USER:
-                       ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
-                       if (mbr_uid_to_uuid(ae_uid, ae_uuid) != 0)
-                               continue;
-                       if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
-                               continue;
-                       break;
-               case ARCHIVE_ENTRY_ACL_GROUP:
-                       ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
-                       if (mbr_gid_to_uuid(ae_gid, ae_uuid) != 0)
-                               continue;
-                       if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
-                               continue;
-                       break;
-               default:
-                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
-                           "Unsupported ACL tag");
-                       ret = ARCHIVE_FAILED;
-                       goto exit_free;
-               }
-
-               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;
-               }
-
-               for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
-                       if (ae_permset & acl_nfs4_perm_map[i].a_perm) {
-                               if (acl_add_perm(acl_permset,
-                                   acl_nfs4_perm_map[i].p_perm) != 0) {
-                                       archive_set_error(a, errno,
-                                           "Failed to add ACL permission");
-                                       ret = ARCHIVE_FAILED;
-                                       goto exit_free;
-                               }
-                       }
-               }
-
-               /*
-                * 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;
-                               }
-                       }
-               }
-       }
-
-       if (fd >= 0) {
-               if (acl_set_fd_np(fd, acl, ACL_TYPE_EXTENDED) == 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;
-                       }
-               }
-       } else if (acl_set_link_np(name, ACL_TYPE_EXTENDED, acl) != 0) {
-               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_NFS4) != 0) {
-               ret = set_acl(a, fd, name, abstract_acl,
-                   ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
-       }
-       return (ret);
-}
diff --git a/libarchive/archive_write_disk_acl_freebsd.c b/libarchive/archive_write_disk_acl_freebsd.c
deleted file mode 100644 (file)
index 29e64ad..0000000
+++ /dev/null
@@ -1,321 +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$");
-
-#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/libarchive/archive_write_disk_acl_sunos.c b/libarchive/archive_write_disk_acl_sunos.c
deleted file mode 100644 (file)
index ebc0b09..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*-
- * 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
- *    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"
-
-#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)
-{
-       aclent_t         *aclent;
-#if ARCHIVE_ACL_SUNOS_NFS4
-       ace_t            *ace;
-#endif
-       int              cmd, e, r;
-       void             *aclp;
-       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_POSIX1E:
-               cmd = SETACL;
-               aclp = malloc(entries * sizeof(aclent_t));
-               break;
-#if ARCHIVE_ACL_SUNOS_NFS4
-       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, "Unsupported ACL type");
-               return (ARCHIVE_FAILED);
-       }
-
-       if (aclp == NULL) {
-               archive_set_error(a, errno,
-                   "Can't allocate memory for acl buffer");
-               return (ARCHIVE_FAILED);
-       }
-
-       e = 0;
-
-       while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
-                  &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
-               aclent = NULL;
-#if ARCHIVE_ACL_SUNOS_NFS4
-               ace = NULL;
-#endif
-               if (cmd == SETACL) {
-                       aclent = &((aclent_t *)aclp)[e];
-                       aclent->a_id = -1;
-                       aclent->a_type = 0;
-                       aclent->a_perm = 0;
-               }
-#if ARCHIVE_ACL_SUNOS_NFS4
-               else {  /* cmd == ACE_SETACL */
-                       ace = &((ace_t *)aclp)[e];
-                       ace->a_who = -1;
-                       ace->a_access_mask = 0;
-                       ace->a_flags = 0;
-               }
-#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
-
-               switch (ae_tag) {
-               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 ARCHIVE_ACL_SUNOS_NFS4
-                       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 ARCHIVE_ACL_SUNOS_NFS4
-                       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 ARCHIVE_ACL_SUNOS_NFS4
-                       else {
-                               ace->a_flags |= ACE_OWNER;
-                       }
-#endif
-                       break;
-               case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
-                       if (aclent != NULL)
-                               aclent->a_type |= GROUP_OBJ;
-#if ARCHIVE_ACL_SUNOS_NFS4
-                       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 ARCHIVE_ACL_SUNOS_NFS4
-               case ARCHIVE_ENTRY_ACL_EVERYONE:
-                       if (ace != NULL)
-                               ace->a_flags |= ACE_EVERYONE;
-                       break;
-#endif
-               default:
-                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
-                           "Unsupported ACL tag");
-                       ret = ARCHIVE_FAILED;
-                       goto exit_free;
-               }
-
-               r = 0;
-               switch (ae_type) {
-#if ARCHIVE_ACL_SUNOS_NFS4
-               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;
-               default:
-                       archive_set_error(a, ARCHIVE_ERRNO_MISC,
-                           "Unsupported ACL entry type");
-                       ret = ARCHIVE_FAILED;
-                       goto exit_free;
-               }
-
-               if (r != 0) {
-                       errno = EINVAL;
-                       archive_set_error(a, errno,
-                           "Failed to set ACL entry type");
-                       ret = ARCHIVE_FAILED;
-                       goto exit_free;
-               }
-
-#if ARCHIVE_ACL_SUNOS_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_SUNOS_NFS4
-               }
-#endif
-               for (i = 0; i < perm_map_size; ++i) {
-                       if (ae_permset & perm_map[i].a_perm) {
-#if ARCHIVE_ACL_SUNOS_NFS4
-                               if (ae_requested_type ==
-                                   ARCHIVE_ENTRY_ACL_TYPE_NFS4)
-                                       ace->a_access_mask |=
-                                           perm_map[i].p_perm;
-                               else
-#endif
-                                       aclent->a_perm |= perm_map[i].p_perm;
-                       }
-               }
-
-#if ARCHIVE_ACL_SUNOS_NFS4
-               if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
-                       for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
-                               if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
-                                       ace->a_flags |=
-                                           acl_nfs4_flag_map[i].p_perm;
-                               }
-                       }
-               }
-#endif
-       e++;
-       }
-
-       /* Try restoring the ACL through 'fd' if we can. */
-       if (fd >= 0) {
-               if (facl(fd, cmd, entries, aclp) == 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;
-                       }
-               }
-       } else if (acl(name, cmd, entries, aclp) != 0) {
-               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:
-       free(aclp);
-       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) {
-               /* Solaris writes POSIX.1e access and default ACLs together */
-               ret = set_acl(a, fd, name, abstract_acl,
-                   ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
-
-               /* Simultaneous POSIX.1e and NFSv4 is not supported */
-               return (ret);
-       }
-#if ARCHIVE_ACL_SUNOS_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);
-}