From 782ceec6db44f98526c6423f7e08dc12851ea20c Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Tue, 28 Mar 2017 09:58:54 +0000 Subject: [PATCH] Update vendor/libarchive to git 13b0ed2ba504389c363cd302041fe10afa1837ad Vendor changes (FreeBSD-related): - constify variables in several places - unify platform ACL code in a single source file - fix unused variable if compiling on FreeBSD without NFSv4 ACL support --- libarchive/CMakeLists.txt | 20 +- libarchive/archive_acl_maps.h | 50 --- libarchive/archive_acl_maps_darwin.c | 75 ---- libarchive/archive_acl_maps_freebsd.c | 86 ----- libarchive/archive_acl_maps_linux.c | 89 ----- libarchive/archive_acl_maps_sunos.c | 89 ----- ...acl_darwin.c => archive_disk_acl_darwin.c} | 239 +++++++++++- ...l_freebsd.c => archive_disk_acl_freebsd.c} | 338 +++++++++++++++- ...k_acl_linux.c => archive_disk_acl_linux.c} | 364 +++++++++++++++++- ...k_acl_sunos.c => archive_disk_acl_sunos.c} | 350 ++++++++++++++++- libarchive/archive_entry.c | 8 +- libarchive/archive_getdate.c | 2 +- libarchive/archive_pack_dev.c | 2 +- libarchive/archive_read_disk_acl_linux.c | 352 ----------------- libarchive/archive_read_support_format_cab.c | 2 +- libarchive/archive_read_support_format_lha.c | 2 +- .../archive_read_support_format_mtree.c | 22 +- libarchive/archive_read_support_format_zip.c | 2 +- libarchive/archive_string_sprintf.c | 2 +- libarchive/archive_util.c | 6 +- libarchive/archive_write_add_filter.c | 2 +- libarchive/archive_write_add_filter_by_name.c | 2 +- libarchive/archive_write_add_filter_lz4.c | 2 +- libarchive/archive_write_add_filter_program.c | 2 +- libarchive/archive_write_disk_acl_darwin.c | 234 ----------- libarchive/archive_write_disk_acl_freebsd.c | 321 --------------- libarchive/archive_write_disk_acl_sunos.c | 329 ---------------- libarchive/archive_write_set_format.c | 2 +- libarchive/archive_write_set_format_by_name.c | 2 +- .../archive_write_set_format_filter_by_ext.c | 2 +- libarchive/archive_write_set_format_warc.c | 2 +- 31 files changed, 1298 insertions(+), 1702 deletions(-) delete mode 100644 libarchive/archive_acl_maps.h delete mode 100644 libarchive/archive_acl_maps_darwin.c delete mode 100644 libarchive/archive_acl_maps_freebsd.c delete mode 100644 libarchive/archive_acl_maps_linux.c delete mode 100644 libarchive/archive_acl_maps_sunos.c rename libarchive/{archive_read_disk_acl_darwin.c => archive_disk_acl_darwin.c} (57%) rename libarchive/{archive_read_disk_acl_freebsd.c => archive_disk_acl_freebsd.c} (51%) rename libarchive/{archive_write_disk_acl_linux.c => archive_disk_acl_linux.c} (51%) rename libarchive/{archive_read_disk_acl_sunos.c => archive_disk_acl_sunos.c} (57%) delete mode 100644 libarchive/archive_read_disk_acl_linux.c delete mode 100644 libarchive/archive_write_disk_acl_darwin.c delete mode 100644 libarchive/archive_write_disk_acl_freebsd.c delete mode 100644 libarchive/archive_write_disk_acl_sunos.c diff --git a/libarchive/CMakeLists.txt b/libarchive/CMakeLists.txt index 44ffd453f348..5e958da1c538 100644 --- a/libarchive/CMakeLists.txt +++ b/libarchive/CMakeLists.txt @@ -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 index e3f4408286a1..000000000000 --- a/libarchive/archive_acl_maps.h +++ /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 index af0f4c3eef9f..000000000000 --- a/libarchive/archive_acl_maps_darwin.c +++ /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 -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#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 index 17b1e953a396..000000000000 --- a/libarchive/archive_acl_maps_freebsd.c +++ /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 -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#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 index 04f630eb8426..000000000000 --- a/libarchive/archive_acl_maps_linux.c +++ /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 -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#endif -#ifdef HAVE_SYS_RICHACL_H -#include -#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 index bdc869d175f1..000000000000 --- a/libarchive/archive_acl_maps_sunos.c +++ /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 -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#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 */ diff --git a/libarchive/archive_read_disk_acl_darwin.c b/libarchive/archive_disk_acl_darwin.c similarity index 57% rename from libarchive/archive_read_disk_acl_darwin.c rename to libarchive/archive_disk_acl_darwin.c index 8de33b91473f..0d3bc4e9861f 100644 --- a/libarchive/archive_read_disk_acl_darwin.c +++ b/libarchive/archive_disk_acl_darwin.c @@ -45,15 +45,49 @@ #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); +} diff --git a/libarchive/archive_read_disk_acl_freebsd.c b/libarchive/archive_disk_acl_freebsd.c similarity index 51% rename from libarchive/archive_read_disk_acl_freebsd.c rename to libarchive/archive_disk_acl_freebsd.c index c09c3e1c2b51..eff9c22e94ab 100644 --- a/libarchive/archive_read_disk_acl_freebsd.c +++ b/libarchive/archive_disk_acl_freebsd.c @@ -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 @@ -44,11 +44,60 @@ #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) @@ -56,11 +105,11 @@ translate_acl(struct archive_read_disk *a, #if ARCHIVE_ACL_FREEBSD_NFS4 int brand; acl_flagset_t acl_flagset; + acl_entry_type_t acl_type; #endif acl_tag_t acl_tag; acl_entry_t acl_entry; acl_permset_t acl_permset; - acl_entry_type_t acl_type; int i, entry_acl_type, perm_map_size; const acl_perm_map_t *perm_map; int r, s, ae_id, ae_tag, ae_perm; @@ -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); +} diff --git a/libarchive/archive_write_disk_acl_linux.c b/libarchive/archive_disk_acl_linux.c similarity index 51% rename from libarchive/archive_write_disk_acl_linux.c rename to libarchive/archive_disk_acl_linux.c index 2239df6c10f7..6e9288d221f9 100644 --- a/libarchive/archive_write_disk_acl_linux.c +++ b/libarchive/archive_disk_acl_linux.c @@ -1,13 +1,14 @@ /*- - * Copyright (c) 2003-2010 Tim Kientzle + * Copyright (c) 2003-2009 Tim Kientzle + * Copyright (c) 2010-2012 Michihiro NAKAJIMA + * 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. @@ -38,14 +39,254 @@ #ifdef HAVE_SYS_ACL_H #include #endif -#if HAVE_SYS_RICHACL_H +#ifdef HAVE_SYS_RICHACL_H #include #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 +589,117 @@ set_acl(struct archive *a, int fd, const char *name, } #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) diff --git a/libarchive/archive_read_disk_acl_sunos.c b/libarchive/archive_disk_acl_sunos.c similarity index 57% rename from libarchive/archive_read_disk_acl_sunos.c rename to libarchive/archive_disk_acl_sunos.c index 066c30371b56..7d806b016f90 100644 --- a/libarchive/archive_read_disk_acl_sunos.c +++ b/libarchive/archive_disk_acl_sunos.c @@ -35,20 +35,70 @@ #include #endif #ifdef HAVE_SYS_ACL_H +#define _ACL_PRIVATE /* For debugging */ #include #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_entry.c b/libarchive/archive_entry.c index 05c5563c70fe..30fb4566eb9a 100644 --- a/libarchive/archive_entry.c +++ b/libarchive/archive_entry.c @@ -1638,7 +1638,7 @@ _archive_entry_acl_text_l(struct archive_entry *entry, int flags, * SUCH DAMAGE. */ -static struct flag { +static const struct flag { const char *name; const wchar_t *wname; unsigned long set; @@ -1843,7 +1843,7 @@ ae_fflagstostr(unsigned long bitset, unsigned long bitclear) char *string, *dp; const char *sp; unsigned long bits; - struct flag *flag; + const struct flag *flag; size_t length; bits = bitset | bitclear; @@ -1895,7 +1895,7 @@ static const char * ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp) { const char *start, *end; - struct flag *flag; + const struct flag *flag; unsigned long set, clear; const char *failed; @@ -1963,7 +1963,7 @@ static const wchar_t * ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp) { const wchar_t *start, *end; - struct flag *flag; + const struct flag *flag; unsigned long set, clear; const wchar_t *failed; diff --git a/libarchive/archive_getdate.c b/libarchive/archive_getdate.c index beb0cba2ed3b..fe43ae820aee 100644 --- a/libarchive/archive_getdate.c +++ b/libarchive/archive_getdate.c @@ -691,7 +691,7 @@ Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes, time_t Seconds, time_t Timezone, enum DSTMODE DSTmode) { - static int DaysInMonth[12] = { + int DaysInMonth[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; time_t Julian; diff --git a/libarchive/archive_pack_dev.c b/libarchive/archive_pack_dev.c index 6b7b4726d6ea..098881b678cd 100644 --- a/libarchive/archive_pack_dev.c +++ b/libarchive/archive_pack_dev.c @@ -280,7 +280,7 @@ pack_bsdos(int n, unsigned long numbers[], const char **error) /* list of formats and pack functions */ /* this list must be sorted lexically */ -static struct format { +static const struct format { const char *name; pack_t *pack; } formats[] = { diff --git a/libarchive/archive_read_disk_acl_linux.c b/libarchive/archive_read_disk_acl_linux.c deleted file mode 100644 index 033e68a1a18c..000000000000 --- a/libarchive/archive_read_disk_acl_linux.c +++ /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 -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#if HAVE_ACL_LIBACL_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#include -#endif -#if HAVE_SYS_RICHACL_H -#include -#endif - -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_disk_private.h" -#include "archive_acl_maps.h" - -#if HAVE_LIBACL -#include -#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_read_support_format_cab.c b/libarchive/archive_read_support_format_cab.c index e2f8c6b70aeb..2cf0d453abdc 100644 --- a/libarchive/archive_read_support_format_cab.c +++ b/libarchive/archive_read_support_format_cab.c @@ -187,7 +187,7 @@ struct lzx_stream { #define CFDATA_cbData 4 #define CFDATA_cbUncomp 6 -static const char *compression_name[] = { +static const char * const compression_name[] = { "NONE", "MSZIP", "Quantum", diff --git a/libarchive/archive_read_support_format_lha.c b/libarchive/archive_read_support_format_lha.c index d77a7c2e4766..b8ef4ae10ece 100644 --- a/libarchive/archive_read_support_format_lha.c +++ b/libarchive/archive_read_support_format_lha.c @@ -2477,7 +2477,7 @@ lzh_huffman_free(struct huffman *hf) free(hf->tree); } -static char bitlen_tbl[0x400] = { +static const char bitlen_tbl[0x400] = { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c index 00d3250707a6..1590187febe5 100644 --- a/libarchive/archive_read_support_format_mtree.c +++ b/libarchive/archive_read_support_format_mtree.c @@ -399,41 +399,41 @@ bid_keycmp(const char *p, const char *key, ssize_t len) static int bid_keyword(const char *p, ssize_t len) { - static const char *keys_c[] = { + static const char * const keys_c[] = { "content", "contents", "cksum", NULL }; - static const char *keys_df[] = { + static const char * const keys_df[] = { "device", "flags", NULL }; - static const char *keys_g[] = { + static const char * const keys_g[] = { "gid", "gname", NULL }; - static const char *keys_il[] = { + static const char * const keys_il[] = { "ignore", "inode", "link", NULL }; - static const char *keys_m[] = { + static const char * const keys_m[] = { "md5", "md5digest", "mode", NULL }; - static const char *keys_no[] = { + static const char * const keys_no[] = { "nlink", "nochange", "optional", NULL }; - static const char *keys_r[] = { + static const char * const keys_r[] = { "resdevice", "rmd160", "rmd160digest", NULL }; - static const char *keys_s[] = { + static const char * const keys_s[] = { "sha1", "sha1digest", "sha256", "sha256digest", "sha384", "sha384digest", "sha512", "sha512digest", "size", NULL }; - static const char *keys_t[] = { + static const char * const keys_t[] = { "tags", "time", "type", NULL }; - static const char *keys_u[] = { + static const char * const keys_u[] = { "uid", "uname", NULL }; - const char **keys; + const char * const *keys; int i; switch (*p) { diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c index e62f99c8b9e8..4c4f6fad4798 100644 --- a/libarchive/archive_read_support_format_zip.c +++ b/libarchive/archive_read_support_format_zip.c @@ -347,7 +347,7 @@ fake_crc32(unsigned long crc, const void *buff, size_t len) return 0; } -static struct { +static const struct { int id; const char * name; } compression_methods[] = { diff --git a/libarchive/archive_string_sprintf.c b/libarchive/archive_string_sprintf.c index 964ea2bea1f3..969a5603a49e 100644 --- a/libarchive/archive_string_sprintf.c +++ b/libarchive/archive_string_sprintf.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03- static void append_uint(struct archive_string *as, uintmax_t d, unsigned base) { - static const char *digits = "0123456789abcdef"; + static const char digits[] = "0123456789abcdef"; if (d >= base) append_uint(as, d/base, base); archive_strappend_char(as, digits[d % base]); diff --git a/libarchive/archive_util.c b/libarchive/archive_util.c index a751868f4542..bac9ba1cab1a 100644 --- a/libarchive/archive_util.c +++ b/libarchive/archive_util.c @@ -193,7 +193,7 @@ archive_copy_error(struct archive *dest, struct archive *src) void __archive_errx(int retvalue, const char *msg) { - static const char *msg1 = "Fatal Internal Error in libarchive: "; + static const char msg1[] = "Fatal Internal Error in libarchive: "; size_t s; s = write(2, msg1, strlen(msg1)); @@ -221,8 +221,8 @@ __archive_errx(int retvalue, const char *msg) int __archive_mktemp(const char *tmpdir) { - static const wchar_t *prefix = L"libarchive_"; - static const wchar_t *suffix = L"XXXXXXXXXX"; + static const wchar_t prefix[] = L"libarchive_"; + static const wchar_t suffix[] = L"XXXXXXXXXX"; static const wchar_t num[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F', diff --git a/libarchive/archive_write_add_filter.c b/libarchive/archive_write_add_filter.c index ad5dc832fdae..08f518adec4b 100644 --- a/libarchive/archive_write_add_filter.c +++ b/libarchive/archive_write_add_filter.c @@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$"); #include "archive_private.h" /* A table that maps filter codes to functions. */ -static +static const struct { int code; int (*setter)(struct archive *); } codes[] = { { ARCHIVE_FILTER_NONE, archive_write_add_filter_none }, diff --git a/libarchive/archive_write_add_filter_by_name.c b/libarchive/archive_write_add_filter_by_name.c index eac4011cb2ee..85a8d4753415 100644 --- a/libarchive/archive_write_add_filter_by_name.c +++ b/libarchive/archive_write_add_filter_by_name.c @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); #include "archive_private.h" /* A table that maps names to functions. */ -static +static const struct { const char *name; int (*setter)(struct archive *); } names[] = { { "b64encode", archive_write_add_filter_b64encode }, diff --git a/libarchive/archive_write_add_filter_lz4.c b/libarchive/archive_write_add_filter_lz4.c index e6551859c060..15fd494a4197 100644 --- a/libarchive/archive_write_add_filter_lz4.c +++ b/libarchive/archive_write_add_filter_lz4.c @@ -225,7 +225,7 @@ archive_filter_lz4_open(struct archive_write_filter *f) struct private_data *data = (struct private_data *)f->data; int ret; size_t required_size; - static size_t bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024, + static size_t const bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024, 4 * 1024 * 1024 }; size_t pre_block_size; diff --git a/libarchive/archive_write_add_filter_program.c b/libarchive/archive_write_add_filter_program.c index 55b5e8ecdf82..660f693f29d0 100644 --- a/libarchive/archive_write_add_filter_program.c +++ b/libarchive/archive_write_add_filter_program.c @@ -92,7 +92,7 @@ archive_write_add_filter_program(struct archive *_a, const char *cmd) { struct archive_write_filter *f = __archive_write_allocate_filter(_a); struct private_data *data; - static const char *prefix = "Program: "; + static const char prefix[] = "Program: "; archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, "archive_write_add_filter_program"); diff --git a/libarchive/archive_write_disk_acl_darwin.c b/libarchive/archive_write_disk_acl_darwin.c deleted file mode 100644 index 4ffdd66b4333..000000000000 --- a/libarchive/archive_write_disk_acl_darwin.c +++ /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 -#endif -#if HAVE_MEMBERSHIP_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#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 index 29e64adf0f33..000000000000 --- a/libarchive/archive_write_disk_acl_freebsd.c +++ /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 -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#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 index ebc0b095db93..000000000000 --- a/libarchive/archive_write_disk_acl_sunos.c +++ /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 -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#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); -} diff --git a/libarchive/archive_write_set_format.c b/libarchive/archive_write_set_format.c index 744302d06775..0f706231add1 100644 --- a/libarchive/archive_write_set_format.c +++ b/libarchive/archive_write_set_format.c @@ -38,7 +38,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format.c 201168 2009-1 #include "archive_private.h" /* A table that maps format codes to functions. */ -static +static const struct { int code; int (*setter)(struct archive *); } codes[] = { { ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip }, diff --git a/libarchive/archive_write_set_format_by_name.c b/libarchive/archive_write_set_format_by_name.c index a2ce7c6cde4e..86e8621ef7b5 100644 --- a/libarchive/archive_write_set_format_by_name.c +++ b/libarchive/archive_write_set_format_by_name.c @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 20116 #include "archive_private.h" /* A table that maps names to functions. */ -static +static const struct { const char *name; int (*setter)(struct archive *); } names[] = { { "7zip", archive_write_set_format_7zip }, diff --git a/libarchive/archive_write_set_format_filter_by_ext.c b/libarchive/archive_write_set_format_filter_by_ext.c index 3f3aeddef090..db69203e96fb 100644 --- a/libarchive/archive_write_set_format_filter_by_ext.c +++ b/libarchive/archive_write_set_format_filter_by_ext.c @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); #include "archive_private.h" /* A table that maps names to functions. */ -static +static const struct { const char *name; int (*format)(struct archive *); int (*filter)(struct archive *); } names[] = { { ".7z", archive_write_set_format_7zip, archive_write_add_filter_none}, diff --git a/libarchive/archive_write_set_format_warc.c b/libarchive/archive_write_set_format_warc.c index 8b6daf942b8e..edad072cf77d 100644 --- a/libarchive/archive_write_set_format_warc.c +++ b/libarchive/archive_write_set_format_warc.c @@ -354,7 +354,7 @@ static ssize_t _popul_ehdr(struct archive_string *tgt, size_t tsz, warc_essential_hdr_t hdr) { static const char _ver[] = "WARC/1.0\r\n"; - static const char *_typ[LAST_WT] = { + static const char * const _typ[LAST_WT] = { NULL, "warcinfo", "metadata", "resource", NULL }; char std_uuid[48U];