Update vendor/libarchive to git 5881c9021a85668bd945593f5ba43a0d22c53d71
Vendor changes (FreeBSD-related): Break ACL read/write code into platform-specific source files Vendor bugfixes (FreeBSD-related): PR 867 (bsdcpio): show numeric uid/gid when names are not found PR 870 (seekable zip): accept files with valid ZIP64 EOCD headers PR 880 (pax): Fix handling of "size" pax header keyword PR 887 (crypto): Discard 3072 bytes instead of 1024 of first keystream OSS-Fuzz issue 806 (mtree): rework mtree_atol10 integer parser Unbreak static dependency on libbz2
This commit is contained in:
parent
651c72fcea
commit
66c81a3794
255
CMakeLists.txt
255
CMakeLists.txt
@ -602,6 +602,7 @@ LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
|
||||
LA_CHECK_INCLUDE_FILE("sys/statfs.h" HAVE_SYS_STATFS_H)
|
||||
@ -619,6 +620,9 @@ LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H)
|
||||
LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H)
|
||||
IF(ENABLE_CNG)
|
||||
LA_CHECK_INCLUDE_FILE("Bcrypt.h" HAVE_BCRYPT_H)
|
||||
IF(HAVE_BCRYPT_H)
|
||||
LIST(APPEND ADDITIONAL_LIBS "Bcrypt")
|
||||
ENDIF(HAVE_BCRYPT_H)
|
||||
ELSE(ENABLE_CNG)
|
||||
UNSET(HAVE_BCRYPT_H CACHE)
|
||||
ENDIF(ENABLE_CNG)
|
||||
@ -1593,83 +1597,212 @@ ENDIF(ENABLE_XATTR)
|
||||
# which makes the following checks rather more complex than I would like.
|
||||
#
|
||||
IF(ENABLE_ACL)
|
||||
# Solaris and derivates ACLs
|
||||
CHECK_FUNCTION_EXISTS(acl HAVE_ACL)
|
||||
CHECK_FUNCTION_EXISTS(facl HAVE_FACL)
|
||||
|
||||
# Libacl
|
||||
CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_LIBACL)
|
||||
IF(HAVE_LIBACL)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "acl")
|
||||
FIND_LIBRARY(ACL_LIBRARY NAMES acl)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${ACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBACL)
|
||||
#
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd HAVE_ACL_SET_FD)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd_np HAVE_ACL_SET_FD_NP)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_set_file HAVE_ACL_SET_FILE)
|
||||
CHECK_TYPE_EXISTS(acl_permset_t "${INCLUDES}" HAVE_ACL_PERMSET_T)
|
||||
|
||||
# The "acl_get_perm()" function was omitted from the POSIX draft.
|
||||
# (It's a pretty obvious oversight; otherwise, there's no way to
|
||||
# test for specific permissions in a permset.) Linux uses the obvious
|
||||
# name, FreeBSD adds _np to mark it as "non-Posix extension."
|
||||
# Test for both as a double-check that we really have POSIX-style ACL support.
|
||||
CHECK_FUNCTION_EXISTS(acl_get_fd_np HAVE_ACL_GET_FD_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_perm HAVE_ACL_GET_PERM)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_link HAVE_ACL_GET_LINK)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
|
||||
CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "${INCLUDES}" HAVE_DECL_ACL_TYPE_NFS4)
|
||||
CHECK_TYPE_EXISTS(acl_t "sys/types.h;sys/acl.h" HAVE_ACL_T)
|
||||
CHECK_TYPE_EXISTS(acl_entry_t "sys/types.h;sys/acl.h" HAVE_ACL_ENTRY_T)
|
||||
CHECK_TYPE_EXISTS(acl_permset_t "sys/types.h;sys/acl.h" HAVE_ACL_PERMSET_T)
|
||||
CHECK_TYPE_EXISTS(acl_tag_t "sys/types.h;sys/acl.h" HAVE_ACL_TAG_T)
|
||||
|
||||
# MacOS has an acl.h that isn't POSIX. It can be detected by
|
||||
# checking for ACL_USER
|
||||
CHECK_SYMBOL_EXISTS(ACL_USER "${INCLUDES}" HAVE_DECL_ACL_USER)
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
|
||||
IF(HAVE_ACL AND HAVE_FACL)
|
||||
CHECK_TYPE_EXISTS(aclent_t "sys/acl.h" HAVE_ACLENT_T)
|
||||
IF(HAVE_ACLENT_T)
|
||||
CHECK_SYMBOL_EXISTS(GETACL "sys/acl.h" HAVE_DECL_GETACL)
|
||||
CHECK_SYMBOL_EXISTS(GETACLCNT "sys/acl.h" HAVE_DECL_GETACLCNT)
|
||||
CHECK_SYMBOL_EXISTS(SETACL "sys/acl.h" HAVE_DECL_SETACL)
|
||||
IF(HAVE_DECL_GETACL AND
|
||||
HAVE_DECL_GETACLCNT AND
|
||||
HAVE_DECL_SETACL)
|
||||
SET(ARCHIVE_ACL_SUNOS TRUE)
|
||||
ENDIF()
|
||||
CHECK_TYPE_EXISTS(ace_t "sys/acl.h" HAVE_ACE_T)
|
||||
IF(HAVE_ACE_T)
|
||||
CHECK_SYMBOL_EXISTS(ACE_GETACL "sys/acl.h" HAVE_DECL_ACE_GETACL)
|
||||
CHECK_SYMBOL_EXISTS(ACE_GETACLCNT "sys/acl.h" HAVE_DECL_ACE_GETACLCNT)
|
||||
CHECK_SYMBOL_EXISTS(ACE_SETACL "sys/acl.h" HAVE_DECL_ACE_SETACL)
|
||||
IF(HAVE_DECL_ACE_GETACL AND
|
||||
HAVE_DECL_ACE_GETACLCNT AND
|
||||
HAVE_DECL_ACE_SETACL)
|
||||
SET(ARCHIVE_ACL_SUNOS_NFS4 TRUE)
|
||||
ENDIF()
|
||||
ENDIF(HAVE_ACE_T)
|
||||
ENDIF(HAVE_ACLENT_T)
|
||||
ENDIF(HAVE_ACL AND HAVE_FACL)
|
||||
|
||||
IF(HAVE_ACL_T AND HAVE_ACL_ENTRY_T AND HAVE_ACL_PERMSET_T AND HAVE_ACL_TAG_T)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_add_perm HAVE_ACL_ADD_PERM)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_clear_perms HAVE_ACL_CLEAR_PERMS)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_delete_def_file HAVE_ACL_DELETE_DEF_FILE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_free HAVE_ACL_FREE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_get_entry HAVE_ACL_GET_ENTRY)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_get_fd HAVE_ACL_GET_FD)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_get_file HAVE_ACL_GET_FILE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_get_permset HAVE_ACL_GET_PERMSET)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_get_qualifier HAVE_ACL_GET_QUALIFIER)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_get_tag_type HAVE_ACL_GET_TAG_TYPE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd HAVE_ACL_SET_FD)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_set_file HAVE_ACL_SET_FILE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_set_qualifier HAVE_ACL_SET_QUALIFIER)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_set_tag_type HAVE_ACL_SET_TAG_TYPE)
|
||||
IF(HAVE_ACL_ADD_PERM AND
|
||||
HAVE_ACL_CLEAR_PERMS AND
|
||||
HAVE_ACL_CREATE_ENTRY AND
|
||||
HAVE_ACL_DELETE_DEF_FILE AND
|
||||
HAVE_ACL_FREE AND
|
||||
HAVE_ACL_GET_ENTRY AND
|
||||
HAVE_ACL_GET_FD AND
|
||||
HAVE_ACL_GET_FILE AND
|
||||
HAVE_ACL_GET_PERMSET AND
|
||||
HAVE_ACL_GET_QUALIFIER AND
|
||||
HAVE_ACL_GET_TAG_TYPE AND
|
||||
HAVE_ACL_INIT AND
|
||||
HAVE_ACL_SET_FD AND
|
||||
HAVE_ACL_SET_FILE AND
|
||||
HAVE_ACL_SET_QUALIFIER AND
|
||||
HAVE_ACL_SET_TAG_TYPE)
|
||||
SET(HAVE_POSIX_ACL_FUNCS 1)
|
||||
ENDIF()
|
||||
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(acl_get_perm HAVE_ACL_GET_PERM)
|
||||
|
||||
IF(HAVE_POSIX_ACL_FUNCS AND HAVE_ACL_LIBACL_H AND HAVE_LIBACL AND
|
||||
HAVE_ACL_GET_PERM)
|
||||
SET(ARCHIVE_ACL_LIBACL TRUE)
|
||||
ELSE()
|
||||
CHECK_FUNCTION_EXISTS(acl_add_flag_np HAVE_ACL_ADD_FLAG_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_clear_flags_np HAVE_ACL_CLEAR_FLAGS_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_brand_np HAVE_ACL_GET_BRAND_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_entry_type_np HAVE_ACL_GET_ENTRY_TYPE_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_flag_np HAVE_ACL_GET_FLAG_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_flagset_np HAVE_ACL_GET_FLAGSET_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_fd_np HAVE_ACL_GET_FD_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_set_entry_type_np HAVE_ACL_SET_ENTRY_TYPE_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_set_fd_np HAVE_ACL_SET_FD_NP)
|
||||
CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP)
|
||||
CHECK_FUNCTION_EXISTS(mbr_gid_to_uuid HAVE_MBR_GID_TO_UUID)
|
||||
CHECK_FUNCTION_EXISTS(mbr_uid_to_uuid HAVE_MBR_UID_TO_UUID)
|
||||
CHECK_FUNCTION_EXISTS(mbr_uuid_to_id HAVE_MBR_UUID_TO_ID)
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
|
||||
#include <sys/acl.h>
|
||||
int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_DECL_ACL_TYPE_EXTENDED)
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
|
||||
#include <sys/acl.h>
|
||||
int main(void) { return ACL_SYNCHRONIZE; }" HAVE_DECL_ACL_SYNCHRONIZE)
|
||||
CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "sys/acl.h" HAVE_DECL_ACL_TYPE_NFS4)
|
||||
CHECK_SYMBOL_EXISTS(ACL_USER "sys/acl.h" HAVE_DECL_ACL_USER)
|
||||
|
||||
IF(HAVE_POSIX_ACL_FUNCS AND
|
||||
HAVE_ACL_GET_FD_NP AND
|
||||
HAVE_ACL_GET_PERM_NP AND
|
||||
NOT HAVE_ACL_GET_PERM AND
|
||||
HAVE_ACL_SET_FD_NP)
|
||||
IF(HAVE_DECL_ACL_USER)
|
||||
SET(ARCHIVE_ACL_FREEBSD TRUE)
|
||||
IF(HAVE_DECL_ACL_TYPE_NFS4 AND
|
||||
HAVE_ACL_ADD_FLAG_NP AND
|
||||
HAVE_ACL_CLEAR_FLAGS_NP AND
|
||||
HAVE_ACL_GET_BRAND_NP AND
|
||||
HAVE_ACL_GET_ENTRY_TYPE_NP AND
|
||||
HAVE_ACL_GET_FLAGSET_NP AND
|
||||
HAVE_ACL_SET_ENTRY_TYPE_NP)
|
||||
SET(ARCHIVE_ACL_FREEBSD_NFS4 TRUE)
|
||||
ENDIF()
|
||||
ELSEIF(HAVE_DECL_ACL_TYPE_EXTENDED AND
|
||||
HAVE_MEMBERSHIP_H AND
|
||||
HAVE_ACL_ADD_FLAG_NP AND
|
||||
HAVE_ACL_CLEAR_FLAGS_NP AND
|
||||
HAVE_ACL_GET_FLAGSET_NP AND
|
||||
HAVE_ACL_GET_LINK_NP AND
|
||||
HAVE_ACL_SET_LINK_NP AND
|
||||
HAVE_MBR_UID_TO_UUID AND
|
||||
HAVE_MBR_GID_TO_UUID AND
|
||||
HAVE_MBR_UUID_TO_ID)
|
||||
SET(ARCHIVE_ACL_DARWIN TRUE)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF(HAVE_ACL_T AND HAVE_ACL_ENTRY_T AND HAVE_ACL_PERMSET_T AND
|
||||
HAVE_ACL_TAG_T)
|
||||
|
||||
# Richacl
|
||||
CHECK_LIBRARY_EXISTS(richacl "richacl_get_file" "" HAVE_LIBRICHACL)
|
||||
IF(HAVE_LIBRICHACL)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "richacl")
|
||||
FIND_LIBRARY(RICHACL_LIBRARY NAMES richacl)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${RICHACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBRICHACL)
|
||||
|
||||
CHECK_STRUCT_HAS_MEMBER("struct richace" e_type "sys/richacl.h"
|
||||
HAVE_STRUCT_RICHACE)
|
||||
CHECK_STRUCT_HAS_MEMBER("struct richacl" a_flags "sys/richacl.h"
|
||||
HAVE_STRUCT_RICHACL)
|
||||
|
||||
IF(HAVE_LIBRICHACL AND HAVE_STRUCT_RICHACL AND HAVE_STRUCT_RICHACE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(richacl_alloc HAVE_RICHACL_ALLOC)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(richacl_equiv_mode HAVE_RICHACL_EQUIV_MODE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(richacl_free HAVE_RICHACL_FREE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(richacl_get_fd HAVE_RICHACL_GET_FD)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(richacl_get_file HAVE_RICHACL_GET_FILE)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(richacl_set_fd HAVE_RICHACL_SET_FD)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(richacl_set_file HAVE_RICHACL_SET_FILE)
|
||||
IF(HAVE_RICHACL_ALLOC AND
|
||||
HAVE_RICHACL_EQUIV_MODE AND
|
||||
HAVE_RICHACL_FREE AND
|
||||
HAVE_RICHACL_GET_FD AND
|
||||
HAVE_RICHACL_GET_FILE AND
|
||||
HAVE_RICHACL_SET_FD AND
|
||||
HAVE_RICHACL_SET_FILE)
|
||||
SET(ARCHIVE_ACL_LIBRICHACL TRUE)
|
||||
ENDIF()
|
||||
ENDIF(HAVE_LIBRICHACL AND HAVE_STRUCT_RICHACL AND HAVE_STRUCT_RICHACE)
|
||||
|
||||
IF(ARCHIVE_ACL_DARWIN)
|
||||
MESSAGE(STATUS "ACL support: Darwin (limited NFSv4)")
|
||||
ELSEIF(ARCHIVE_ACL_FREEBSD_NFS4)
|
||||
MESSAGE(STATUS "ACL support: FreeBSD (POSIX.1e and NFSv4)")
|
||||
ELSEIF(ARCHIVE_ACL_FREEBSD)
|
||||
MESSAGE(STATUS "ACL support: FreeBSD (POSIX.1e)")
|
||||
ELSEIF(ARCHIVE_ACL_LIBACL OR ARCHIVE_ACL_LIBRICHACL)
|
||||
IF(ARCHIVE_ACL_LIBACL AND ARCHIVE_ACL_LIBRICHACL)
|
||||
MESSAGE(STATUS "ACL support: libacl (POSIX.1e) + librichacl (NFSv4)")
|
||||
ELSEIF(ARCHIVE_ACL_LIBRICHACL)
|
||||
MESSAGE(STATUS "ACL support: librichacl (NFSv4)")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "ACL support: libacl (POSIX.1e)")
|
||||
ENDIF()
|
||||
ELSEIF(ARCHIVE_ACL_SUNOS_NFS4)
|
||||
MESSAGE(STATUS "ACL support: Solaris (POSIX.1e and NFSv4)")
|
||||
ELSEIF(ARCHIVE_ACL_SUNOS)
|
||||
MESSAGE(STATUS "ACL support: Solaris (POSIX.1e)")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "ACL support: none")
|
||||
ENDIF()
|
||||
|
||||
# Solaris and derivates ACLs
|
||||
CHECK_TYPE_EXISTS(aclent_t "${INCLUDES}" HAVE_ACLENT_T)
|
||||
CHECK_TYPE_EXISTS(ace_t "${INCLUDES}" HAVE_ACE_T)
|
||||
CHECK_FUNCTION_EXISTS(acl HAVE_ACL)
|
||||
CHECK_FUNCTION_EXISTS(facl HAVE_FACL)
|
||||
CHECK_SYMBOL_EXISTS(GETACL "${INCLUDES}" HAVE_DECL_GETACL)
|
||||
CHECK_SYMBOL_EXISTS(GETACLCNT "${INCLUDES}" HAVE_DECL_GETACLCNT)
|
||||
CHECK_SYMBOL_EXISTS(SETACL "${INCLUDES}" HAVE_DECL_SETACL)
|
||||
CHECK_SYMBOL_EXISTS(ACE_GETACL "${INCLUDES}" HAVE_DECL_ACE_GETACL)
|
||||
CHECK_SYMBOL_EXISTS(ACE_GETACLCNT "${INCLUDES}" HAVE_DECL_ACE_GETACLCNT)
|
||||
CHECK_SYMBOL_EXISTS(ACE_SETACL "${INCLUDES}" HAVE_DECL_ACE_SETACL)
|
||||
ELSE(ENABLE_ACL)
|
||||
# If someone runs cmake, then disables ACL support, we need
|
||||
# to forcibly override the cached values for these.
|
||||
SET(HAVE_ACL_CREATE_ENTRY FALSE)
|
||||
SET(HAVE_ACL_GET_LINK FALSE)
|
||||
SET(HAVE_ACL_GET_LINK_NP FALSE)
|
||||
SET(HAVE_ACL_GET_PERM FALSE)
|
||||
SET(HAVE_ACL_GET_PERM_NP FALSE)
|
||||
SET(HAVE_ACL_INIT FALSE)
|
||||
SET(HAVE_ACL_LIB FALSE)
|
||||
SET(HAVE_ACL_PERMSET_T FALSE)
|
||||
SET(HAVE_ACL_SET_FD FALSE)
|
||||
SET(HAVE_ACL_SET_FD_NP FALSE)
|
||||
SET(HAVE_ACL_SET_FILE FALSE)
|
||||
SET(HAVE_ACL_TYPE_EXTENDED FALSE)
|
||||
SET(HAVE_ACLENT_T FALSE)
|
||||
SET(HAVE_ACE_T FALSE)
|
||||
SET(HAVE_DECL_ACL_TYPE_NFS4 FALSE)
|
||||
SET(HAVE_DECL_ACL_USER FALSE)
|
||||
SET(HAVE_DECL_ACL_SYNCHRONIZE FALSE)
|
||||
SET(HAVE_DECL_GETACL FALSE)
|
||||
SET(HAVE_DECL_GETACLCNT FALSE)
|
||||
SET(HAVE_DECL_SETACL FALSE)
|
||||
SET(HAVE_DECL_ACE_GETACL FALSE)
|
||||
SET(HAVE_DECL_ACE_GETACLCNT FALSE)
|
||||
SET(HAVE_DECL_ACE_SETACL FALSE)
|
||||
SET(HAVE_ACL FALSE)
|
||||
SET(HAVE_FACL FALSE)
|
||||
SET(ARCHIVE_ACL_DARWIN FALSE)
|
||||
SET(ARCHIVE_ACL_FREEBSD FALSE)
|
||||
SET(ARCHIVE_ACL_FREEBSD_NFS4 FALSE)
|
||||
SET(ARCHIVE_ACL_LIBACL FALSE)
|
||||
SET(ARCHIVE_ACL_SUNOS FALSE)
|
||||
SET(ARCHIVE_ACL_SUNOS_NFS4 FALSE)
|
||||
ENDIF(ENABLE_ACL)
|
||||
|
||||
#
|
||||
|
35
Makefile.am
35
Makefile.am
@ -127,6 +127,7 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_pathmatch.c \
|
||||
libarchive/archive_pathmatch.h \
|
||||
libarchive/archive_platform.h \
|
||||
libarchive/archive_platform_acl.h \
|
||||
libarchive/archive_ppmd_private.h \
|
||||
libarchive/archive_ppmd7.c \
|
||||
libarchive/archive_ppmd7_private.h \
|
||||
@ -186,9 +187,9 @@ libarchive_la_SOURCES= \
|
||||
libarchive/archive_string_composition.h \
|
||||
libarchive/archive_string_sprintf.c \
|
||||
libarchive/archive_util.c \
|
||||
libarchive/archive_version_details.c \
|
||||
libarchive/archive_virtual.c \
|
||||
libarchive/archive_write.c \
|
||||
libarchive/archive_write_disk_acl.c \
|
||||
libarchive/archive_write_disk_posix.c \
|
||||
libarchive/archive_write_disk_private.h \
|
||||
libarchive/archive_write_disk_set_standard_lookup.c \
|
||||
@ -247,6 +248,38 @@ libarchive_la_SOURCES+= \
|
||||
libarchive/filter_fork_windows.c
|
||||
endif
|
||||
|
||||
if INC_LINUX_ACL
|
||||
libarchive_la_SOURCES+= \
|
||||
libarchive/archive_acl_maps.h \
|
||||
libarchive/archive_acl_maps_linux.c \
|
||||
libarchive/archive_read_disk_acl_linux.c \
|
||||
libarchive/archive_write_disk_acl_linux.c
|
||||
else
|
||||
if INC_SUNOS_ACL
|
||||
libarchive_la_SOURCES+= \
|
||||
libarchive/archive_acl_maps.h \
|
||||
libarchive/archive_acl_maps_sunos.c \
|
||||
libarchive/archive_read_disk_acl_sunos.c \
|
||||
libarchive/archive_write_disk_acl_sunos.c
|
||||
else
|
||||
if INC_DARWIN_ACL
|
||||
libarchive_la_SOURCES+= \
|
||||
libarchive/archive_acl_maps.h \
|
||||
libarchive/archive_acl_maps_darwin.c \
|
||||
libarchive/archive_read_disk_acl_darwin.c \
|
||||
libarchive/archive_write_disk_acl_darwin.c
|
||||
else
|
||||
if INC_FREEBSD_ACL
|
||||
libarchive_la_SOURCES+= \
|
||||
libarchive/archive_acl_maps.h \
|
||||
libarchive/archive_acl_maps_freebsd.c \
|
||||
libarchive/archive_read_disk_acl_freebsd.c \
|
||||
libarchive/archive_write_disk_acl_freebsd.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# -no-undefined marks that libarchive doesn't rely on symbols
|
||||
# defined in the application. This is mandatory for cygwin.
|
||||
libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION)
|
||||
|
4
NEWS
4
NEWS
@ -1,3 +1,5 @@
|
||||
Mar 16, 2017: NFSv4 ACL support for Linux (librichacl)
|
||||
|
||||
Feb 26, 2017: libarchive 3.3.1 released
|
||||
Security & Feature release
|
||||
|
||||
@ -293,7 +295,7 @@ May 04, 2008: libarchive 2.5.3b released
|
||||
* libarchive: Mark which entry strings are set; be accurate about
|
||||
distinguishing empty strings ("") from unset ones (NULL)
|
||||
* tar: Don't crash reading entries with empty filenames
|
||||
* libarchive_test, bsdtar_test, bsdcpio_test: Better detaults:
|
||||
* libarchive_test, bsdtar_test, bsdcpio_test: Better defaults:
|
||||
run all tests, delete temp dirs, summarize repeated failures
|
||||
* -no-undefined to libtool for Cygwin
|
||||
* libarchive_test: Skip large file tests on systems with 32-bit off_t
|
||||
|
@ -179,6 +179,27 @@ typedef uint64_t uintmax_t;
|
||||
/* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
|
||||
#cmakedefine ZLIB_WINAPI 1
|
||||
|
||||
/* Darwin ACL support */
|
||||
#cmakedefine ARCHIVE_ACL_DARWIN 1
|
||||
|
||||
/* FreeBSD ACL support */
|
||||
#cmakedefine ARCHIVE_ACL_FREEBSD 1
|
||||
|
||||
/* FreeBSD NFSv4 ACL support */
|
||||
#cmakedefine ARCHIVE_ACL_FREEBSD_NFS4 1
|
||||
|
||||
/* Linux POSIX.1e ACL support via libacl */
|
||||
#cmakedefine ARCHIVE_ACL_LIBACL 1
|
||||
|
||||
/* Linux NFSv4 ACL support via librichacl */
|
||||
#cmakedefine ARCHIVE_ACL_LIBRICHACL 1
|
||||
|
||||
/* Solaris ACL support */
|
||||
#cmakedefine ARCHIVE_ACL_SUNOS 1
|
||||
|
||||
/* Solaris NFSv4 ACL support */
|
||||
#cmakedefine ARCHIVE_ACL_SUNOS_NFS4 1
|
||||
|
||||
/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */
|
||||
#cmakedefine ARCHIVE_CRYPTO_MD5_LIBC 1
|
||||
|
||||
@ -1013,6 +1034,9 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
#cmakedefine HAVE_SYS_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/richacl.h> header file. */
|
||||
#cmakedefine HAVE_SYS_RICHACL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SELECT_H 1
|
||||
|
||||
|
@ -30,9 +30,14 @@ IF(ENABLE_CAT AND ENABLE_TEST)
|
||||
#
|
||||
ADD_EXECUTABLE(bsdcat_test ${bsdcat_test_SOURCES})
|
||||
IF(ENABLE_ACL)
|
||||
SET(TEST_ACL_LIBS "")
|
||||
IF(HAVE_LIBACL)
|
||||
TARGET_LINK_LIBRARIES(bsdcat_test ${ACL_LIBRARY})
|
||||
LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBACL)
|
||||
IF(HAVE_LIBRICHACL)
|
||||
LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBRICHACL)
|
||||
TARGET_LINK_LIBRARIES(bsdcat_test ${TEST_ACL_LIBS})
|
||||
ENDIF(ENABLE_ACL)
|
||||
SET_PROPERTY(TARGET bsdcat_test PROPERTY COMPILE_DEFINITIONS LIST_H)
|
||||
|
||||
|
272
configure.ac
272
configure.ac
@ -253,6 +253,7 @@ esac
|
||||
# Checks for header files.
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS([acl/libacl.h])
|
||||
AC_CHECK_HEADERS([copyfile.h ctype.h])
|
||||
AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h grp.h])
|
||||
|
||||
@ -283,16 +284,16 @@ AS_VAR_IF([ac_cv_have_decl_FS_IOC_GETFLAGS], [yes],
|
||||
[AC_DEFINE_UNQUOTED([HAVE_WORKING_FS_IOC_GETFLAGS], [1],
|
||||
[Define to 1 if you have a working FS_IOC_GETFLAGS])])
|
||||
|
||||
AC_CHECK_HEADERS([locale.h paths.h poll.h pthread.h pwd.h])
|
||||
AC_CHECK_HEADERS([locale.h membership.h paths.h poll.h pthread.h pwd.h])
|
||||
AC_CHECK_HEADERS([readpassphrase.h signal.h spawn.h])
|
||||
AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h])
|
||||
AC_CHECK_HEADERS([sys/cdefs.h sys/extattr.h])
|
||||
AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/extattr.h])
|
||||
AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h])
|
||||
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/select.h sys/statfs.h sys/statvfs.h])
|
||||
AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/richacl.h])
|
||||
AC_CHECK_HEADERS([sys/select.h sys/statfs.h sys/statvfs.h])
|
||||
AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h])
|
||||
AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h])
|
||||
AC_CHECK_HEADERS([windows.h])
|
||||
AC_CHECK_HEADERS([Bcrypt.h])
|
||||
# check windows.h first; the other headers require it.
|
||||
AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[],
|
||||
[[#ifdef HAVE_WINDOWS_H
|
||||
@ -399,6 +400,9 @@ if test "x$with_lzo2" = "xyes"; then
|
||||
AC_CHECK_LIB(lzo2,lzo1x_decompress_safe)
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([cng],
|
||||
AS_HELP_STRING([--without-cng], [Don't build support of CNG(Crypto Next Generation)]))
|
||||
|
||||
AC_ARG_WITH([nettle],
|
||||
AS_HELP_STRING([--without-nettle], [Don't build with crypto support from Nettle]))
|
||||
AC_ARG_WITH([openssl],
|
||||
@ -697,66 +701,212 @@ AC_ARG_ENABLE([acl],
|
||||
[Disable ACL support (default: check)]))
|
||||
|
||||
if test "x$enable_acl" != "xno"; then
|
||||
AC_CHECK_HEADERS([acl/libacl.h])
|
||||
AC_CHECK_HEADERS([sys/acl.h])
|
||||
AC_CHECK_HEADERS([membership.h])
|
||||
AC_CHECK_LIB([acl],[acl_get_file])
|
||||
AC_CHECK_FUNCS([acl_create_entry acl_get_fd_np])
|
||||
AC_CHECK_FUNCS([acl_init acl_set_fd acl_set_fd_np acl_set_file])
|
||||
# Libacl
|
||||
AC_CHECK_LIB([acl], [acl_get_file])
|
||||
|
||||
AC_CHECK_TYPES(acl_permset_t,,,
|
||||
[#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
])
|
||||
AC_CHECK_TYPES([acl_t, acl_entry_t, acl_permset_t, acl_tag_t], [], [], [
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
# The "acl_get_perm()" function was omitted from the POSIX draft.
|
||||
# (It's a pretty obvious oversight; otherwise, there's no way to
|
||||
# test for specific permissions in a permset.) Linux uses the obvious
|
||||
# name, FreeBSD adds _np to mark it as "non-Posix extension."
|
||||
# Test for both as a double-check that we really have POSIX-style ACL
|
||||
# support.
|
||||
AC_CHECK_FUNCS(acl_get_perm_np acl_get_perm acl_get_link acl_get_link_np,,,
|
||||
[#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
])
|
||||
AC_CHECK_LIB([richacl], [richacl_get_file])
|
||||
|
||||
# Check for acl_is_trivial_np on FreeBSD
|
||||
AC_CHECK_FUNCS(acl_is_trivial_np,,,
|
||||
[#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
# FreeBSD and POSIX
|
||||
# MacOS has no ACL_USER in acl.h
|
||||
AC_CHECK_DECLS([ACL_TYPE_NFS4, ACL_USER],
|
||||
[], [],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/acl.h>])
|
||||
|
||||
# FreeBSD and MacOS ACL support
|
||||
AC_CHECK_DECLS([ACL_TYPE_EXTENDED, ACL_SYNCHRONIZE], [], [],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/acl.h>])
|
||||
AC_CHECK_TYPES([[struct richace], [struct richacl]], [], [], [
|
||||
#if HAVE_SYS_RICHACL_H
|
||||
#include <sys/richacl.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
# Solaris and derivates ACLs
|
||||
AC_CHECK_TYPES([aclent_t], [], [], [[#include <sys/acl.h>]])
|
||||
AC_CHECK_TYPES([ace_t], [], [], [[#include <sys/acl.h>]])
|
||||
AC_CHECK_FUNCS(acl facl)
|
||||
AC_CHECK_DECLS([GETACL, SETACL, GETACLCNT, ACE_GETACL, ACE_SETACL, ACE_GETACLCNT], [], [], [#include <sys/acl.h>])
|
||||
|
||||
if test "x$ac_cv_lib_richacl_richacl_get_file" = "xyes" \
|
||||
-a "x$ac_cv_type_struct_richace" = "xyes" \
|
||||
-a "x$ac_cv_type_struct_richacl" = "xyes"; then
|
||||
AC_CACHE_VAL([ac_cv_archive_acl_librichacl],
|
||||
[AC_CHECK_FUNCS(richacl_alloc \
|
||||
richacl_equiv_mode \
|
||||
richacl_free \
|
||||
richacl_get_fd \
|
||||
richacl_get_file \
|
||||
richacl_set_fd \
|
||||
richacl_set_file,
|
||||
[ac_cv_archive_acl_librichacl=yes], [ac_cv_archive_acl_librichacl=no], [#include <sys/richacl.h>])])
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_func_acl" = "xyes" \
|
||||
-a "x$ac_cv_func_facl" = "xyes"; then
|
||||
AC_CHECK_TYPES([aclent_t], [], [], [[#include <sys/acl.h>]])
|
||||
if test "x$ac_cv_type_aclent_t" = "xyes"; then
|
||||
AC_CACHE_VAL([ac_cv_archive_acl_sunos],
|
||||
[AC_CHECK_DECLS([GETACL, SETACL, GETACLCNT],
|
||||
[ac_cv_archive_acl_sunos=yes], [ac_cv_archive_acl_sunos=no],
|
||||
[#include <sys/acl.h>])])
|
||||
AC_CHECK_TYPES([ace_t], [], [], [[#include <sys/acl.h>]])
|
||||
if test "x$ac_cv_type_ace_t" = "xyes"; then
|
||||
AC_CACHE_VAL([ac_cv_archive_acl_sunos_nfs4],
|
||||
[AC_CHECK_DECLS([ACE_GETACL, ACE_SETACL, ACE_GETACLCNT],
|
||||
[ac_cv_archive_acl_sunos_nfs4=yes],
|
||||
[ac_cv_archive_acl_sonos_nfs4=no],
|
||||
[#include <sys/acl.h>])])
|
||||
fi
|
||||
fi
|
||||
elif test "x$ac_cv_type_acl_t" = "xyes" \
|
||||
-a "x$ac_cv_type_acl_entry_t" = "xyes" \
|
||||
-a "x$ac_cv_type_acl_permset_t" = "xyes" \
|
||||
-a "x$ac_cv_type_acl_tag_t" = "xyes"; then
|
||||
# POSIX.1e ACL functions
|
||||
AC_CACHE_VAL([ac_cv_posix_acl_funcs],
|
||||
[AC_CHECK_FUNCS(acl_add_perm \
|
||||
acl_clear_perms \
|
||||
acl_create_entry \
|
||||
acl_delete_def_file \
|
||||
acl_free \
|
||||
acl_get_entry \
|
||||
acl_get_fd \
|
||||
acl_get_file \
|
||||
acl_get_permset \
|
||||
acl_get_qualifier \
|
||||
acl_get_tag_type \
|
||||
acl_init \
|
||||
acl_set_fd \
|
||||
acl_set_file \
|
||||
acl_set_qualifier \
|
||||
acl_set_tag_type,
|
||||
[ac_cv_posix_acl_funcs=yes], [ac_cv_posix_acl_funcs=no],
|
||||
[#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
])
|
||||
])
|
||||
|
||||
AC_CHECK_FUNCS(acl_get_perm)
|
||||
|
||||
if test "x$ac_cv_posix_acl_funcs" = "xyes" \
|
||||
-a "x$ac_cv_header_acl_libacl_h" = "xyes" \
|
||||
-a "x$ac_cv_lib_acl_acl_get_file" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_perm"; then
|
||||
AC_CACHE_VAL([ac_cv_archive_acl_libacl],
|
||||
[ac_cv_archive_acl_libacl=yes])
|
||||
AC_DEFINE([ARCHIVE_ACL_LIBACL], [1],
|
||||
[POSIX.1e ACL support via libacl])
|
||||
else
|
||||
# FreeBSD/Darwin
|
||||
AC_CHECK_FUNCS(acl_add_flag_np \
|
||||
acl_clear_flags_np \
|
||||
acl_get_brand_np \
|
||||
acl_get_entry_type_np \
|
||||
acl_get_flag_np \
|
||||
acl_get_flagset_np \
|
||||
acl_get_fd_np \
|
||||
acl_get_link_np \
|
||||
acl_get_perm_np \
|
||||
acl_is_trivial_np \
|
||||
acl_set_entry_type_np \
|
||||
acl_set_fd_np \
|
||||
acl_set_link_np,,,
|
||||
[#include <sys/types.h>
|
||||
#include <sys/acl.h>])
|
||||
|
||||
AC_CHECK_FUNCS(mbr_uid_to_uuid \
|
||||
mbr_uuid_to_id \
|
||||
mbr_gid_to_uuid,,,
|
||||
[#include <membership.h>])
|
||||
|
||||
AC_CHECK_DECLS([ACL_TYPE_EXTENDED, ACL_TYPE_NFS4, ACL_USER,
|
||||
ACL_SYNCHRONIZE], [], [],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/acl.h>])
|
||||
if test "x$ac_cv_posix_acl_funcs" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_fd_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_perm" != "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_perm_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_set_fd_np" = "xyes"; then
|
||||
if test "x$ac_cv_have_decl_ACL_USER" = "xyes"; then
|
||||
AC_CACHE_VAL([ac_cv_archive_acl_freebsd],
|
||||
[ac_cv_archive_acl_freebsd=yes])
|
||||
if test "x$ac_cv_have_decl_ACL_TYPE_NFS4" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_add_flag_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_brand_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_entry_type_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_flagset_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_set_entry_type_np" = "xyes"; then
|
||||
AC_CACHE_VAL([ac_cv_archive_acl_freebsd_nfs4],
|
||||
[ac_cv_archive_acl_freebsd_nfs4=yes])
|
||||
fi
|
||||
elif test "x$ac_cv_have_decl_ACL_TYPE_EXTENDED" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_add_flag_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_flagset_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_get_link_np" = "xyes" \
|
||||
-a "x$ac_cv_func_acl_set_link_np" = "xyes" \
|
||||
-a "x$ac_cv_func_mbr_uid_to_uuid" = "xyes" \
|
||||
-a "x$ac_cv_func_mbr_uuid_to_id" = "xyes" \
|
||||
-a "x$ac_cv_func_mbr_gid_to_uuid" = "xyes"; then
|
||||
AC_CACHE_VAL([ac_cv_archive_acl_darwin],
|
||||
[ac_cv_archive_acl_darwin=yes])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_MSG_CHECKING([for ACL support])
|
||||
if test "x$ac_cv_archive_acl_libacl" = "xyes" \
|
||||
-a "x$ac_cv_archive_acl_librichacl" = "xyes"; then
|
||||
AC_MSG_RESULT([libacl (POSIX.1e) + librichacl (NFSv4)])
|
||||
AC_DEFINE([ARCHIVE_ACL_LIBACL], [1],
|
||||
[Linux POSIX.1e ACL support via libacl])
|
||||
AC_DEFINE([ARCHIVE_ACL_LIBRICHACL], [1],
|
||||
[Linux NFSv4 ACL support via librichacl])
|
||||
elif test "x$ac_cv_archive_acl_libacl" = "xyes"; then
|
||||
AC_MSG_RESULT([libacl (POSIX.1e)])
|
||||
AC_DEFINE([ARCHIVE_ACL_LIBACL], [1],
|
||||
[Linux POSIX.1e ACL support via libacl])
|
||||
elif test "x$ac_cv_archive_acl_librichacl" = "xyes"; then
|
||||
AC_MSG_RESULT([librichacl (NFSv4)])
|
||||
AC_DEFINE([ARCHIVE_ACL_LIBRICHACL], [1],
|
||||
[Linux NFSv4 ACL support via librichacl])
|
||||
elif test "x$ac_cv_archive_acl_darwin" = "xyes"; then
|
||||
AC_DEFINE([ARCHIVE_ACL_DARWIN], [1], [Darwin ACL support])
|
||||
AC_MSG_RESULT([Darwin (limited NFSv4)])
|
||||
elif test "x$ac_cv_archive_acl_sunos" = "xyes"; then
|
||||
AC_DEFINE([ARCHIVE_ACL_SUNOS], [1], [Solaris ACL support])
|
||||
if test "x$ac_cv_archive_acl_sunos_nfs4" = "xyes"; then
|
||||
AC_DEFINE([ARCHIVE_ACL_SUNOS_NFS4], [1],
|
||||
[Solaris NFSv4 ACL support])
|
||||
AC_MSG_RESULT([Solaris (POSIX.1e and NFSv4)])
|
||||
else
|
||||
AC_MSG_RESULT([Solaris (POSIX.1e)])
|
||||
fi
|
||||
elif test "x$ac_cv_archive_acl_freebsd" = "xyes"; then
|
||||
AC_DEFINE([ARCHIVE_ACL_FREEBSD], [1], [FreeBSD ACL support])
|
||||
if test "x$ac_cv_archive_acl_freebsd_nfs4" = "xyes"; then
|
||||
AC_DEFINE([ARCHIVE_ACL_FREEBSD_NFS4], [1],
|
||||
[FreeBSD NFSv4 ACL support])
|
||||
AC_MSG_RESULT([FreeBSD (POSIX.1e and NFSv4)])
|
||||
else
|
||||
AC_MSG_RESULT([FreeBSD (POSIX.1e)])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([none])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
AM_CONDITIONAL([INC_LINUX_ACL],
|
||||
[test "x$ac_cv_archive_acl_libacl" = "xyes" \
|
||||
-o "x$ac_cv_archive_acl_librichacl" = "xyes"])
|
||||
AM_CONDITIONAL([INC_SUNOS_ACL], [test "x$ac_cv_archive_acl_sunos" = "xyes"])
|
||||
AM_CONDITIONAL([INC_DARWIN_ACL],
|
||||
[test "x$ac_cv_archive_acl_darwin" = "xyes"])
|
||||
AM_CONDITIONAL([INC_FREEBSD_ACL],
|
||||
[test "x$ac_cv_archive_acl_freebsd" = "xyes"])
|
||||
|
||||
# Additional requirements
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
@ -845,6 +995,16 @@ case "$host_os" in
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "x$with_cng" != "xno"; then
|
||||
AC_CHECK_HEADERS([bcrypt.h],[
|
||||
LIBS="$LIBS -lbcrypt"
|
||||
],[],
|
||||
[[#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
]])
|
||||
fi
|
||||
|
||||
if test "x$with_nettle" != "xno"; then
|
||||
AC_CHECK_HEADERS([nettle/md5.h nettle/ripemd160.h nettle/sha.h])
|
||||
AC_CHECK_HEADERS([nettle/pbkdf2.h nettle/aes.h nettle/hmac.h])
|
||||
|
46
cpio/cpio.c
46
cpio/cpio.c
@ -1344,23 +1344,23 @@ lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable,
|
||||
cache->cache[slot].name = NULL;
|
||||
}
|
||||
|
||||
if (lookup_fn(cpio, &name, id) == 0) {
|
||||
if (name == NULL || name[0] == '\0') {
|
||||
/* If lookup failed, format it as a number. */
|
||||
snprintf(asnum, sizeof(asnum), "%u", (unsigned)id);
|
||||
name = asnum;
|
||||
}
|
||||
cache->cache[slot].name = strdup(name);
|
||||
if (cache->cache[slot].name != NULL) {
|
||||
cache->cache[slot].id = id;
|
||||
return (cache->cache[slot].name);
|
||||
}
|
||||
/*
|
||||
* Conveniently, NULL marks an empty slot, so
|
||||
* if the strdup() fails, we've just failed to
|
||||
* cache it. No recovery necessary.
|
||||
*/
|
||||
if (lookup_fn(cpio, &name, id)) {
|
||||
/* If lookup failed, format it as a number. */
|
||||
snprintf(asnum, sizeof(asnum), "%u", (unsigned)id);
|
||||
name = asnum;
|
||||
}
|
||||
|
||||
cache->cache[slot].name = strdup(name);
|
||||
if (cache->cache[slot].name != NULL) {
|
||||
cache->cache[slot].id = id;
|
||||
return (cache->cache[slot].name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Conveniently, NULL marks an empty slot, so
|
||||
* if the strdup() fails, we've just failed to
|
||||
* cache it. No recovery necessary.
|
||||
*/
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -1381,15 +1381,14 @@ lookup_uname_helper(struct cpio *cpio, const char **name, id_t id)
|
||||
errno = 0;
|
||||
pwent = getpwuid((uid_t)id);
|
||||
if (pwent == NULL) {
|
||||
*name = NULL;
|
||||
if (errno != 0 && errno != ENOENT)
|
||||
if (errno && errno != ENOENT)
|
||||
lafe_warnc(errno, "getpwuid(%s) failed",
|
||||
cpio_i64toa((int64_t)id));
|
||||
return (errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*name = pwent->pw_name;
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *
|
||||
@ -1409,15 +1408,14 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
|
||||
errno = 0;
|
||||
grent = getgrgid((gid_t)id);
|
||||
if (grent == NULL) {
|
||||
*name = NULL;
|
||||
if (errno != 0)
|
||||
if (errno && errno != ENOENT)
|
||||
lafe_warnc(errno, "getgrgid(%s) failed",
|
||||
cpio_i64toa((int64_t)id));
|
||||
return (errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*name = grent->gr_name;
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -63,9 +63,14 @@ IF(ENABLE_CPIO AND ENABLE_TEST)
|
||||
#
|
||||
ADD_EXECUTABLE(bsdcpio_test ${bsdcpio_test_SOURCES})
|
||||
IF(ENABLE_ACL)
|
||||
SET(TEST_ACL_LIBS "")
|
||||
IF(HAVE_LIBACL)
|
||||
TARGET_LINK_LIBRARIES(bsdcpio_test ${ACL_LIBRARY})
|
||||
LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBACL)
|
||||
IF(HAVE_LIBRICHACL)
|
||||
LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBRICHACL)
|
||||
TARGET_LINK_LIBRARIES(bsdcpio_test ${TEST_ACL_LIBS})
|
||||
ENDIF(ENABLE_ACL)
|
||||
SET_PROPERTY(TARGET bsdcpio_test PROPERTY COMPILE_DEFINITIONS LIST_H)
|
||||
|
||||
|
@ -14,6 +14,7 @@ SET(include_HEADERS
|
||||
# Sources and private headers
|
||||
SET(libarchive_SOURCES
|
||||
archive_acl.c
|
||||
archive_acl_private.h
|
||||
archive_check_magic.c
|
||||
archive_cmdline.c
|
||||
archive_cmdline_private.h
|
||||
@ -47,6 +48,7 @@ SET(libarchive_SOURCES
|
||||
archive_pathmatch.c
|
||||
archive_pathmatch.h
|
||||
archive_platform.h
|
||||
archive_platform_acl.h
|
||||
archive_ppmd_private.h
|
||||
archive_ppmd7.c
|
||||
archive_ppmd7_private.h
|
||||
@ -106,9 +108,9 @@ SET(libarchive_SOURCES
|
||||
archive_string_composition.h
|
||||
archive_string_sprintf.c
|
||||
archive_util.c
|
||||
archive_version_details.c
|
||||
archive_virtual.c
|
||||
archive_write.c
|
||||
archive_write_disk_acl.c
|
||||
archive_write_disk_posix.c
|
||||
archive_write_disk_private.h
|
||||
archive_write_disk_set_standard_lookup.c
|
||||
@ -210,6 +212,28 @@ IF(WIN32 AND NOT CYGWIN)
|
||||
LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
ENDIF()
|
||||
|
||||
# Libarchive is a shared library
|
||||
ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
|
||||
TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
|
||||
|
52
libarchive/archive_acl_maps.h
Normal file
52
libarchive/archive_acl_maps.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* 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;
|
||||
|
||||
#ifndef _ARCHIVE_ACL_MAPS_DEFS
|
||||
#if ARCHIVE_ACL_POSIX1E
|
||||
extern const acl_perm_map_t acl_posix_perm_map[];
|
||||
extern const int acl_posix_perm_map_size;
|
||||
#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_DEFS */
|
||||
#endif /* ARCHIVE_ACL_MAPS_H_INCLUDED */
|
76
libarchive/archive_acl_maps_darwin.c
Normal file
76
libarchive/archive_acl_maps_darwin.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#define _ARCHIVE_ACL_MAPS_DEFS
|
||||
#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]));
|
87
libarchive/archive_acl_maps_freebsd.c
Normal file
87
libarchive/archive_acl_maps_freebsd.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#define _ARCHIVE_ACL_MAPS_DEFS
|
||||
#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 */
|
90
libarchive/archive_acl_maps_linux.c
Normal file
90
libarchive/archive_acl_maps_linux.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_RICHACL_H
|
||||
#include <sys/richacl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#define _ARCHIVE_ACL_MAPS_DEFS
|
||||
#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 */
|
90
libarchive/archive_acl_maps_sunos.c
Normal file
90
libarchive/archive_acl_maps_sunos.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#define _ARCHIVE_ACL_MAPS_DEFS
|
||||
#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 */
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd Feburary 2, 2012
|
||||
.Dd February 2, 2012
|
||||
.Dt ARCHIVE_ENTRY 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -267,7 +267,7 @@ Only inherit, do not apply the permission on the directory itself.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n )
|
||||
Do not propagate inherit flags. Only first-level entries inherit ACLs.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S )
|
||||
Trigger alarm or audit on succesful access.
|
||||
Trigger alarm or audit on successful access.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F )
|
||||
Trigger alarm or audit on failed access.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERITED ( Sy I )
|
||||
@ -279,7 +279,7 @@ and
|
||||
.Fn archive_entry_acl_add_entry_w
|
||||
add a single ACL entry.
|
||||
For the access ACL and non-extended principals, the classic Unix permissions
|
||||
are updated. An archive enry cannot contain both POSIX.1e and NFSv4 ACL
|
||||
are updated. An archive entry cannot contain both POSIX.1e and NFSv4 ACL
|
||||
entries.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_clear
|
||||
@ -303,7 +303,7 @@ for POSIX.1e ACLs and
|
||||
for NFSv4 ACLs. For POSIX.1e ACLs if
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
is included and at least one extended ACL entry is found,
|
||||
the three non-extened ACLs are added.
|
||||
the three non-extended ACLs are added.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_from_text
|
||||
and
|
||||
@ -367,7 +367,7 @@ and
|
||||
.Fn archive_entry_acl_to_text_w
|
||||
convert the ACL entries for the given type into a
|
||||
.Pq wide
|
||||
string of ACL entries separated by newline. If the the pointer
|
||||
string of ACL entries separated by newline. If the pointer
|
||||
.Fa len_p
|
||||
is not NULL, then the function shall return the length of the string
|
||||
.Pq not including the NULL terminator
|
||||
|
@ -142,40 +142,6 @@
|
||||
#define INTMAX_MIN ((intmax_t)(~INTMAX_MAX))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
|
||||
* acl_set_file(), and ACL_USER, we assume it has the rest of the
|
||||
* POSIX.1e draft functions used in archive_read_extract.c.
|
||||
*/
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
|
||||
#if HAVE_DECL_ACL_USER
|
||||
#define HAVE_POSIX_ACL 1
|
||||
#elif HAVE_DECL_ACL_TYPE_EXTENDED && HAVE_MEMBERSHIP_H
|
||||
#define HAVE_DARWIN_ACL 1
|
||||
#endif
|
||||
#if HAVE_DECL_ACL_TYPE_NFS4
|
||||
#define HAVE_FREEBSD_NFS4_ACL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this platform has <sys/acl.h>, acl(), facl() and ACLENT_T
|
||||
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
|
||||
*/
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL && HAVE_FACL && HAVE_ACLENT_T && \
|
||||
HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL
|
||||
#define HAVE_SUN_ACL 1
|
||||
#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \
|
||||
HAVE_DECL_ACE_SETACL
|
||||
#define HAVE_SUN_NFS4_ACL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Define if platform supports NFSv4 ACLs */
|
||||
#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL
|
||||
#define HAVE_NFS4_ACL 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we can't restore metadata using a file descriptor, then
|
||||
* for compatibility's sake, close files before trying to restore metadata.
|
||||
|
49
libarchive/archive_platform_acl.h
Normal file
49
libarchive/archive_platform_acl.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
|
||||
|
||||
#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
|
||||
#define ARCHIVE_PLATFORM_ACL_H_INCLUDED
|
||||
|
||||
/*
|
||||
* Determine what ACL types are supported
|
||||
*/
|
||||
#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_SUNOS || ARCHIVE_ACL_LIBACL
|
||||
#define ARCHIVE_ACL_POSIX1E 1
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_SUNOS_NFS4 || \
|
||||
ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
|
||||
#define ARCHIVE_ACL_NFS4 1
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_POSIX1E || ARCHIVE_ACL_NFS4
|
||||
#define ARCHIVE_ACL_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#endif /* ARCHIVE_PLATFORM_ACL_H_INCLUDED */
|
@ -221,8 +221,11 @@ arc4_stir(void)
|
||||
/*
|
||||
* Discard early keystream, as per recommendations in:
|
||||
* "(Not So) Random Shuffles of RC4" by Ilya Mironov.
|
||||
* As per the Network Operations Division, cryptographic requirements
|
||||
* published on wikileaks on March 2017.
|
||||
*/
|
||||
for (i = 0; i < 1024; i++)
|
||||
|
||||
for (i = 0; i < 3072; i++)
|
||||
(void)arc4_getbyte();
|
||||
arc4_count = 1600000;
|
||||
}
|
||||
|
337
libarchive/archive_read_disk_acl_darwin.c
Normal file
337
libarchive/archive_read_disk_acl_darwin.c
Normal file
@ -0,0 +1,337 @@
|
||||
/*-
|
||||
* 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_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#if HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#if HAVE_MEMBERSHIP_H
|
||||
#include <membership.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#include "archive_acl_maps.h"
|
||||
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
void *q;
|
||||
uid_t ugid;
|
||||
int r, idtype;
|
||||
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q == NULL)
|
||||
return (1);
|
||||
r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
|
||||
if (r != 0) {
|
||||
acl_free(q);
|
||||
return (1);
|
||||
}
|
||||
if (idtype == ID_TYPE_UID) {
|
||||
*ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
*ae_id = ugid;
|
||||
*ae_name = archive_read_disk_uname(a, *ae_id);
|
||||
} else if (idtype == ID_TYPE_GID) {
|
||||
*ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
*ae_id = ugid;
|
||||
*ae_name = archive_read_disk_gname(a, *ae_id);
|
||||
} else
|
||||
r = 1;
|
||||
|
||||
acl_free(q);
|
||||
return (r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add trivial NFSv4 ACL entries from mode
|
||||
*/
|
||||
static void
|
||||
add_trivial_nfs4_acl(struct archive_entry *entry)
|
||||
{
|
||||
mode_t mode;
|
||||
int i;
|
||||
const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
|
||||
const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA;
|
||||
const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
|
||||
const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER;
|
||||
|
||||
struct {
|
||||
const int type;
|
||||
const int tag;
|
||||
int permset;
|
||||
} tacl_entry[] = {
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset}
|
||||
};
|
||||
|
||||
mode = archive_entry_mode(entry);
|
||||
|
||||
/* Permissions for everyone@ */
|
||||
if (mode & 0004)
|
||||
tacl_entry[5].permset |= rperm;
|
||||
if (mode & 0002)
|
||||
tacl_entry[5].permset |= wperm;
|
||||
if (mode & 0001)
|
||||
tacl_entry[5].permset |= eperm;
|
||||
|
||||
/* Permissions for group@ */
|
||||
if (mode & 0040)
|
||||
tacl_entry[4].permset |= rperm;
|
||||
else if (mode & 0004)
|
||||
tacl_entry[2].permset |= rperm;
|
||||
if (mode & 0020)
|
||||
tacl_entry[4].permset |= wperm;
|
||||
else if (mode & 0002)
|
||||
tacl_entry[2].permset |= wperm;
|
||||
if (mode & 0010)
|
||||
tacl_entry[4].permset |= eperm;
|
||||
else if (mode & 0001)
|
||||
tacl_entry[2].permset |= eperm;
|
||||
|
||||
/* Permissions for owner@ */
|
||||
if (mode & 0400) {
|
||||
tacl_entry[3].permset |= rperm;
|
||||
if (!(mode & 0040) && (mode & 0004))
|
||||
tacl_entry[0].permset |= rperm;
|
||||
} else if ((mode & 0040) || (mode & 0004))
|
||||
tacl_entry[1].permset |= rperm;
|
||||
if (mode & 0200) {
|
||||
tacl_entry[3].permset |= wperm;
|
||||
if (!(mode & 0020) && (mode & 0002))
|
||||
tacl_entry[0].permset |= wperm;
|
||||
} else if ((mode & 0020) || (mode & 0002))
|
||||
tacl_entry[1].permset |= wperm;
|
||||
if (mode & 0100) {
|
||||
tacl_entry[3].permset |= eperm;
|
||||
if (!(mode & 0010) && (mode & 0001))
|
||||
tacl_entry[0].permset |= eperm;
|
||||
} else if ((mode & 0010) || (mode & 0001))
|
||||
tacl_entry[1].permset |= eperm;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (tacl_entry[i].permset != 0) {
|
||||
archive_entry_acl_add_entry(entry,
|
||||
tacl_entry[i].type, tacl_entry[i].permset,
|
||||
tacl_entry[i].tag, -1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl)
|
||||
{
|
||||
acl_tag_t acl_tag;
|
||||
acl_flagset_t acl_flagset;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
int i, entry_acl_type;
|
||||
int r, s, ae_id, ae_tag, ae_perm;
|
||||
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 == 0) {
|
||||
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_EXTENDED_ALLOW:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
r = translate_guid(&a->archive, acl_entry,
|
||||
&ae_id, &ae_tag, &ae_name);
|
||||
break;
|
||||
case ACL_EXTENDED_DENY:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
r = translate_guid(&a->archive, acl_entry,
|
||||
&ae_id, &ae_tag, &ae_name);
|
||||
break;
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip if translate_guid() above failed */
|
||||
if (r != 0) {
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Libarchive stores "flag" (NFSv4 inheritance bits)
|
||||
* in the ae_perm bitmap.
|
||||
*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get flagset from a NFSv4 ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
r = acl_get_flag_np(acl_flagset,
|
||||
acl_nfs4_flag_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check flag in a NFSv4 "
|
||||
"ACL flagset");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_nfs4_flag_map[i].a_perm;
|
||||
}
|
||||
|
||||
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_nfs4_perm_map_size; ++i) {
|
||||
/*
|
||||
* acl_get_perm() is spelled differently on different
|
||||
* platforms; see above.
|
||||
*/
|
||||
r = acl_get_perm_np(acl_permset,
|
||||
acl_nfs4_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_nfs4_perm_map[i].a_perm;
|
||||
}
|
||||
|
||||
#if !HAVE_DECL_ACL_SYNCHRONIZE
|
||||
/* On Mac OS X without ACL_SYNCHRONIZE assume it is set */
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
|
||||
#endif
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
acl_t acl;
|
||||
int r;
|
||||
|
||||
accpath = NULL;
|
||||
|
||||
if (*fd < 0) {
|
||||
accpath = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (accpath == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
acl = NULL;
|
||||
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_EXTENDED);
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_EXTENDED);
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_EXTENDED);
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
|
||||
/*
|
||||
* Because Mac OS doesn't support owner@, group@ and everyone@
|
||||
* ACLs we need to add NFSv4 ACLs mirroring the file mode to
|
||||
* the archive entry. Otherwise extraction on non-Mac platforms
|
||||
* would lead to an invalid file mode.
|
||||
*/
|
||||
if ((archive_entry_acl_types(entry) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
|
||||
add_trivial_nfs4_acl(entry);
|
||||
|
||||
return (r);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
371
libarchive/archive_read_disk_acl_freebsd.c
Normal file
371
libarchive/archive_read_disk_acl_freebsd.c
Normal file
@ -0,0 +1,371 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2016-2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#include "archive_acl_maps.h"
|
||||
|
||||
/*
|
||||
* Translate FreeBSD ACLs into libarchive internal structure
|
||||
*/
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
||||
{
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
int brand;
|
||||
acl_flagset_t acl_flagset;
|
||||
#endif
|
||||
acl_tag_t acl_tag;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
acl_entry_type_t acl_type;
|
||||
int i, entry_acl_type, perm_map_size;
|
||||
const acl_perm_map_t *perm_map;
|
||||
int r, s, ae_id, ae_tag, ae_perm;
|
||||
void *q;
|
||||
const char *ae_name;
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
|
||||
// Make sure the "brand" on this ACL is consistent
|
||||
// with the default_entry_acl_type bits provided.
|
||||
if (acl_get_brand_np(acl, &brand) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to read ACL brand");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (brand) {
|
||||
case ACL_BRAND_POSIX:
|
||||
switch (default_entry_acl_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ACL entry type for POSIX.1e ACL");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
break;
|
||||
case ACL_BRAND_NFS4:
|
||||
if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ACL entry type for NFSv4 ACL");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown ACL brand");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#endif
|
||||
|
||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get first ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
while (s == 1) {
|
||||
ae_id = -1;
|
||||
ae_name = NULL;
|
||||
ae_perm = 0;
|
||||
|
||||
if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL tag type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_tag) {
|
||||
case ACL_USER:
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(uid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
break;
|
||||
case ACL_GROUP:
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(gid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
break;
|
||||
case ACL_MASK:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
|
||||
break;
|
||||
case ACL_USER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case ACL_GROUP_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case ACL_OTHER:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
case ACL_EVERYONE:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
// XXX acl_type maps to allow/deny/audit/YYYY bits
|
||||
entry_acl_type = default_entry_acl_type;
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
/*
|
||||
* acl_get_entry_type_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) {
|
||||
archive_set_error(&a->archive, errno, "Failed "
|
||||
"to get ACL type from a NFSv4 ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_type) {
|
||||
case ACL_ENTRY_TYPE_ALLOW:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_DENY:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_AUDIT:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_ALARM:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Invalid NFSv4 ACL entry type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Libarchive stores "flag" (NFSv4 inheritance bits)
|
||||
* in the ae_perm bitmap.
|
||||
*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get flagset from a NFSv4 "
|
||||
"ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
r = acl_get_flag_np(acl_flagset,
|
||||
acl_nfs4_flag_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check flag in a NFSv4 "
|
||||
"ACL flagset");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_nfs4_flag_map[i].a_perm;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
perm_map_size = acl_nfs4_perm_map_size;
|
||||
perm_map = acl_nfs4_perm_map;
|
||||
} else {
|
||||
#endif
|
||||
perm_map_size = acl_posix_perm_map_size;
|
||||
perm_map = acl_posix_perm_map;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < perm_map_size; ++i) {
|
||||
r = acl_get_perm_np(acl_permset, perm_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check permission in an ACL "
|
||||
"permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= perm_map[i].a_perm;
|
||||
}
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get next ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
acl_t acl;
|
||||
int r;
|
||||
|
||||
accpath = NULL;
|
||||
|
||||
if (*fd < 0) {
|
||||
accpath = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (accpath == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
acl = NULL;
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
/* Try NFSv4 ACL first. */
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_NFS4);
|
||||
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Retrieve access ACL from file. */
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_ACCESS);
|
||||
#if HAVE_ACL_GET_LINK_NP
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
|
||||
#else
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one. */
|
||||
acl = NULL;
|
||||
#endif
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
|
||||
|
||||
#if HAVE_ACL_IS_TRIVIAL_NP
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate access ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only directories can have default ACLs. */
|
||||
if (S_ISDIR(archive_entry_mode(entry))) {
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT);
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
|
||||
acl_free(acl);
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate default ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
352
libarchive/archive_read_disk_acl_linux.c
Normal file
352
libarchive/archive_read_disk_acl_linux.c
Normal file
@ -0,0 +1,352 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2016-2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#if HAVE_ACL_LIBACL_H
|
||||
#include <acl/libacl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#if HAVE_SYS_RICHACL_H
|
||||
#include <sys/richacl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#include "archive_acl_maps.h"
|
||||
|
||||
#if HAVE_LIBACL
|
||||
#include <acl/libacl.h>
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
/*
|
||||
* Translate POSIX.1e ACLs into libarchive internal structure
|
||||
*/
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
||||
{
|
||||
acl_tag_t acl_tag;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
int i, entry_acl_type;
|
||||
int r, s, ae_id, ae_tag, ae_perm;
|
||||
void *q;
|
||||
const char *ae_name;
|
||||
|
||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get first ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
while (s == 1) {
|
||||
ae_id = -1;
|
||||
ae_name = NULL;
|
||||
ae_perm = 0;
|
||||
|
||||
if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL tag type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_tag) {
|
||||
case ACL_USER:
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(uid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
break;
|
||||
case ACL_GROUP:
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(gid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
break;
|
||||
case ACL_MASK:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
|
||||
break;
|
||||
case ACL_USER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case ACL_GROUP_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case ACL_OTHER:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
// XXX acl_type maps to allow/deny/audit/YYYY bits
|
||||
entry_acl_type = default_entry_acl_type;
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get ACL permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_posix_perm_map_size; ++i) {
|
||||
r = acl_get_perm(acl_permset,
|
||||
acl_posix_perm_map[i].p_perm);
|
||||
if (r == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to check permission in an ACL "
|
||||
"permission set");
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_posix_perm_map[i].a_perm;
|
||||
}
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get next ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
/*
|
||||
* Translate RichACL into libarchive internal ACL
|
||||
*/
|
||||
static int
|
||||
translate_richacl(struct archive_read_disk *a, struct archive_entry *entry,
|
||||
struct richacl *richacl)
|
||||
{
|
||||
int ae_id, ae_tag, ae_perm;
|
||||
int entry_acl_type, i;
|
||||
const char *ae_name;
|
||||
|
||||
struct richace *richace;
|
||||
|
||||
richacl_for_each_entry(richace, richacl) {
|
||||
ae_name = NULL;
|
||||
ae_tag = 0;
|
||||
ae_perm = 0;
|
||||
ae_id = -1;
|
||||
|
||||
switch (richace->e_type) {
|
||||
case RICHACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
break;
|
||||
case RICHACE_ACCESS_DENIED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
break;
|
||||
default: /* Unknown entry type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Unsupported */
|
||||
if (richace->e_flags & RICHACE_UNMAPPED_WHO)
|
||||
continue;
|
||||
|
||||
if (richace->e_flags & RICHACE_SPECIAL_WHO) {
|
||||
switch (richace->e_id) {
|
||||
case RICHACE_OWNER_SPECIAL_ID:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case RICHACE_GROUP_SPECIAL_ID:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case RICHACE_EVERYONE_SPECIAL_ID:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
break;
|
||||
default: /* Unknown special ID type */
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
ae_id = richace->e_id;
|
||||
if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
(gid_t)(richace->e_id));
|
||||
} else {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
(uid_t)(richace->e_id));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if ((richace->e_flags &
|
||||
acl_nfs4_flag_map[i].p_perm) != 0)
|
||||
ae_perm |= acl_nfs4_flag_map[i].a_perm;
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
|
||||
if ((richace->e_mask &
|
||||
acl_nfs4_perm_map[i].p_perm) != 0)
|
||||
ae_perm |=
|
||||
acl_nfs4_perm_map[i].a_perm;
|
||||
}
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag, ae_id, ae_name);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
int r;
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
acl_t acl;
|
||||
#endif
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
struct richacl *richacl;
|
||||
mode_t mode;
|
||||
#endif
|
||||
|
||||
accpath = NULL;
|
||||
r = ARCHIVE_OK;
|
||||
|
||||
/* For default ACLs we need reachable accpath */
|
||||
if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) {
|
||||
accpath = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (accpath == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
acl = NULL;
|
||||
#endif
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
richacl = NULL;
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
/* Try NFSv4 ACL first. */
|
||||
if (*fd >= 0)
|
||||
richacl = richacl_get_fd(*fd);
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one */
|
||||
richacl = NULL;
|
||||
else
|
||||
richacl = richacl_get_file(accpath);
|
||||
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (richacl != NULL) {
|
||||
mode = archive_entry_mode(entry);
|
||||
if (richacl_equiv_mode(richacl, &mode) == 0) {
|
||||
richacl_free(richacl);
|
||||
richacl = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
}
|
||||
|
||||
if (richacl != NULL) {
|
||||
r = translate_richacl(a, entry, richacl);
|
||||
richacl_free(richacl);
|
||||
richacl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
/* Retrieve access ACL from file. */
|
||||
if (*fd >= 0)
|
||||
acl = acl_get_fd(*fd);
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
/* We can't get the ACL of a symlink, so we assume it can't
|
||||
have one. */
|
||||
acl = NULL;
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate access ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only directories can have default ACLs. */
|
||||
if (S_ISDIR(archive_entry_mode(entry))) {
|
||||
acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
|
||||
acl_free(acl);
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate default ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
return (r);
|
||||
}
|
482
libarchive/archive_read_disk_acl_sunos.c
Normal file
482
libarchive/archive_read_disk_acl_sunos.c
Normal file
@ -0,0 +1,482 @@
|
||||
/*-
|
||||
* 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_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_read_disk_private.h"
|
||||
#include "archive_acl_maps.h"
|
||||
|
||||
/*
|
||||
* Solaris-specific ACL functions and helper functions
|
||||
*
|
||||
* Exported functions:
|
||||
* translate_acl()
|
||||
*/
|
||||
static void *
|
||||
sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
|
||||
{
|
||||
int cnt, cntcmd;
|
||||
size_t size;
|
||||
void *aclp;
|
||||
|
||||
if (cmd == GETACL) {
|
||||
cntcmd = GETACLCNT;
|
||||
size = sizeof(aclent_t);
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else if (cmd == ACE_GETACL) {
|
||||
cntcmd = ACE_GETACLCNT;
|
||||
size = sizeof(ace_t);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
errno = EINVAL;
|
||||
*aclcnt = -1;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
aclp = NULL;
|
||||
cnt = -2;
|
||||
|
||||
while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
|
||||
if (path != NULL)
|
||||
cnt = acl(path, cntcmd, 0, NULL);
|
||||
else
|
||||
cnt = facl(fd, cntcmd, 0, NULL);
|
||||
|
||||
if (cnt > 0) {
|
||||
if (aclp == NULL)
|
||||
aclp = malloc(cnt * size);
|
||||
else
|
||||
aclp = realloc(NULL, cnt * size);
|
||||
if (aclp != NULL) {
|
||||
if (path != NULL)
|
||||
cnt = acl(path, cmd, cnt, aclp);
|
||||
else
|
||||
cnt = facl(fd, cmd, cnt, aclp);
|
||||
}
|
||||
} else {
|
||||
if (aclp != NULL) {
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*aclcnt = cnt;
|
||||
return (aclp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if acl is trivial
|
||||
* This is a FreeBSD acl_is_trivial_np() implementation for Solaris
|
||||
*/
|
||||
static int
|
||||
sun_acl_is_trivial(void *aclp, int aclcnt, mode_t mode, int is_nfs4,
|
||||
int is_dir, int *trivialp)
|
||||
{
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
int i, p;
|
||||
const uint32_t rperm = ACE_READ_DATA;
|
||||
const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
|
||||
const uint32_t eperm = ACE_EXECUTE;
|
||||
const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
|
||||
ACE_READ_ACL | ACE_SYNCHRONIZE;
|
||||
const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
|
||||
ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
|
||||
|
||||
ace_t *ace;
|
||||
ace_t tace[6];
|
||||
#endif
|
||||
|
||||
if (aclp == NULL || trivialp == NULL)
|
||||
return (-1);
|
||||
|
||||
*trivialp = 0;
|
||||
|
||||
/*
|
||||
* POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
|
||||
* FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
|
||||
* including mask.
|
||||
*/
|
||||
if (!is_nfs4) {
|
||||
if (aclcnt == 4)
|
||||
*trivialp = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
/*
|
||||
* Continue with checking NFSv4 ACLs
|
||||
*
|
||||
* Create list of trivial ace's to be compared
|
||||
*/
|
||||
|
||||
/* owner@ allow pre */
|
||||
tace[0].a_flags = ACE_OWNER;
|
||||
tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[0].a_access_mask = 0;
|
||||
|
||||
/* owner@ deny */
|
||||
tace[1].a_flags = ACE_OWNER;
|
||||
tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
tace[1].a_access_mask = 0;
|
||||
|
||||
/* group@ deny */
|
||||
tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
|
||||
tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
tace[2].a_access_mask = 0;
|
||||
|
||||
/* owner@ allow */
|
||||
tace[3].a_flags = ACE_OWNER;
|
||||
tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[3].a_access_mask = ownset;
|
||||
|
||||
/* group@ allow */
|
||||
tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
|
||||
tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[4].a_access_mask = pubset;
|
||||
|
||||
/* everyone@ allow */
|
||||
tace[5].a_flags = ACE_EVERYONE;
|
||||
tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[5].a_access_mask = pubset;
|
||||
|
||||
/* Permissions for everyone@ */
|
||||
if (mode & 0004)
|
||||
tace[5].a_access_mask |= rperm;
|
||||
if (mode & 0002)
|
||||
tace[5].a_access_mask |= wperm;
|
||||
if (mode & 0001)
|
||||
tace[5].a_access_mask |= eperm;
|
||||
|
||||
/* Permissions for group@ */
|
||||
if (mode & 0040)
|
||||
tace[4].a_access_mask |= rperm;
|
||||
else if (mode & 0004)
|
||||
tace[2].a_access_mask |= rperm;
|
||||
if (mode & 0020)
|
||||
tace[4].a_access_mask |= wperm;
|
||||
else if (mode & 0002)
|
||||
tace[2].a_access_mask |= wperm;
|
||||
if (mode & 0010)
|
||||
tace[4].a_access_mask |= eperm;
|
||||
else if (mode & 0001)
|
||||
tace[2].a_access_mask |= eperm;
|
||||
|
||||
/* Permissions for owner@ */
|
||||
if (mode & 0400) {
|
||||
tace[3].a_access_mask |= rperm;
|
||||
if (!(mode & 0040) && (mode & 0004))
|
||||
tace[0].a_access_mask |= rperm;
|
||||
} else if ((mode & 0040) || (mode & 0004))
|
||||
tace[1].a_access_mask |= rperm;
|
||||
if (mode & 0200) {
|
||||
tace[3].a_access_mask |= wperm;
|
||||
if (!(mode & 0020) && (mode & 0002))
|
||||
tace[0].a_access_mask |= wperm;
|
||||
} else if ((mode & 0020) || (mode & 0002))
|
||||
tace[1].a_access_mask |= wperm;
|
||||
if (mode & 0100) {
|
||||
tace[3].a_access_mask |= eperm;
|
||||
if (!(mode & 0010) && (mode & 0001))
|
||||
tace[0].a_access_mask |= eperm;
|
||||
} else if ((mode & 0010) || (mode & 0001))
|
||||
tace[1].a_access_mask |= eperm;
|
||||
|
||||
/* Check if the acl count matches */
|
||||
p = 3;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (tace[i].a_access_mask != 0)
|
||||
p++;
|
||||
}
|
||||
if (aclcnt != p)
|
||||
return (0);
|
||||
|
||||
p = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (tace[i].a_access_mask != 0) {
|
||||
ace = &((ace_t *)aclp)[p];
|
||||
/*
|
||||
* Illumos added ACE_DELETE_CHILD to write perms for
|
||||
* directories. We have to check against that, too.
|
||||
*/
|
||||
if (ace->a_flags != tace[i].a_flags ||
|
||||
ace->a_type != tace[i].a_type ||
|
||||
(ace->a_access_mask != tace[i].a_access_mask &&
|
||||
(!is_dir || (tace[i].a_access_mask & wperm) == 0 ||
|
||||
ace->a_access_mask !=
|
||||
(tace[i].a_access_mask | ACE_DELETE_CHILD))))
|
||||
return (0);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
*trivialp = 1;
|
||||
#else /* !ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
(void)is_dir; /* UNUSED */
|
||||
(void)aclp; /* UNUSED */
|
||||
#endif /* !ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
|
||||
*/
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, void *aclp, int aclcnt,
|
||||
int default_entry_acl_type)
|
||||
{
|
||||
int e, i;
|
||||
int ae_id, ae_tag, ae_perm;
|
||||
int entry_acl_type;
|
||||
const char *ae_name;
|
||||
aclent_t *aclent;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
ace_t *ace;
|
||||
#endif
|
||||
|
||||
if (aclcnt <= 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
for (e = 0; e < aclcnt; e++) {
|
||||
ae_name = NULL;
|
||||
ae_tag = 0;
|
||||
ae_perm = 0;
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
ace = &((ace_t *)aclp)[e];
|
||||
ae_id = ace->a_who;
|
||||
|
||||
switch(ace->a_type) {
|
||||
case ACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
break;
|
||||
case ACE_ACCESS_DENIED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
break;
|
||||
case ACE_SYSTEM_AUDIT_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
break;
|
||||
case ACE_SYSTEM_ALARM_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
|
||||
break;
|
||||
default:
|
||||
/* Unknown entry type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ace->a_flags & ACE_OWNER) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
else if ((ace->a_flags & ACE_GROUP) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
else if ((ace->a_flags & ACE_EVERYONE) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
} else {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if ((ace->a_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 ((ace->a_access_mask &
|
||||
acl_nfs4_perm_map[i].p_perm) != 0)
|
||||
ae_perm |= acl_nfs4_perm_map[i].a_perm;
|
||||
}
|
||||
} else
|
||||
#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
||||
aclent = &((aclent_t *)aclp)[e];
|
||||
if ((aclent->a_type & ACL_DEFAULT) != 0)
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
|
||||
else
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
ae_id = aclent->a_id;
|
||||
|
||||
switch(aclent->a_type) {
|
||||
case DEF_USER:
|
||||
case USER:
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
break;
|
||||
case DEF_GROUP:
|
||||
case GROUP:
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
break;
|
||||
case DEF_CLASS_OBJ:
|
||||
case CLASS_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
|
||||
break;
|
||||
case DEF_USER_OBJ:
|
||||
case USER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case DEF_GROUP_OBJ:
|
||||
case GROUP_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case DEF_OTHER_OBJ:
|
||||
case OTHER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
default:
|
||||
/* Unknown tag type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_posix_perm_map_size; ++i) {
|
||||
if ((aclent->a_perm &
|
||||
acl_posix_perm_map[i].p_perm) != 0)
|
||||
ae_perm |= acl_posix_perm_map[i].a_perm;
|
||||
}
|
||||
} else
|
||||
return (ARCHIVE_WARN);
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag, ae_id, ae_name);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
void *aclp;
|
||||
int aclcnt;
|
||||
int r;
|
||||
|
||||
accpath = NULL;
|
||||
|
||||
if (*fd < 0) {
|
||||
accpath = archive_read_disk_entry_setup_path(a, entry, fd);
|
||||
if (accpath == NULL)
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
archive_entry_acl_clear(entry);
|
||||
|
||||
aclp = NULL;
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (*fd >= 0)
|
||||
aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL);
|
||||
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. */
|
||||
aclp = NULL;
|
||||
else
|
||||
aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath);
|
||||
|
||||
if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
|
||||
archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)),
|
||||
&r) == 0 && r == 1) {
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
if (aclp != NULL) {
|
||||
r = translate_acl(a, entry, aclp, aclcnt,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4);
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate NFSv4 ACLs");
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
|
||||
/* Retrieve POSIX.1e ACLs from file. */
|
||||
if (*fd >= 0)
|
||||
aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL);
|
||||
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. */
|
||||
aclp = NULL;
|
||||
else
|
||||
aclp = sunacl_get(GETACL, &aclcnt, 0, accpath);
|
||||
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
|
||||
archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)),
|
||||
&r) == 0 && r == 1) {
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
}
|
||||
|
||||
if (aclp != NULL)
|
||||
{
|
||||
r = translate_acl(a, entry, aclp, aclcnt,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Couldn't translate access ACLs");
|
||||
return (r);
|
||||
}
|
||||
}
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,8 @@
|
||||
#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_platform_acl.h"
|
||||
|
||||
struct tree;
|
||||
struct archive_entry;
|
||||
|
||||
@ -86,4 +88,11 @@ struct archive_read_disk {
|
||||
void *excluded_cb_data;
|
||||
};
|
||||
|
||||
const char *
|
||||
archive_read_disk_entry_setup_path(struct archive_read_disk *,
|
||||
struct archive_entry *, int *);
|
||||
|
||||
int
|
||||
archive_read_disk_entry_setup_acls(struct archive_read_disk *,
|
||||
struct archive_entry *, int *);
|
||||
#endif
|
||||
|
@ -1857,33 +1857,38 @@ mtree_atol8(char **p)
|
||||
* Note that this implementation does not (and should not!) obey
|
||||
* locale settings; you cannot simply substitute strtol here, since
|
||||
* it does obey locale.
|
||||
*
|
||||
* Convert the number pointed to by 'p' into a 64-bit signed integer.
|
||||
* On return, 'p' points to the first non-digit following the number.
|
||||
* On overflow, the function returns INT64_MIN or INT64_MAX.
|
||||
*/
|
||||
static int64_t
|
||||
mtree_atol10(char **p)
|
||||
{
|
||||
int64_t l, limit, last_digit_limit;
|
||||
int base, digit, sign;
|
||||
|
||||
base = 10;
|
||||
const int base = 10;
|
||||
const int64_t limit = INT64_MAX / base;
|
||||
const int64_t last_digit_limit = INT64_MAX % base;
|
||||
int64_t l;
|
||||
int sign;
|
||||
|
||||
if (**p == '-') {
|
||||
sign = -1;
|
||||
limit = ((uint64_t)(INT64_MAX) + 1) / base;
|
||||
last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
|
||||
++(*p);
|
||||
} else {
|
||||
sign = 1;
|
||||
limit = INT64_MAX / base;
|
||||
last_digit_limit = INT64_MAX % base;
|
||||
}
|
||||
|
||||
l = 0;
|
||||
digit = **p - '0';
|
||||
while (digit >= 0 && digit < base) {
|
||||
if (l > limit || (l == limit && digit > last_digit_limit))
|
||||
while (**p >= '0' && **p < '0' + base) {
|
||||
int digit = **p - '0';
|
||||
if (l > limit || (l == limit && digit > last_digit_limit)) {
|
||||
while (**p >= '0' && **p < '0' + base) {
|
||||
++(*p);
|
||||
}
|
||||
return (sign < 0) ? INT64_MIN : INT64_MAX;
|
||||
}
|
||||
l = (l * base) + digit;
|
||||
digit = *++(*p) - '0';
|
||||
++(*p);
|
||||
}
|
||||
return (sign < 0) ? -l : l;
|
||||
}
|
||||
|
@ -155,6 +155,7 @@ struct tar {
|
||||
int compat_2x;
|
||||
int process_mac_extensions;
|
||||
int read_concatenated_archives;
|
||||
int realsize_override;
|
||||
};
|
||||
|
||||
static int archive_block_is_null(const char *p);
|
||||
@ -527,6 +528,7 @@ archive_read_format_tar_read_header(struct archive_read *a,
|
||||
tar->entry_offset = 0;
|
||||
gnu_clear_sparse_list(tar);
|
||||
tar->realsize = -1; /* Mark this as "unset" */
|
||||
tar->realsize_override = 0;
|
||||
|
||||
/* Setup default string conversion. */
|
||||
tar->sconv = tar->opt_sconv;
|
||||
@ -1894,6 +1896,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
|
||||
if (strcmp(key, "GNU.sparse.size") == 0) {
|
||||
tar->realsize = tar_atol10(value, strlen(value));
|
||||
archive_entry_set_size(entry, tar->realsize);
|
||||
tar->realsize_override = 1;
|
||||
}
|
||||
|
||||
/* GNU "0.1" sparse pax format. */
|
||||
@ -1925,6 +1928,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
|
||||
if (strcmp(key, "GNU.sparse.realsize") == 0) {
|
||||
tar->realsize = tar_atol10(value, strlen(value));
|
||||
archive_entry_set_size(entry, tar->realsize);
|
||||
tar->realsize_override = 1;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
@ -1977,6 +1981,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
|
||||
tar_atol10(value, strlen(value)));
|
||||
} else if (strcmp(key, "SCHILY.realsize") == 0) {
|
||||
tar->realsize = tar_atol10(value, strlen(value));
|
||||
tar->realsize_override = 1;
|
||||
archive_entry_set_size(entry, tar->realsize);
|
||||
} else if (strncmp(key, "SCHILY.xattr.", 13) == 0) {
|
||||
pax_attribute_schily_xattr(entry, key, value,
|
||||
@ -2055,14 +2060,12 @@ pax_attribute(struct archive_read *a, struct tar *tar,
|
||||
tar->entry_bytes_remaining
|
||||
= tar_atol10(value, strlen(value));
|
||||
/*
|
||||
* But, "size" is not necessarily the size of
|
||||
* the file on disk; if this is a sparse file,
|
||||
* the disk size may have already been set from
|
||||
* GNU.sparse.realsize or GNU.sparse.size or
|
||||
* an old GNU header field or SCHILY.realsize
|
||||
* or ....
|
||||
* The "size" pax header keyword always overrides the
|
||||
* "size" field in the tar header.
|
||||
* GNU.sparse.realsize, GNU.sparse.size and
|
||||
* SCHILY.realsize override this value.
|
||||
*/
|
||||
if (tar->realsize < 0) {
|
||||
if (!tar->realsize_override) {
|
||||
archive_entry_set_size(entry,
|
||||
tar->entry_bytes_remaining);
|
||||
tar->realsize
|
||||
@ -2206,6 +2209,7 @@ header_gnutar(struct archive_read *a, struct tar *tar,
|
||||
tar->realsize
|
||||
= tar_atol(header->realsize, sizeof(header->realsize));
|
||||
archive_entry_set_size(entry, tar->realsize);
|
||||
tar->realsize_override = 1;
|
||||
}
|
||||
|
||||
if (header->sparse[0].offset[0] != 0) {
|
||||
|
@ -2407,7 +2407,7 @@ read_eocd(struct zip *zip, const char *p, int64_t current_offset)
|
||||
* Examine Zip64 EOCD locator: If it's valid, store the information
|
||||
* from it.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
|
||||
{
|
||||
int64_t eocd64_offset;
|
||||
@ -2417,35 +2417,37 @@ read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
|
||||
|
||||
/* Central dir must be on first volume. */
|
||||
if (archive_le32dec(p + 4) != 0)
|
||||
return;
|
||||
return 0;
|
||||
/* Must be only a single volume. */
|
||||
if (archive_le32dec(p + 16) != 1)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
/* Find the Zip64 EOCD record. */
|
||||
eocd64_offset = archive_le64dec(p + 8);
|
||||
if (__archive_read_seek(a, eocd64_offset, SEEK_SET) < 0)
|
||||
return;
|
||||
return 0;
|
||||
if ((p = __archive_read_ahead(a, 56, NULL)) == NULL)
|
||||
return;
|
||||
return 0;
|
||||
/* Make sure we can read all of it. */
|
||||
eocd64_size = archive_le64dec(p + 4) + 12;
|
||||
if (eocd64_size < 56 || eocd64_size > 16384)
|
||||
return;
|
||||
return 0;
|
||||
if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
/* Sanity-check the EOCD64 */
|
||||
if (archive_le32dec(p + 16) != 0) /* Must be disk #0 */
|
||||
return;
|
||||
return 0;
|
||||
if (archive_le32dec(p + 20) != 0) /* CD must be on disk #0 */
|
||||
return;
|
||||
return 0;
|
||||
/* CD can't be split. */
|
||||
if (archive_le64dec(p + 24) != archive_le64dec(p + 32))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
/* Save the central directory offset for later use. */
|
||||
zip->central_directory_offset = archive_le64dec(p + 48);
|
||||
|
||||
return 32;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2483,15 +2485,14 @@ archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
|
||||
if (memcmp(p + i, "PK\005\006", 4) == 0) {
|
||||
int ret = read_eocd(zip, p + i,
|
||||
current_offset + i);
|
||||
if (ret > 0) {
|
||||
/* Zip64 EOCD locator precedes
|
||||
* regular EOCD if present. */
|
||||
if (i >= 20
|
||||
&& memcmp(p + i - 20, "PK\006\007", 4) == 0) {
|
||||
read_zip64_eocd(a, zip, p + i - 20);
|
||||
}
|
||||
return (ret);
|
||||
/* Zip64 EOCD locator precedes
|
||||
* regular EOCD if present. */
|
||||
if (i >= 20 && memcmp(p + i - 20, "PK\006\007", 4) == 0) {
|
||||
int ret_zip64 = read_zip64_eocd(a, zip, p + i - 20);
|
||||
if (ret_zip64 > ret)
|
||||
ret = ret_zip64;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
i -= 4;
|
||||
break;
|
||||
|
@ -89,88 +89,6 @@ archive_version_string(void)
|
||||
return (ARCHIVE_VERSION_STRING);
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_version_details(void)
|
||||
{
|
||||
static struct archive_string str;
|
||||
static int init = 0;
|
||||
const char *zlib = archive_zlib_version();
|
||||
const char *liblzma = archive_liblzma_version();
|
||||
const char *bzlib = archive_bzlib_version();
|
||||
const char *liblz4 = archive_liblz4_version();
|
||||
|
||||
if (!init) {
|
||||
archive_string_init(&str);
|
||||
|
||||
archive_strcat(&str, ARCHIVE_VERSION_STRING);
|
||||
if (zlib != NULL) {
|
||||
archive_strcat(&str, " zlib/");
|
||||
archive_strcat(&str, zlib);
|
||||
}
|
||||
if (liblzma) {
|
||||
archive_strcat(&str, " liblzma/");
|
||||
archive_strcat(&str, liblzma);
|
||||
}
|
||||
if (bzlib) {
|
||||
const char *p = bzlib;
|
||||
const char *sep = strchr(p, ',');
|
||||
if (sep == NULL)
|
||||
sep = p + strlen(p);
|
||||
archive_strcat(&str, " bz2lib/");
|
||||
archive_strncat(&str, p, sep - p);
|
||||
}
|
||||
if (liblz4) {
|
||||
archive_strcat(&str, " liblz4/");
|
||||
archive_strcat(&str, liblz4);
|
||||
}
|
||||
}
|
||||
return str.s;
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_zlib_version(void)
|
||||
{
|
||||
#ifdef HAVE_ZLIB_H
|
||||
return ZLIB_VERSION;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_liblzma_version(void)
|
||||
{
|
||||
#ifdef HAVE_LZMA_H
|
||||
return LZMA_VERSION_STRING;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_bzlib_version(void)
|
||||
{
|
||||
#ifdef HAVE_BZLIB_H
|
||||
return BZ2_bzlibVersion();
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_liblz4_version(void)
|
||||
{
|
||||
#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
|
||||
#define str(s) #s
|
||||
#define NUMBER(x) str(x)
|
||||
return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
|
||||
#undef NUMBER
|
||||
#undef str
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
archive_errno(struct archive *a)
|
||||
{
|
||||
|
133
libarchive/archive_version_details.c
Normal file
133
libarchive/archive_version_details.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_ZLIB_H
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_LZMA_H
|
||||
#include <lzma.h>
|
||||
#endif
|
||||
#ifdef HAVE_BZLIB_H
|
||||
#include <bzlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_LZ4_H
|
||||
#include <lz4.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_string.h"
|
||||
|
||||
const char *
|
||||
archive_version_details(void)
|
||||
{
|
||||
static struct archive_string str;
|
||||
static int init = 0;
|
||||
const char *zlib = archive_zlib_version();
|
||||
const char *liblzma = archive_liblzma_version();
|
||||
const char *bzlib = archive_bzlib_version();
|
||||
const char *liblz4 = archive_liblz4_version();
|
||||
|
||||
if (!init) {
|
||||
archive_string_init(&str);
|
||||
|
||||
archive_strcat(&str, ARCHIVE_VERSION_STRING);
|
||||
if (zlib != NULL) {
|
||||
archive_strcat(&str, " zlib/");
|
||||
archive_strcat(&str, zlib);
|
||||
}
|
||||
if (liblzma) {
|
||||
archive_strcat(&str, " liblzma/");
|
||||
archive_strcat(&str, liblzma);
|
||||
}
|
||||
if (bzlib) {
|
||||
const char *p = bzlib;
|
||||
const char *sep = strchr(p, ',');
|
||||
if (sep == NULL)
|
||||
sep = p + strlen(p);
|
||||
archive_strcat(&str, " bz2lib/");
|
||||
archive_strncat(&str, p, sep - p);
|
||||
}
|
||||
if (liblz4) {
|
||||
archive_strcat(&str, " liblz4/");
|
||||
archive_strcat(&str, liblz4);
|
||||
}
|
||||
}
|
||||
return str.s;
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_zlib_version(void)
|
||||
{
|
||||
#ifdef HAVE_ZLIB_H
|
||||
return ZLIB_VERSION;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_liblzma_version(void)
|
||||
{
|
||||
#ifdef HAVE_LZMA_H
|
||||
return LZMA_VERSION_STRING;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_bzlib_version(void)
|
||||
{
|
||||
#ifdef HAVE_BZLIB_H
|
||||
return BZ2_bzlibVersion();
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_liblz4_version(void)
|
||||
{
|
||||
#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
|
||||
#define str(s) #s
|
||||
#define NUMBER(x) str(x)
|
||||
return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
|
||||
#undef NUMBER
|
||||
#undef str
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
@ -1,697 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2010 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 05:35:40Z kientzle $");
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#if HAVE_DARWIN_ACL
|
||||
#include <membership.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_acl_private.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
|
||||
#if !HAVE_POSIX_ACL && !HAVE_NFS4_ACL
|
||||
/* Default empty function body to satisfy mainline code. */
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl)
|
||||
{
|
||||
(void)a; /* UNUSED */
|
||||
(void)fd; /* UNUSED */
|
||||
(void)name; /* UNUSED */
|
||||
(void)abstract_acl; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
|
||||
#elif HAVE_FREEBSD_NFS4_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
|
||||
#endif
|
||||
|
||||
static int set_acl(struct archive *, int fd, const char *,
|
||||
struct archive_acl *,
|
||||
#if !HAVE_SUN_ACL
|
||||
acl_type_t,
|
||||
#endif
|
||||
int archive_entry_acl_type, const char *tn);
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
#if !HAVE_DARWIN_ACL
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
/* Solaris writes POSIX.1e access and default ACLs together */
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
|
||||
#else /* HAVE_POSIX_ACL */
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
"access");
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
}
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
|
||||
"default");
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
/* Simultaneous POSIX.1e and NFSv4 is not supported */
|
||||
return (ret);
|
||||
}
|
||||
#endif /* !HAVE_DARWIN_ACL */
|
||||
#if HAVE_NFS4_ACL
|
||||
if ((archive_acl_types(abstract_acl) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
#if !HAVE_SUN_ACL
|
||||
ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
|
||||
#endif
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#if !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL
|
||||
/*
|
||||
* Translate system ACL permissions into libarchive internal structure
|
||||
*/
|
||||
static const struct {
|
||||
const int archive_perm;
|
||||
const int platform_perm;
|
||||
} acl_perm_map[] = {
|
||||
#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
|
||||
#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
|
||||
#if HAVE_DECL_ACL_SYNCHRONIZE
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
#else /* POSIX.1e ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
#endif /* !HAVE_SUN_ACL || HAVE_SUN_NFS4_ACL */
|
||||
|
||||
#if HAVE_NFS4_ACL
|
||||
/*
|
||||
* Translate system NFSv4 inheritance flags into libarchive internal structure
|
||||
*/
|
||||
static const struct {
|
||||
const int archive_inherit;
|
||||
const int platform_inherit;
|
||||
} acl_inherit_map[] = {
|
||||
#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
|
||||
#ifdef ACE_INHERITED_ACE
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
|
||||
#endif
|
||||
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
|
||||
#else /* FreeBSD NFSv4 ACL inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
|
||||
#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
#if !HAVE_SUN_ACL
|
||||
acl_type_t acl_type,
|
||||
#endif
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
aclent_t *aclent;
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
ace_t *ace;
|
||||
#endif
|
||||
int cmd, e, r;
|
||||
void *aclp;
|
||||
#else
|
||||
acl_t acl;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
#if HAVE_FREEBSD_NFS4_ACL || HAVE_DARWIN_ACL
|
||||
acl_flagset_t acl_flagset;
|
||||
#endif
|
||||
#endif /* HAVE_SUN_ACL */
|
||||
#if HAVE_FREEBSD_NFS4_ACL
|
||||
int r;
|
||||
#endif
|
||||
int ret;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
#if HAVE_DARWIN_ACL
|
||||
uuid_t ae_uuid;
|
||||
#endif
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
switch (ae_requested_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
|
||||
cmd = SETACL;
|
||||
aclp = malloc(entries * sizeof(aclent_t));
|
||||
break;
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
|
||||
cmd = ACE_SETACL;
|
||||
aclp = malloc(entries * sizeof(ace_t));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Invalid ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
if (aclp == NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Can't allocate memory for acl buffer");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
acl = acl_init(entries);
|
||||
if (acl == (acl_t)NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize ACL working storage");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
#if HAVE_SUN_ACL
|
||||
e = 0;
|
||||
#endif
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
#if HAVE_SUN_ACL
|
||||
aclent = NULL;
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
ace = NULL;
|
||||
#endif
|
||||
if (cmd == SETACL) {
|
||||
aclent = &((aclent_t *)aclp)[e];
|
||||
aclent->a_id = -1;
|
||||
aclent->a_type = 0;
|
||||
aclent->a_perm = 0;
|
||||
}
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
else { /* cmd == ACE_SETACL */
|
||||
ace = &((ace_t *)aclp)[e];
|
||||
ace->a_who = -1;
|
||||
ace->a_access_mask = 0;
|
||||
ace->a_flags = 0;
|
||||
}
|
||||
#endif /* HAVE_SUN_NFS4_ACL */
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
#if HAVE_DARWIN_ACL
|
||||
/*
|
||||
* Mac OS doesn't support NFSv4 ACLs for
|
||||
* owner@, group@ and everyone@.
|
||||
* We skip any of these ACLs found.
|
||||
*/
|
||||
if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
|
||||
ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
|
||||
ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
continue;
|
||||
#endif
|
||||
if (acl_create_entry(&acl, &acl_entry) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to create a new ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
#if HAVE_DARWIN_ACL
|
||||
switch (ae_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
|
||||
break;
|
||||
default:
|
||||
/* We don't support any other types on MacOS */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
switch (ae_tag) {
|
||||
#if HAVE_SUN_ACL
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
if (aclent != NULL) {
|
||||
aclent->a_id = ae_uid;
|
||||
aclent->a_type |= USER;
|
||||
}
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
else {
|
||||
ace->a_who = ae_uid;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
if (aclent != NULL) {
|
||||
aclent->a_id = ae_gid;
|
||||
aclent->a_type |= GROUP;
|
||||
}
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
else {
|
||||
ace->a_who = ae_gid;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= USER_OBJ;
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
else {
|
||||
ace->a_flags |= ACE_OWNER;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= GROUP_OBJ;
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
else {
|
||||
ace->a_flags |= ACE_GROUP;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
}
|
||||
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= CLASS_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= OTHER_OBJ;
|
||||
break;
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
if (ace != NULL)
|
||||
ace->a_flags |= ACE_EVERYONE;
|
||||
break;
|
||||
#endif
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
|
||||
acl_set_tag_type(acl_entry, ACL_USER);
|
||||
acl_set_qualifier(acl_entry, &ae_uid);
|
||||
#else /* MacOS */
|
||||
if (mbr_identifier_to_uuid(ID_TYPE_UID, &ae_uid,
|
||||
sizeof(uid_t), ae_uuid) != 0)
|
||||
continue;
|
||||
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
|
||||
continue;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP);
|
||||
acl_set_qualifier(acl_entry, &ae_gid);
|
||||
#else /* MacOS */
|
||||
if (mbr_identifier_to_uuid(ID_TYPE_GID, &ae_gid,
|
||||
sizeof(gid_t), ae_uuid) != 0)
|
||||
continue;
|
||||
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
|
||||
continue;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
break;
|
||||
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_USER_OBJ);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
acl_set_tag_type(acl_entry, ACL_MASK);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
acl_set_tag_type(acl_entry, ACL_OTHER);
|
||||
break;
|
||||
#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD only */
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
acl_set_tag_type(acl_entry, ACL_EVERYONE);
|
||||
break;
|
||||
#endif
|
||||
#endif /* !HAVE_DARWIN_ACL */
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL
|
||||
r = 0;
|
||||
switch (ae_type) {
|
||||
#if HAVE_SUN_ACL
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
#endif
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
if (aclent == NULL)
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= ACL_DEFAULT;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
// These don't translate directly into the system ACL.
|
||||
break;
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
errno = EINVAL;
|
||||
#endif
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif /* HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_ACL */
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
if (aclent != NULL) {
|
||||
if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
|
||||
aclent->a_perm |= 1;
|
||||
if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
|
||||
aclent->a_perm |= 2;
|
||||
if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
|
||||
aclent->a_perm |= 4;
|
||||
}
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
else /* falls through to for statement below, ace != NULL */
|
||||
#endif
|
||||
#else
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get ACL permission set");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_perms(acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear ACL permissions");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
|
||||
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
|
||||
if (ae_permset & acl_perm_map[i].archive_perm) {
|
||||
#if HAVE_SUN_ACL
|
||||
ace->a_access_mask |=
|
||||
acl_perm_map[i].platform_perm;
|
||||
#else
|
||||
if (acl_add_perm(acl_permset,
|
||||
acl_perm_map[i].platform_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add ACL permission");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
|
||||
|
||||
#if HAVE_NFS4_ACL
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
if (ace != NULL)
|
||||
#elif HAVE_DARWIN_ACL
|
||||
if (acl_type == ACL_TYPE_EXTENDED)
|
||||
#else /* FreeBSD */
|
||||
if (acl_type == ACL_TYPE_NFS4)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
|
||||
/*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get flagset from an NFSv4 ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_flags_np(acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear flags from an NFSv4 ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) /sizeof(acl_inherit_map[0])); ++i) {
|
||||
if (ae_permset & acl_inherit_map[i].archive_inherit) {
|
||||
#if HAVE_SUN_ACL
|
||||
ace->a_flags |=
|
||||
acl_inherit_map[i].platform_inherit;
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
if (acl_add_flag_np(acl_flagset,
|
||||
acl_inherit_map[i].platform_inherit) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add flag to NFSv4 ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif /* HAVE_SUN_ACL */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
#if HAVE_SUN_ACL
|
||||
e++;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL
|
||||
/* Try restoring the ACL through 'fd' if we can. */
|
||||
#if HAVE_SUN_ACL || HAVE_ACL_SET_FD_NP
|
||||
if (fd >= 0)
|
||||
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
|
||||
if (fd >= 0 && acl_type == ACL_TYPE_ACCESS)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
if (facl(fd, cmd, entries, aclp) == 0)
|
||||
#elif HAVE_ACL_SET_FD_NP
|
||||
if (acl_set_fd_np(fd, acl, acl_type) == 0)
|
||||
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
|
||||
if (acl_set_fd(fd, acl) == 0)
|
||||
#endif
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set %s acl on fd", tname);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl(name, cmd, entries, aclp) != 0)
|
||||
#elif HAVE_ACL_SET_LINK_NP
|
||||
if (acl_set_link_np(name, acl_type, acl) != 0)
|
||||
#else
|
||||
/* TODO: Skip this if 'name' is a symlink. */
|
||||
if (acl_set_file(name, acl_type, acl) != 0)
|
||||
#endif
|
||||
{
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set %s acl",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
#if HAVE_SUN_ACL
|
||||
free(aclp);
|
||||
#else
|
||||
acl_free(acl);
|
||||
#endif
|
||||
return (ret);
|
||||
}
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
|
234
libarchive/archive_write_disk_acl_darwin.c
Normal file
234
libarchive/archive_write_disk_acl_darwin.c
Normal file
@ -0,0 +1,234 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_MEMBERSHIP_H
|
||||
#include <membership.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
#include "archive_acl_maps.h"
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
acl_t acl;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
acl_flagset_t acl_flagset;
|
||||
int ret;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
uuid_t ae_uuid;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Unsupported ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
acl = acl_init(entries);
|
||||
if (acl == (acl_t)NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize ACL working storage");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
/*
|
||||
* Mac OS doesn't support NFSv4 ACLs for
|
||||
* owner@, group@ and everyone@.
|
||||
* We skip any of these ACLs found.
|
||||
*/
|
||||
if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
|
||||
ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
|
||||
ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
continue;
|
||||
|
||||
if (acl_create_entry(&acl, &acl_entry) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to create a new ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
switch (ae_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
|
||||
break;
|
||||
default:
|
||||
/* We don't support any other types on MacOS */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
if (mbr_uid_to_uuid(ae_uid, ae_uuid) != 0)
|
||||
continue;
|
||||
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
|
||||
continue;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
if (mbr_gid_to_uuid(ae_gid, ae_uuid) != 0)
|
||||
continue;
|
||||
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get ACL permission set");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_perms(acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear ACL permissions");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_perm_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_perm_map[i].a_perm) {
|
||||
if (acl_add_perm(acl_permset,
|
||||
acl_nfs4_perm_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add ACL permission");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get flagset from an NFSv4 ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_flags_np(acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear flags from an NFSv4 ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
|
||||
if (acl_add_flag_np(acl_flagset,
|
||||
acl_nfs4_flag_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add flag to "
|
||||
"NFSv4 ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
if (acl_set_fd_np(fd, acl, ACL_TYPE_EXTENDED) == 0)
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set acl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
} else if (acl_set_link_np(name, ACL_TYPE_EXTENDED, acl) != 0) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set acl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
acl_free(acl);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
(void)mode; /* UNUSED */
|
||||
|
||||
if ((archive_acl_types(abstract_acl) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
return (ret);
|
||||
}
|
321
libarchive/archive_write_disk_acl_freebsd.c
Normal file
321
libarchive/archive_write_disk_acl_freebsd.c
Normal file
@ -0,0 +1,321 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2010 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
#include "archive_acl_maps.h"
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
int acl_type = 0;
|
||||
acl_t acl;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
acl_flagset_t acl_flagset;
|
||||
int r;
|
||||
#endif
|
||||
int ret;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
int perm_map_size;
|
||||
const acl_perm_map_t *perm_map;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
|
||||
switch (ae_requested_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
acl_type = ACL_TYPE_ACCESS;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
acl_type = ACL_TYPE_DEFAULT;
|
||||
break;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
|
||||
acl_type = ACL_TYPE_NFS4;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Unsupported ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
acl = acl_init(entries);
|
||||
if (acl == (acl_t)NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize ACL working storage");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
if (acl_create_entry(&acl, &acl_entry) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to create a new ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
acl_set_tag_type(acl_entry, ACL_USER);
|
||||
acl_set_qualifier(acl_entry, &ae_uid);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP);
|
||||
acl_set_qualifier(acl_entry, &ae_gid);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_USER_OBJ);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
acl_set_tag_type(acl_entry, ACL_MASK);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
acl_set_tag_type(acl_entry, ACL_OTHER);
|
||||
break;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
acl_set_tag_type(acl_entry, ACL_EVERYONE);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
r = 0;
|
||||
switch (ae_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
r = acl_set_entry_type_np(acl_entry,
|
||||
ACL_ENTRY_TYPE_ALLOW);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
r = acl_set_entry_type_np(acl_entry,
|
||||
ACL_ENTRY_TYPE_DENY);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
r = acl_set_entry_type_np(acl_entry,
|
||||
ACL_ENTRY_TYPE_AUDIT);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
r = acl_set_entry_type_np(acl_entry,
|
||||
ACL_ENTRY_TYPE_ALARM);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
// These don't translate directly into the system ACL.
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get ACL permission set");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_perms(acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear ACL permissions");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
perm_map_size = acl_nfs4_perm_map_size;
|
||||
perm_map = acl_nfs4_perm_map;
|
||||
} else {
|
||||
#endif
|
||||
perm_map_size = acl_posix_perm_map_size;
|
||||
perm_map = acl_posix_perm_map;
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < perm_map_size; ++i) {
|
||||
if (ae_permset & perm_map[i].a_perm) {
|
||||
if (acl_add_perm(acl_permset,
|
||||
perm_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add ACL permission");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
/*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get flagset from an NFSv4 "
|
||||
"ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
if (acl_clear_flags_np(acl_flagset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to clear flags from an NFSv4 "
|
||||
"ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
|
||||
if (acl_add_flag_np(acl_flagset,
|
||||
acl_nfs4_flag_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add flag to "
|
||||
"NFSv4 ACL flagset");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Try restoring the ACL through 'fd' if we can. */
|
||||
if (fd >= 0) {
|
||||
if (acl_set_fd_np(fd, acl, acl_type) == 0)
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set acl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if HAVE_ACL_SET_LINK_NP
|
||||
else if (acl_set_link_np(name, acl_type, acl) != 0)
|
||||
#else
|
||||
/* FreeBSD older than 8.0 */
|
||||
else if (acl_set_file(name, acl_type, acl) != 0)
|
||||
#endif
|
||||
{
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set acl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
acl_free(acl);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
(void)mode; /* UNUSED */
|
||||
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
}
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
||||
|
||||
/* Simultaneous POSIX.1e and NFSv4 is not supported */
|
||||
return (ret);
|
||||
}
|
||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
||||
else if ((archive_acl_types(abstract_acl) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
#endif
|
||||
return (ret);
|
||||
}
|
388
libarchive/archive_write_disk_acl_linux.c
Normal file
388
libarchive/archive_write_disk_acl_linux.c
Normal file
@ -0,0 +1,388 @@
|
||||
/*-
|
||||
* 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"
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#if HAVE_ACL_LIBACL_H
|
||||
#include <acl/libacl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#if HAVE_SYS_RICHACL_H
|
||||
#include <sys/richacl.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
#include "archive_acl_maps.h"
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
static int
|
||||
_richacl_mode_to_mask(short mode)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
if (mode & S_IROTH)
|
||||
mask |= RICHACE_POSIX_MODE_READ;
|
||||
if (mode & S_IWOTH)
|
||||
mask |= RICHACE_POSIX_MODE_WRITE;
|
||||
if (mode & S_IXOTH)
|
||||
mask |= RICHACE_POSIX_MODE_EXEC;
|
||||
|
||||
return (mask);
|
||||
}
|
||||
|
||||
static void
|
||||
_richacl_mode_to_masks(struct richacl *richacl, __LA_MODE_T mode)
|
||||
{
|
||||
richacl->a_owner_mask = _richacl_mode_to_mask((mode & 0700) >> 6);
|
||||
richacl->a_group_mask = _richacl_mode_to_mask((mode & 0070) >> 3);
|
||||
richacl->a_other_mask = _richacl_mode_to_mask(mode & 0007);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
static int
|
||||
set_richacl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
int ret;
|
||||
int e = 0;
|
||||
struct richacl *richacl = NULL;
|
||||
struct richace *richace;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
richacl = richacl_alloc(entries);
|
||||
if (richacl == NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize RichACL working storage");
|
||||
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) {
|
||||
richace = &(richacl->a_entries[e]);
|
||||
|
||||
richace->e_flags = 0;
|
||||
richace->e_mask = 0;
|
||||
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
richace->e_id = ae_uid;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
richace->e_id = ae_gid;
|
||||
richace->e_flags |= RICHACE_IDENTIFIER_GROUP;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
richace->e_flags |= RICHACE_SPECIAL_WHO;
|
||||
richace->e_id = RICHACE_OWNER_SPECIAL_ID;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
richace->e_flags |= RICHACE_SPECIAL_WHO;
|
||||
richace->e_id = RICHACE_GROUP_SPECIAL_ID;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
richace->e_flags |= RICHACE_SPECIAL_WHO;
|
||||
richace->e_id = RICHACE_EVERYONE_SPECIAL_ID;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
switch (ae_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
richace->e_type =
|
||||
RICHACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
richace->e_type =
|
||||
RICHACE_ACCESS_DENIED_ACE_TYPE;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL entry type");
|
||||
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)
|
||||
richace->e_mask |= acl_nfs4_perm_map[i].p_perm;
|
||||
}
|
||||
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if (ae_permset &
|
||||
acl_nfs4_flag_map[i].a_perm)
|
||||
richace->e_flags |= acl_nfs4_flag_map[i].p_perm;
|
||||
}
|
||||
e++;
|
||||
}
|
||||
|
||||
/* Fill RichACL masks */
|
||||
_richacl_mode_to_masks(richacl, mode);
|
||||
|
||||
if (fd >= 0) {
|
||||
if (richacl_set_fd(fd, richacl) == 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 richacl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
} else if (richacl_set_file(name, richacl) != 0) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set richacl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
richacl_free(richacl);
|
||||
return (ret);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_RICHACL */
|
||||
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
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;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
int ret;
|
||||
acl_t acl = NULL;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
|
||||
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;
|
||||
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;
|
||||
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_posix_perm_map_size; ++i) {
|
||||
if (ae_permset & acl_posix_perm_map[i].a_perm) {
|
||||
if (acl_add_perm(acl_permset,
|
||||
acl_posix_perm_map[i].p_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to add ACL permission");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fd >= 0 && ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
||||
if (acl_set_fd(fd, acl) == 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_file(name, acl_type, 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);
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
|
||||
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;
|
||||
|
||||
#if !ARCHIVE_ACL_LIBRICHACL
|
||||
(void)mode; /* UNUSED */
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_richacl(a, fd, name, abstract_acl, mode,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
else
|
||||
#endif
|
||||
#endif /* ARCHIVE_ACL_LIBRICHACL */
|
||||
#if ARCHIVE_ACL_LIBACL
|
||||
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");
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_LIBACL */
|
||||
return (ret);
|
||||
}
|
329
libarchive/archive_write_disk_acl_sunos.c
Normal file
329
libarchive/archive_write_disk_acl_sunos.c
Normal file
@ -0,0 +1,329 @@
|
||||
/*-
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer
|
||||
* in this position and unchanged.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "archive_platform.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
#include "archive_acl_maps.h"
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
int ae_requested_type, const char *tname)
|
||||
{
|
||||
aclent_t *aclent;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
ace_t *ace;
|
||||
#endif
|
||||
int cmd, e, r;
|
||||
void *aclp;
|
||||
int ret;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
int perm_map_size;
|
||||
const acl_perm_map_t *perm_map;
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
int entries;
|
||||
int i;
|
||||
|
||||
ret = ARCHIVE_OK;
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
|
||||
switch (ae_requested_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
|
||||
cmd = SETACL;
|
||||
aclp = malloc(entries * sizeof(aclent_t));
|
||||
break;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
|
||||
cmd = ACE_SETACL;
|
||||
aclp = malloc(entries * sizeof(ace_t));
|
||||
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = ENOENT;
|
||||
archive_set_error(a, errno, "Unsupported ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
if (aclp == NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Can't allocate memory for acl buffer");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
e = 0;
|
||||
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
aclent = NULL;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
ace = NULL;
|
||||
#endif
|
||||
if (cmd == SETACL) {
|
||||
aclent = &((aclent_t *)aclp)[e];
|
||||
aclent->a_id = -1;
|
||||
aclent->a_type = 0;
|
||||
aclent->a_perm = 0;
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else { /* cmd == ACE_SETACL */
|
||||
ace = &((ace_t *)aclp)[e];
|
||||
ace->a_who = -1;
|
||||
ace->a_access_mask = 0;
|
||||
ace->a_flags = 0;
|
||||
}
|
||||
#endif /* ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
if (aclent != NULL) {
|
||||
aclent->a_id = ae_uid;
|
||||
aclent->a_type |= USER;
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else {
|
||||
ace->a_who = ae_uid;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
if (aclent != NULL) {
|
||||
aclent->a_id = ae_gid;
|
||||
aclent->a_type |= GROUP;
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else {
|
||||
ace->a_who = ae_gid;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= USER_OBJ;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else {
|
||||
ace->a_flags |= ACE_OWNER;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= GROUP_OBJ;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else {
|
||||
ace->a_flags |= ACE_GROUP;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= CLASS_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= OTHER_OBJ;
|
||||
break;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
if (ace != NULL)
|
||||
ace->a_flags |= ACE_EVERYONE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL tag");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
switch (ae_type) {
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
#endif
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
if (aclent == NULL)
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= ACL_DEFAULT;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unsupported ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
errno = EINVAL;
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
perm_map_size = acl_nfs4_perm_map_size;
|
||||
perm_map = acl_nfs4_perm_map;
|
||||
} else {
|
||||
#endif
|
||||
perm_map_size = acl_posix_perm_map_size;
|
||||
perm_map = acl_posix_perm_map;
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < perm_map_size; ++i) {
|
||||
if (ae_permset & perm_map[i].a_perm) {
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (ae_requested_type ==
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4)
|
||||
ace->a_access_mask |=
|
||||
perm_map[i].p_perm;
|
||||
else
|
||||
#endif
|
||||
aclent->a_perm |= perm_map[i].p_perm;
|
||||
}
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
|
||||
if (ae_permset & acl_nfs4_flag_map[i].a_perm) {
|
||||
ace->a_flags |=
|
||||
acl_nfs4_flag_map[i].p_perm;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
e++;
|
||||
}
|
||||
|
||||
/* Try restoring the ACL through 'fd' if we can. */
|
||||
if (fd >= 0) {
|
||||
if (facl(fd, cmd, entries, aclp) == 0)
|
||||
ret = ARCHIVE_OK;
|
||||
else {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set acl on fd: %s", tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
} else if (acl(name, cmd, entries, aclp) != 0) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
} else {
|
||||
archive_set_error(a, errno, "Failed to set acl: %s",
|
||||
tname);
|
||||
ret = ARCHIVE_WARN;
|
||||
}
|
||||
}
|
||||
exit_free:
|
||||
free(aclp);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode)
|
||||
{
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
(void)mode; /* UNUSED */
|
||||
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
/* Solaris writes POSIX.1e access and default ACLs together */
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
|
||||
|
||||
/* Simultaneous POSIX.1e and NFSv4 is not supported */
|
||||
return (ret);
|
||||
}
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else if ((archive_acl_types(abstract_acl) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
}
|
||||
#endif
|
||||
return (ret);
|
||||
}
|
@ -575,10 +575,55 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
||||
if (a->flags & ARCHIVE_EXTRACT_TIME)
|
||||
a->todo |= TODO_TIMES;
|
||||
if (a->flags & ARCHIVE_EXTRACT_ACL) {
|
||||
#if ARCHIVE_ACL_DARWIN
|
||||
/*
|
||||
* On MacOS, platform ACLs get stored in mac_metadata, too.
|
||||
* If we intend to extract mac_metadata and it is present
|
||||
* we skip extracting libarchive NFSv4 ACLs.
|
||||
*/
|
||||
size_t metadata_size;
|
||||
|
||||
if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 ||
|
||||
archive_entry_mac_metadata(a->entry,
|
||||
&metadata_size) == NULL || metadata_size == 0)
|
||||
#endif
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
/*
|
||||
* RichACLs are stored in an extended attribute.
|
||||
* If we intend to extract extended attributes and have this
|
||||
* attribute we skip extracting libarchive NFSv4 ACLs.
|
||||
*/
|
||||
short extract_acls = 1;
|
||||
if (a->flags & ARCHIVE_EXTRACT_XATTR && (
|
||||
archive_entry_acl_types(a->entry) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4)) {
|
||||
const char *attr_name;
|
||||
const void *attr_value;
|
||||
size_t attr_size;
|
||||
int i = archive_entry_xattr_reset(a->entry);
|
||||
while (i--) {
|
||||
archive_entry_xattr_next(a->entry, &attr_name,
|
||||
&attr_value, &attr_size);
|
||||
if (attr_name != NULL && attr_value != NULL &&
|
||||
attr_size > 0 && strcmp(attr_name,
|
||||
"trusted.richacl") == 0) {
|
||||
extract_acls = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (extract_acls)
|
||||
#endif
|
||||
#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
|
||||
{
|
||||
#endif
|
||||
if (archive_entry_filetype(a->entry) == AE_IFDIR)
|
||||
a->deferred |= TODO_ACLS;
|
||||
else
|
||||
a->todo |= TODO_ACLS;
|
||||
#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) {
|
||||
if (archive_entry_filetype(a->entry) == AE_IFDIR)
|
||||
@ -1703,25 +1748,11 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
*/
|
||||
if (a->todo & TODO_ACLS) {
|
||||
int r2;
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
/*
|
||||
* On Mac OS, platform ACLs are stored also in mac_metadata by
|
||||
* the operating system. If mac_metadata is present it takes
|
||||
* precedence and we skip extracting libarchive NFSv4 ACLs
|
||||
*/
|
||||
const void *metadata;
|
||||
size_t metadata_size;
|
||||
metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
|
||||
if ((a->todo & TODO_MAC_METADATA) == 0 ||
|
||||
metadata == NULL || metadata_size == 0) {
|
||||
#endif
|
||||
r2 = archive_write_disk_set_acls(&a->archive, a->fd,
|
||||
archive_entry_pathname(a->entry),
|
||||
archive_entry_acl(a->entry));
|
||||
archive_entry_acl(a->entry),
|
||||
archive_entry_mode(a->entry));
|
||||
if (r2 < ret) ret = r2;
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
finish_metadata:
|
||||
@ -2293,13 +2324,8 @@ _archive_write_disk_close(struct archive *_a)
|
||||
if (p->fixup & TODO_MODE_BASE)
|
||||
chmod(p->name, p->mode);
|
||||
if (p->fixup & TODO_ACLS)
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
if ((p->fixup & TODO_MAC_METADATA) == 0 ||
|
||||
p->mac_metadata == NULL ||
|
||||
p->mac_metadata_size == 0)
|
||||
#endif
|
||||
archive_write_disk_set_acls(&a->archive,
|
||||
-1, p->name, &p->acl);
|
||||
archive_write_disk_set_acls(&a->archive, -1, p->name,
|
||||
&p->acl, p->mode);
|
||||
if (p->fixup & TODO_FFLAGS)
|
||||
set_fflags_platform(a, -1, p->name,
|
||||
p->mode, p->fflags_set, 0);
|
||||
@ -4239,5 +4265,19 @@ older(struct stat *st, struct archive_entry *entry)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef ARCHIVE_ACL_SUPPORT
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl, __LA_MODE_T mode)
|
||||
{
|
||||
(void)a; /* UNUSED */
|
||||
(void)fd; /* UNUSED */
|
||||
(void)name; /* UNUSED */
|
||||
(void)abstract_acl; /* UNUSED */
|
||||
(void)mode; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_WIN32 || __CYGWIN__ */
|
||||
|
||||
|
@ -33,11 +33,13 @@
|
||||
#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
|
||||
#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
|
||||
|
||||
#include "archive_platform_acl.h"
|
||||
#include "archive_acl_private.h"
|
||||
#include "archive_entry.h"
|
||||
|
||||
struct archive_write_disk;
|
||||
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *, int /* fd */, const char * /* pathname */, struct archive_acl *);
|
||||
int archive_write_disk_set_acls(struct archive *, int, const char *,
|
||||
struct archive_acl *, __LA_MODE_T);
|
||||
|
||||
#endif
|
||||
|
@ -48,7 +48,7 @@ Leading whitespace is always ignored.
|
||||
.Pp
|
||||
When encoding file or pathnames, any backslash character or
|
||||
character outside of the 95 printable ASCII characters must be
|
||||
encoded as a a backslash followed by three
|
||||
encoded as a backslash followed by three
|
||||
octal digits.
|
||||
When reading mtree files, any appearance of a backslash
|
||||
followed by three octal digits should be converted into the
|
||||
|
@ -26,15 +26,18 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
|
||||
#if ARCHIVE_ACL_NFS4
|
||||
#if HAVE_SYS_ACL_H
|
||||
#define _ACL_PRIVATE
|
||||
#include <sys/acl.h>
|
||||
#if HAVE_DARWIN_ACL
|
||||
#endif
|
||||
#if HAVE_SYS_RICHACL_H
|
||||
#include <sys/richacl.h>
|
||||
#endif
|
||||
#if HAVE_MEMBERSHIP_H
|
||||
#include <membership.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_NFS4_ACL
|
||||
struct myacl_t {
|
||||
int type;
|
||||
int permset;
|
||||
@ -44,7 +47,7 @@ struct myacl_t {
|
||||
};
|
||||
|
||||
static struct myacl_t acls_reg[] = {
|
||||
#if !HAVE_DARWIN_ACL
|
||||
#if !ARCHIVE_ACL_DARWIN
|
||||
/* For this test, we need the file owner to be able to read and write the ACL. */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
|
||||
@ -91,7 +94,7 @@ static struct myacl_t acls_reg[] = {
|
||||
// ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" },
|
||||
#if !HAVE_DARWIN_ACL
|
||||
#if !ARCHIVE_ACL_DARWIN
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
@ -134,7 +137,7 @@ static const int acls_reg_cnt = (int)(sizeof(acls_reg)/sizeof(acls_reg[0]));
|
||||
|
||||
static struct myacl_t acls_dir[] = {
|
||||
/* For this test, we need to be able to read and write the ACL. */
|
||||
#if !HAVE_DARWIN_ACL
|
||||
#if !ARCHIVE_ACL_DARWIN
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
|
||||
#endif
|
||||
@ -180,13 +183,17 @@ static struct myacl_t acls_dir[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
|
||||
ARCHIVE_ENTRY_ACL_USER, 302, "user302" },
|
||||
#if 0
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
|
||||
ARCHIVE_ENTRY_ACL_USER, 303, "user303" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
|
||||
ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
|
||||
#if !defined(ARCHIVE_ACL_SUNOS_NFS4) || defined(ACE_INHERITED_ACE)
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
|
||||
ARCHIVE_ENTRY_ACL_USER, 305, "user305" },
|
||||
@ -207,7 +214,7 @@ static struct myacl_t acls_dir[] = {
|
||||
ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
|
||||
#if !HAVE_DARWIN_ACL
|
||||
#if !ARCHIVE_ACL_DARWIN
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
@ -254,7 +261,7 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
|
||||
int i;
|
||||
|
||||
archive_entry_acl_clear(ae);
|
||||
#if !HAVE_DARWIN_ACL
|
||||
#if !ARCHIVE_ACL_DARWIN
|
||||
if (start > 0) {
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_add_entry(ae,
|
||||
@ -271,78 +278,96 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
|
||||
}
|
||||
|
||||
static int
|
||||
#ifdef HAVE_SUN_NFS4_ACL
|
||||
acl_permset_to_bitmap(uint32_t a_access_mask)
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
acl_permset_to_bitmap(uint32_t mask)
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
acl_permset_to_bitmap(unsigned int mask)
|
||||
#else
|
||||
acl_permset_to_bitmap(acl_permset_t opaque_ps)
|
||||
#endif
|
||||
{
|
||||
static struct { int machine; int portable; } perms[] = {
|
||||
#ifdef HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL permissions */
|
||||
{ACE_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
|
||||
{ACE_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
|
||||
{ACE_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
|
||||
{ACE_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
|
||||
{ACE_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
|
||||
{ACE_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
|
||||
{ACE_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
|
||||
{ACE_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
|
||||
{ACE_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
|
||||
{ACE_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
|
||||
{ACE_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
|
||||
{ACE_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
|
||||
{ACE_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
|
||||
{ACE_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
|
||||
{ACE_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
|
||||
{ACE_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
|
||||
{ACE_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
|
||||
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL permissions */
|
||||
{ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
|
||||
{ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
|
||||
{ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
|
||||
{ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
|
||||
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
|
||||
{ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
|
||||
{ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
|
||||
{ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
|
||||
{ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
|
||||
{ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
|
||||
{ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
|
||||
{ACL_READ_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
|
||||
{ACL_WRITE_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
|
||||
{ACL_READ_SECURITY, ARCHIVE_ENTRY_ACL_READ_ACL},
|
||||
{ACL_WRITE_SECURITY, ARCHIVE_ENTRY_ACL_WRITE_ACL},
|
||||
{ACL_CHANGE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
|
||||
static struct { int portable; int machine; } perms[] = {
|
||||
#ifdef ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
|
||||
#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
|
||||
#if HAVE_DECL_ACL_SYNCHRONIZE
|
||||
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE}
|
||||
#else /* FreeBSD NFSv4 ACL permissions */
|
||||
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
|
||||
{ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
|
||||
{ACL_READ, ARCHIVE_ENTRY_ACL_READ},
|
||||
{ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
|
||||
{ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
|
||||
{ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
|
||||
{ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
|
||||
{ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
|
||||
{ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
|
||||
{ACL_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
|
||||
{ACL_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
|
||||
{ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
|
||||
{ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
|
||||
{ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
|
||||
{ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
|
||||
{ACL_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
|
||||
{ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
|
||||
{ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
|
||||
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
};
|
||||
int i, permset = 0;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
if (a_access_mask & perms[i].machine)
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL
|
||||
if (mask & perms[i].machine)
|
||||
#else
|
||||
if (acl_get_perm_np(opaque_ps, perms[i].machine))
|
||||
#endif
|
||||
@ -351,90 +376,70 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
|
||||
}
|
||||
|
||||
static int
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
acl_flagset_to_bitmap(uint16_t a_flags)
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
acl_flagset_to_bitmap(uint16_t flags)
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
acl_flagset_to_bitmap(int flags)
|
||||
#else
|
||||
acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
|
||||
#endif
|
||||
{
|
||||
static struct { int machine; int portable; } flags[] = {
|
||||
#if HAVE_SUN_NFS4_ACL /* Solaris NFSv4 ACL inheritance flags */
|
||||
{ACE_FILE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
|
||||
{ACE_DIRECTORY_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ACE_NO_PROPAGATE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ACE_INHERIT_ONLY_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
|
||||
{ACE_SUCCESSFUL_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ACE_FAILED_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
|
||||
static struct { int portable; int machine; } perms[] = {
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
|
||||
#ifdef ACE_INHERITED_ACE
|
||||
{ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
|
||||
#endif
|
||||
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL inheritance flags */
|
||||
{ACL_ENTRY_INHERITED, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED},
|
||||
{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
|
||||
{ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ACL_ENTRY_LIMIT_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ACL_ENTRY_ONLY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY}
|
||||
#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE}
|
||||
#else /* FreeBSD NFSv4 ACL inheritance flags */
|
||||
{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
|
||||
{ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ACL_ENTRY_SUCCESSFUL_ACCESS, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
|
||||
{ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}
|
||||
#endif
|
||||
};
|
||||
int i, flagset = 0;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
if (a_flags & flags[i].machine)
|
||||
for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL
|
||||
if (flags & perms[i].machine)
|
||||
#else
|
||||
if (acl_get_flag_np(opaque_fs, flags[i].machine))
|
||||
if (acl_get_flag_np(opaque_fs, perms[i].machine))
|
||||
#endif
|
||||
flagset |= flags[i].portable;
|
||||
flagset |= perms[i].portable;
|
||||
return flagset;
|
||||
}
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
static int
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
acl_match(ace_t *ace, struct myacl_t *myacl)
|
||||
#else
|
||||
acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
#endif
|
||||
{
|
||||
#if !HAVE_SUN_NFS4_ACL
|
||||
#if HAVE_DARWIN_ACL
|
||||
void *q;
|
||||
uid_t ugid;
|
||||
int r, idtype;
|
||||
#else
|
||||
gid_t g, *gp;
|
||||
uid_t u, *up;
|
||||
acl_entry_type_t entry_type;
|
||||
#endif /* !HAVE_DARWIN_ACL */
|
||||
acl_tag_t tag_type;
|
||||
acl_permset_t opaque_ps;
|
||||
acl_flagset_t opaque_fs;
|
||||
#endif /* !HAVE_SUN_NFS4_ACL */
|
||||
int perms;
|
||||
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags);
|
||||
#else
|
||||
acl_get_tag_type(aclent, &tag_type);
|
||||
#if !HAVE_DARWIN_ACL
|
||||
acl_get_entry_type_np(aclent, &entry_type);
|
||||
#endif
|
||||
|
||||
/* translate the silly opaque permset to a bitmap */
|
||||
acl_get_permset(aclent, &opaque_ps);
|
||||
acl_get_flagset_np(aclent, &opaque_fs);
|
||||
perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
|
||||
#endif
|
||||
if (perms != myacl->permset)
|
||||
return (0);
|
||||
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
switch (ace->a_type) {
|
||||
case ACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
@ -476,7 +481,85 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
if ((uid_t)myacl->qual != ace->a_who)
|
||||
return (0);
|
||||
}
|
||||
#elif HAVE_DARWIN_ACL
|
||||
return (1);
|
||||
}
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
static int
|
||||
acl_match(struct richace *richace, struct myacl_t *myacl)
|
||||
{
|
||||
int perms;
|
||||
|
||||
perms = acl_permset_to_bitmap(richace->e_mask) |
|
||||
acl_flagset_to_bitmap(richace->e_flags);
|
||||
|
||||
if (perms != myacl->permset)
|
||||
return (0);
|
||||
|
||||
switch (richace->e_type) {
|
||||
case RICHACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
return (0);
|
||||
break;
|
||||
case RICHACE_ACCESS_DENIED_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (richace->e_flags & RICHACE_SPECIAL_WHO) {
|
||||
switch (richace->e_id) {
|
||||
case RICHACE_OWNER_SPECIAL_ID:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
return (0);
|
||||
break;
|
||||
case RICHACE_GROUP_SPECIAL_ID:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
return (0);
|
||||
break;
|
||||
case RICHACE_EVERYONE_SPECIAL_ID:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
/* Invalid e_id */
|
||||
return (0);
|
||||
}
|
||||
} else if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
|
||||
return (0);
|
||||
if ((gid_t)myacl->qual != richace->e_id)
|
||||
return (0);
|
||||
} else {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
|
||||
return (0);
|
||||
if ((uid_t)myacl->qual != richace->e_id)
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
#elif ARCHIVE_ACL_DARWIN
|
||||
static int
|
||||
acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
{
|
||||
void *q;
|
||||
uid_t ugid;
|
||||
int r, idtype;
|
||||
acl_tag_t tag_type;
|
||||
acl_permset_t opaque_ps;
|
||||
acl_flagset_t opaque_fs;
|
||||
int perms;
|
||||
|
||||
acl_get_tag_type(aclent, &tag_type);
|
||||
|
||||
/* translate the silly opaque permset to a bitmap */
|
||||
acl_get_permset(aclent, &opaque_ps);
|
||||
acl_get_flagset_np(aclent, &opaque_fs);
|
||||
perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
|
||||
if (perms != myacl->permset)
|
||||
return (0);
|
||||
|
||||
r = 0;
|
||||
switch (tag_type) {
|
||||
case ACL_EXTENDED_ALLOW:
|
||||
@ -513,7 +596,30 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
#else /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
|
||||
return (1);
|
||||
}
|
||||
#else /* ARCHIVE_ACL_FREEBSD_NFS4 */
|
||||
static int
|
||||
acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
{
|
||||
gid_t g, *gp;
|
||||
uid_t u, *up;
|
||||
acl_entry_type_t entry_type;
|
||||
acl_tag_t tag_type;
|
||||
acl_permset_t opaque_ps;
|
||||
acl_flagset_t opaque_fs;
|
||||
int perms;
|
||||
|
||||
acl_get_tag_type(aclent, &tag_type);
|
||||
acl_get_entry_type_np(aclent, &entry_type);
|
||||
|
||||
/* translate the silly opaque permset to a bitmap */
|
||||
acl_get_permset(aclent, &opaque_ps);
|
||||
acl_get_flagset_np(aclent, &opaque_fs);
|
||||
perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
|
||||
if (perms != myacl->permset)
|
||||
return (0);
|
||||
|
||||
switch (entry_type) {
|
||||
case ACL_ENTRY_TYPE_ALLOW:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
@ -565,15 +671,17 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
|
||||
break;
|
||||
}
|
||||
#endif /* !HAVE_SUN_NFS4_ACL && !HAVE_DARWIN_ACL */
|
||||
return (1);
|
||||
}
|
||||
#endif /* various ARCHIVE_ACL_NFS4 implementations */
|
||||
|
||||
static void
|
||||
compare_acls(
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
void *aclp,
|
||||
int aclcnt,
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
struct richacl *richacl,
|
||||
#else
|
||||
acl_t acl,
|
||||
#endif
|
||||
@ -582,19 +690,40 @@ compare_acls(
|
||||
int *marker;
|
||||
int matched;
|
||||
int i, n;
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
int e;
|
||||
ace_t *acl_entry;
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
int e;
|
||||
struct richace *acl_entry;
|
||||
int aclcnt;
|
||||
#else
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
acl_entry_t acl_entry;
|
||||
#if ARCHIVE_ACL_DARWIN
|
||||
const int acl_get_entry_ret = 0;
|
||||
#else
|
||||
const int acl_get_entry_ret = 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
if (aclp == NULL)
|
||||
return;
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
if (richacl == NULL)
|
||||
return;
|
||||
aclcnt = richacl->a_count;
|
||||
#else
|
||||
if (acl == NULL)
|
||||
return;
|
||||
#endif
|
||||
|
||||
n = end - start;
|
||||
marker = malloc(sizeof(marker[0]) * (n + 1));
|
||||
for (i = 0; i < n; i++)
|
||||
marker[i] = i + start;
|
||||
#if !HAVE_DARWIN_ACL
|
||||
#if !ARCHIVE_ACL_DARWIN
|
||||
/* Always include the first ACE. */
|
||||
if (start > 0) {
|
||||
marker[n] = 0;
|
||||
@ -606,16 +735,16 @@ compare_acls(
|
||||
* Iterate over acls in system acl object, try to match each
|
||||
* one with an item in the myacls array.
|
||||
*/
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL
|
||||
for (e = 0; e < aclcnt; e++)
|
||||
#elif HAVE_DARWIN_ACL
|
||||
while (0 == acl_get_entry(acl, entry_id, &acl_entry))
|
||||
#else
|
||||
while (1 == acl_get_entry(acl, entry_id, &acl_entry))
|
||||
while (acl_get_entry_ret == acl_get_entry(acl, entry_id, &acl_entry))
|
||||
#endif
|
||||
{
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
acl_entry = &((ace_t *)aclp)[e];
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
acl_entry = &(richacl->a_entries[e]);
|
||||
#else
|
||||
/* After the first time... */
|
||||
entry_id = ACL_NEXT_ENTRY;
|
||||
@ -708,7 +837,7 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
|
||||
}
|
||||
free(marker);
|
||||
}
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
#endif /* ARCHIVE_ACL_NFS4 */
|
||||
|
||||
/*
|
||||
* Verify ACL restore-to-disk. This test is Platform-specific.
|
||||
@ -716,25 +845,27 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
|
||||
|
||||
DEFINE_TEST(test_acl_platform_nfs4)
|
||||
{
|
||||
#if !HAVE_NFS4_ACL
|
||||
#if !ARCHIVE_ACL_NFS4
|
||||
skipping("NFS4 ACLs are not supported on this platform");
|
||||
#else
|
||||
#else /* ARCHIVE_ACL_NFS4 */
|
||||
char buff[64];
|
||||
int i;
|
||||
struct stat st;
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
#if HAVE_DARWIN_ACL /* On MacOS we skip trivial ACLs in some tests */
|
||||
#if ARCHIVE_ACL_DARWIN /* On MacOS we skip trivial ACLs in some tests */
|
||||
const int regcnt = acls_reg_cnt - 4;
|
||||
const int dircnt = acls_dir_cnt - 4;
|
||||
#else
|
||||
const int regcnt = acls_reg_cnt;
|
||||
const int dircnt = acls_dir_cnt;
|
||||
#endif
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
void *aclp;
|
||||
int aclcnt;
|
||||
#else /* !HAVE_SUN_NFS4_ACL */
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
struct richacl *richacl;
|
||||
#else /* !ARCHIVE_ACL_SUNOS_NFS4 */
|
||||
acl_t acl;
|
||||
#endif
|
||||
|
||||
@ -790,23 +921,33 @@ DEFINE_TEST(test_acl_platform_nfs4)
|
||||
/* Verify the data on disk. */
|
||||
assertEqualInt(0, stat("testall", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "testall");
|
||||
failure("acl(): errno = %d (%s)", errno, strerror(errno));
|
||||
failure("acl(\"%s\"): errno = %d (%s)", "testall", errno,
|
||||
strerror(errno));
|
||||
assert(aclp != NULL);
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
richacl = richacl_get_file("testall");
|
||||
failure("richacl_get_file(\"%s\"): errno = %d (%s)", "testall", errno,
|
||||
strerror(errno));
|
||||
assert(richacl != NULL);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
#if ARCHIVE_ACL_DARWIN
|
||||
acl = acl_get_file("testall", ACL_TYPE_EXTENDED);
|
||||
#else
|
||||
acl = acl_get_file("testall", ACL_TYPE_NFS4);
|
||||
#endif
|
||||
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
|
||||
failure("acl_get_file(\"%s\"): errno = %d (%s)", "testall", errno,
|
||||
strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
#endif
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
compare_acls(aclp, aclcnt, acls_reg, "testall", 0, regcnt);
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
compare_acls(richacl, acls_reg, "testall", 0, regcnt);
|
||||
richacl_free(richacl);
|
||||
#else
|
||||
compare_acls(acl, acls_reg, "testall", 0, regcnt);
|
||||
acl_free(acl);
|
||||
@ -818,24 +959,37 @@ DEFINE_TEST(test_acl_platform_nfs4)
|
||||
sprintf(buff, "dir%d", i);
|
||||
assertEqualInt(0, stat(buff, &st));
|
||||
assertEqualInt(st.st_mtime, 123456 + i);
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, buff);
|
||||
failure("acl(): errno = %d (%s)", errno, strerror(errno));
|
||||
failure("acl(\"%s\"): errno = %d (%s)", buff, errno,
|
||||
strerror(errno));
|
||||
assert(aclp != NULL);
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
richacl = richacl_get_file(buff);
|
||||
/* First and last two dir do not return a richacl */
|
||||
if ((i == 0 || i >= dircnt - 2) && richacl == NULL &&
|
||||
errno == ENODATA)
|
||||
continue;
|
||||
failure("richacl_get_file(\"%s\"): errno = %d (%s)", buff,
|
||||
errno, strerror(errno));
|
||||
assert(richacl != NULL);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
#if ARCHIVE_ACL_DARWIN
|
||||
acl = acl_get_file(buff, ACL_TYPE_EXTENDED);
|
||||
#else
|
||||
acl = acl_get_file(buff, ACL_TYPE_NFS4);
|
||||
#endif
|
||||
failure("acl_get_file(): errno = %d (%s)", errno,
|
||||
failure("acl_get_file(\"%s\"): errno = %d (%s)", buff, errno,
|
||||
strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
#endif
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
compare_acls(aclp, aclcnt, acls_dir, buff, i, i + 1);
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
compare_acls(richacl, acls_dir, buff, i, i + 1);
|
||||
richacl_free(richacl);
|
||||
#else
|
||||
compare_acls(acl, acls_dir, buff, i, i + 1);
|
||||
acl_free(acl);
|
||||
@ -845,23 +999,33 @@ DEFINE_TEST(test_acl_platform_nfs4)
|
||||
/* Verify "dirall" on disk. */
|
||||
assertEqualInt(0, stat("dirall", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "dirall");
|
||||
failure("acl(): errno = %d (%s)", errno, strerror(errno));
|
||||
failure("acl(\"%s\"): errno = %d (%s)", "dirall", errno,
|
||||
strerror(errno));
|
||||
assert(aclp != NULL);
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
richacl = richacl_get_file("dirall");
|
||||
failure("richacl_get_file(\"%s\"): errno = %d (%s)", "dirall",
|
||||
errno, strerror(errno));
|
||||
assert(richacl != NULL);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
#if ARCHIVE_ACL_DARWIN
|
||||
acl = acl_get_file("dirall", ACL_TYPE_EXTENDED);
|
||||
#else
|
||||
acl = acl_get_file("dirall", ACL_TYPE_NFS4);
|
||||
#endif
|
||||
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
|
||||
failure("acl_get_file(\"%s\"): errno = %d (%s)", "dirall", errno,
|
||||
strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
#endif
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
compare_acls(aclp, aclcnt, acls_dir, "dirall", 0, dircnt);
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
compare_acls(richacl, acls_dir, "dirall", 0, dircnt);
|
||||
richacl_free(richacl);
|
||||
#else
|
||||
compare_acls(acl, acls_dir, "dirall", 0, dircnt);
|
||||
acl_free(acl);
|
||||
@ -890,5 +1054,5 @@ DEFINE_TEST(test_acl_platform_nfs4)
|
||||
compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt);
|
||||
archive_entry_free(ae);
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
#endif /* ARCHIVE_ACL_NFS4 */
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $");
|
||||
|
||||
#if HAVE_POSIX_ACL || HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_POSIX1E
|
||||
#include <sys/acl.h>
|
||||
#if HAVE_ACL_GET_PERM
|
||||
#include <acl/libacl.h>
|
||||
@ -55,18 +55,18 @@ static struct archive_test_acl_t acls2[] = {
|
||||
};
|
||||
|
||||
static int
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
acl_entry_get_perm(aclent_t *aclent)
|
||||
#else
|
||||
acl_entry_get_perm(acl_entry_t aclent)
|
||||
#endif
|
||||
{
|
||||
int permset = 0;
|
||||
#if HAVE_POSIX_ACL
|
||||
#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL
|
||||
acl_permset_t opaque_ps;
|
||||
#endif
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
if (aclent->a_perm & 1)
|
||||
permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
if (aclent->a_perm & 2)
|
||||
@ -127,114 +127,108 @@ acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_ta
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
static int
|
||||
#if HAVE_SUN_ACL
|
||||
acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl)
|
||||
#else
|
||||
acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_POSIX_ACL
|
||||
gid_t g, *gp;
|
||||
uid_t u, *up;
|
||||
acl_tag_t tag_type;
|
||||
#endif
|
||||
|
||||
if (myacl->permset != acl_entry_get_perm(aclent))
|
||||
return (0);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
switch (aclent->a_type)
|
||||
#else
|
||||
acl_get_tag_type(aclent, &tag_type);
|
||||
switch (tag_type)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
switch (aclent->a_type) {
|
||||
case DEF_USER_OBJ:
|
||||
case USER_OBJ:
|
||||
#else
|
||||
case ACL_USER_OBJ:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_USER:
|
||||
case USER:
|
||||
#else
|
||||
case ACL_USER:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
|
||||
return (0);
|
||||
#if HAVE_SUN_ACL
|
||||
if ((uid_t)myacl->qual != aclent->a_id)
|
||||
return (0);
|
||||
#else
|
||||
up = acl_get_qualifier(aclent);
|
||||
u = *up;
|
||||
acl_free(up);
|
||||
if ((uid_t)myacl->qual != u)
|
||||
return (0);
|
||||
#endif
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_GROUP_OBJ:
|
||||
case GROUP_OBJ:
|
||||
#else
|
||||
case ACL_GROUP_OBJ:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_GROUP:
|
||||
case GROUP:
|
||||
#else
|
||||
case ACL_GROUP:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
|
||||
return (0);
|
||||
#if HAVE_SUN_ACL
|
||||
if ((gid_t)myacl->qual != aclent->a_id)
|
||||
return (0);
|
||||
#else
|
||||
gp = acl_get_qualifier(aclent);
|
||||
g = *gp;
|
||||
acl_free(gp);
|
||||
if ((gid_t)myacl->qual != g)
|
||||
return (0);
|
||||
#endif
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_CLASS_OBJ:
|
||||
case CLASS_OBJ:
|
||||
#else
|
||||
case ACL_MASK:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_OTHER_OBJ:
|
||||
case OTHER_OBJ:
|
||||
#else
|
||||
case ACL_OTHER:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0);
|
||||
break;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
#if HAVE_SUN_ACL
|
||||
compare_acls(void *aclp, int aclcnt, struct archive_test_acl_t *myacls, int n)
|
||||
#else
|
||||
compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
#else /* ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL */
|
||||
static int
|
||||
acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
|
||||
{
|
||||
gid_t g, *gp;
|
||||
uid_t u, *up;
|
||||
acl_tag_t tag_type;
|
||||
|
||||
if (myacl->permset != acl_entry_get_perm(aclent))
|
||||
return (0);
|
||||
|
||||
acl_get_tag_type(aclent, &tag_type);
|
||||
switch (tag_type) {
|
||||
case ACL_USER_OBJ:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
|
||||
break;
|
||||
case ACL_USER:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
|
||||
return (0);
|
||||
up = acl_get_qualifier(aclent);
|
||||
u = *up;
|
||||
acl_free(up);
|
||||
if ((uid_t)myacl->qual != u)
|
||||
return (0);
|
||||
break;
|
||||
case ACL_GROUP_OBJ:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
|
||||
break;
|
||||
case ACL_GROUP:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
|
||||
return (0);
|
||||
gp = acl_get_qualifier(aclent);
|
||||
g = *gp;
|
||||
acl_free(gp);
|
||||
if ((gid_t)myacl->qual != g)
|
||||
return (0);
|
||||
break;
|
||||
case ACL_MASK:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
|
||||
break;
|
||||
case ACL_OTHER:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0);
|
||||
break;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
compare_acls(
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
void *aclp, int aclcnt,
|
||||
#else
|
||||
acl_t acl,
|
||||
#endif
|
||||
struct archive_test_acl_t *myacls, int n)
|
||||
{
|
||||
int *marker;
|
||||
int matched;
|
||||
int i;
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
int e;
|
||||
aclent_t *acl_entry;
|
||||
#else
|
||||
@ -253,7 +247,7 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
* Iterate over acls in system acl object, try to match each
|
||||
* one with an item in the myacls array.
|
||||
*/
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
for(e = 0; e < aclcnt; e++) {
|
||||
acl_entry = &((aclent_t *)aclp)[e];
|
||||
#else
|
||||
@ -288,23 +282,21 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
}
|
||||
free(marker);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Verify ACL restore-to-disk. This test is Platform-specific.
|
||||
*/
|
||||
|
||||
DEFINE_TEST(test_acl_platform_posix1e_restore)
|
||||
{
|
||||
#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
|
||||
#if !ARCHIVE_ACL_POSIX1E
|
||||
skipping("POSIX.1e ACLs are not supported on this platform");
|
||||
#else /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
|
||||
#else /* ARCHIVE_ACL_POSIX1E */
|
||||
struct stat st;
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
void *aclp;
|
||||
int aclcnt;
|
||||
#else
|
||||
@ -340,7 +332,7 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
|
||||
/* Verify the data on disk. */
|
||||
assertEqualInt(0, stat("test0", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
aclp = sunacl_get(GETACL, &aclcnt, 0, "test0");
|
||||
failure("acl(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert(aclp != NULL);
|
||||
@ -349,7 +341,7 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
|
||||
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
#endif
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
compare_acls(aclp, aclcnt, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
free(aclp);
|
||||
aclp = NULL;
|
||||
@ -358,7 +350,7 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
|
||||
acl_free(acl);
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
|
||||
#endif /* ARCHIVE_ACL_POSIX1E */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -366,15 +358,15 @@ DEFINE_TEST(test_acl_platform_posix1e_restore)
|
||||
*/
|
||||
DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
{
|
||||
#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
|
||||
#if !ARCHIVE_ACL_POSIX1E
|
||||
skipping("POSIX.1e ACLs are not supported on this platform");
|
||||
#else
|
||||
#else /* ARCHIVE_ACL_POSIX1E */
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
int n, fd, flags, dflags;
|
||||
char *func, *acl_text;
|
||||
const char *acl1_text, *acl2_text, *acl3_text;
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
void *aclp;
|
||||
int aclcnt;
|
||||
#else
|
||||
@ -388,7 +380,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
*/
|
||||
|
||||
/* Create a test file f1 with acl1 */
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
acl1_text = "user::rwx,"
|
||||
"group::rwx,"
|
||||
"other:rwx,"
|
||||
@ -417,12 +409,12 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
failure("Could not create test file?!");
|
||||
if (!assert(fd >= 0)) {
|
||||
#if !HAVE_SUN_ACL
|
||||
#if !ARCHIVE_ACL_SUNOS
|
||||
acl_free(acl1);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
/* Check if Solaris filesystem supports POSIX.1e ACLs */
|
||||
aclp = sunacl_get(GETACL, &aclcnt, fd, NULL);
|
||||
if (aclp == 0)
|
||||
@ -440,12 +432,12 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
func = "acl_set_fd()";
|
||||
n = acl_set_fd(fd, acl1);
|
||||
#endif
|
||||
#if !HAVE_SUN_ACL
|
||||
#if !ARCHIVE_ACL_SUNOS
|
||||
acl_free(acl1);
|
||||
#endif
|
||||
|
||||
if (n != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
if (errno == ENOSYS || errno == ENOTSUP)
|
||||
#else
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL)
|
||||
@ -474,7 +466,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
* to read ACLs, resulting in reading the ACL from a like-named
|
||||
* file in the wrong directory.
|
||||
*/
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
acl2_text = "user::rwx,"
|
||||
"group::rwx,"
|
||||
"other:---,"
|
||||
@ -503,12 +495,12 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
failure("Could not create test file?!");
|
||||
if (!assert(fd >= 0)) {
|
||||
#if !HAVE_SUN_ACL
|
||||
#if !ARCHIVE_ACL_SUNOS
|
||||
acl_free(acl2);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
func = "facl()";
|
||||
n = facl(fd, SETACL, (int)(sizeof(aclp2) / sizeof(aclp2[0])), aclp2);
|
||||
#else
|
||||
@ -525,7 +517,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
/* Create nested directory d2 with default ACLs */
|
||||
assertMakeDir("d/d2", 0755);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
acl3_text = "user::rwx,"
|
||||
"group::r-x,"
|
||||
"other:r-x,"
|
||||
@ -564,7 +556,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
assert((void *)acl3 != NULL);
|
||||
#endif
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
func = "acl()";
|
||||
n = acl("d/d2", SETACL, (int)(sizeof(aclp3) / sizeof(aclp3[0])), aclp3);
|
||||
#else
|
||||
@ -580,7 +572,7 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
|
||||
assert(NULL != (ae = archive_entry_new()));
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E
|
||||
| ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA
|
||||
| ARCHIVE_ENTRY_ACL_STYLE_SOLARIS;
|
||||
@ -610,5 +602,5 @@ DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
|
||||
archive_entry_free(ae);
|
||||
assertEqualInt(ARCHIVE_OK, archive_free(a));
|
||||
#endif
|
||||
#endif /* ARCHIVE_ACL_POSIX1E */
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ This option suppresses these behaviors.
|
||||
(x mode only)
|
||||
Preserve file permissions.
|
||||
Attempt to restore the full permissions, including owner, file modes, ACLs,
|
||||
extended atributes and extended file flags, if available, for each item
|
||||
extended attributes and extended file flags, if available, for each item
|
||||
extracted from the archive. This is te reverse of
|
||||
.Fl Fl no-same-permissions
|
||||
and the default if
|
||||
|
@ -74,9 +74,14 @@ IF(ENABLE_TAR AND ENABLE_TEST)
|
||||
#
|
||||
ADD_EXECUTABLE(bsdtar_test ${bsdtar_test_SOURCES})
|
||||
IF(ENABLE_ACL)
|
||||
SET(TEST_ACL_LIBS "")
|
||||
IF(HAVE_LIBACL)
|
||||
TARGET_LINK_LIBRARIES(bsdtar_test ${ACL_LIBRARY})
|
||||
LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBACL)
|
||||
IF(HAVE_LIBRICHACL)
|
||||
LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY})
|
||||
ENDIF(HAVE_LIBRICHACL)
|
||||
TARGET_LINK_LIBRARIES(bsdtar_test ${TEST_ACL_LIBS})
|
||||
ENDIF(ENABLE_ACL)
|
||||
SET_PROPERTY(TARGET bsdtar_test PROPERTY COMPILE_DEFINITIONS LIST_H)
|
||||
|
||||
|
@ -73,8 +73,6 @@ static const acl_perm_t acl_perms[] = {
|
||||
#if HAVE_DARWIN_ACL || HAVE_FREEBSD_NFS4_ACL
|
||||
static const acl_flag_t acl_flags[] = {
|
||||
#if HAVE_DARWIN_ACL
|
||||
ACL_FLAG_DEFER_INHERIT,
|
||||
ACL_FLAG_NO_INHERIT,
|
||||
ACL_ENTRY_INHERITED,
|
||||
ACL_ENTRY_FILE_INHERIT,
|
||||
ACL_ENTRY_DIRECTORY_INHERIT,
|
||||
|
@ -127,43 +127,11 @@
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
|
||||
* acl_set_file(), and ACL_USER, we assume it has the rest of the
|
||||
* POSIX.1e draft functions used in archive_read_extract.c.
|
||||
*/
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
|
||||
#if HAVE_DECL_ACL_USER
|
||||
#define HAVE_POSIX_ACL 1
|
||||
#elif HAVE_DECL_ACL_TYPE_EXTENDED
|
||||
#define HAVE_DARWIN_ACL 1
|
||||
#endif
|
||||
#if HAVE_DECL_ACL_TYPE_NFS4
|
||||
#define HAVE_FREEBSD_NFS4_ACL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
|
||||
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
|
||||
*/
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL && HAVE_FACL && HAVE_ACLENT_T && \
|
||||
HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL
|
||||
#define HAVE_SUN_ACL 1
|
||||
#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \
|
||||
HAVE_DECL_ACE_SETACL
|
||||
#define HAVE_SUN_NFS4_ACL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Define if platform supports NFSv4 ACLs */
|
||||
#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL
|
||||
#define HAVE_NFS4_ACL 1
|
||||
#endif
|
||||
|
||||
#include "archive_platform_acl.h"
|
||||
#define ARCHIVE_TEST_ACL_TYPE_POSIX1E 1
|
||||
#define ARCHIVE_TEST_ACL_TYPE_NFS4 2
|
||||
|
||||
|
||||
/*
|
||||
* Redefine DEFINE_TEST for use in defining the test functions.
|
||||
*/
|
||||
@ -378,7 +346,7 @@ int setTestAcl(const char *path);
|
||||
/* Return true if the file has large i-node number(>0xffffffff). */
|
||||
int is_LargeInode(const char *);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
/* Fetch ACLs on Solaris using acl() or facl() */
|
||||
void *sunacl_get(int cmd, int *aclcnt, int fd, const char *path);
|
||||
#endif
|
||||
|
@ -56,7 +56,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
/* ACL support */
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#endif
|
||||
#ifdef HAVE_ACL_LIBACL_H
|
||||
#include <acl/libacl.h>
|
||||
#endif
|
||||
@ -66,7 +67,10 @@
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#if HAVE_DARWIN_ACL
|
||||
#ifdef HAVE_SYS_RICHACL_H
|
||||
#include <sys/richacl.h>
|
||||
#endif
|
||||
#if HAVE_MEMBERSHIP_H
|
||||
#include <membership.h>
|
||||
#endif
|
||||
|
||||
@ -2436,7 +2440,7 @@ canNodump(void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_SUNOS
|
||||
/* Fetch ACLs on Solaris using acl() or facl() */
|
||||
void *
|
||||
sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
|
||||
@ -2449,7 +2453,7 @@ sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
|
||||
cntcmd = GETACLCNT;
|
||||
size = sizeof(aclent_t);
|
||||
}
|
||||
#if HAVE_SUN_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
||||
else if (cmd == ACE_GETACL) {
|
||||
cntcmd = ACE_GETACLCNT;
|
||||
size = sizeof(ace_t);
|
||||
@ -2492,7 +2496,7 @@ sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
|
||||
*aclcnt = cnt;
|
||||
return (aclp);
|
||||
}
|
||||
#endif /* HAVE_SUN_ACL */
|
||||
#endif /* ARCHIVE_ACL_SUNOS */
|
||||
|
||||
/*
|
||||
* Set test ACLs on a path
|
||||
@ -2504,19 +2508,22 @@ sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
|
||||
int
|
||||
setTestAcl(const char *path)
|
||||
{
|
||||
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
|
||||
#if ARCHIVE_ACL_SUPPORT
|
||||
int r = 1;
|
||||
#if !HAVE_SUN_ACL
|
||||
#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_DARWIN
|
||||
acl_t acl;
|
||||
#endif
|
||||
#if HAVE_POSIX_ACL /* Linux, FreeBSD POSIX.1e */
|
||||
#if ARCHIVE_ACL_LIBRICHACL
|
||||
struct richacl *richacl;
|
||||
#endif
|
||||
#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_FREEBSD
|
||||
const char *acltext_posix1e = "user:1:rw-,"
|
||||
"group:15:r-x,"
|
||||
"user::rwx,"
|
||||
"group::rwx,"
|
||||
"other::r-x,"
|
||||
"mask::rwx";
|
||||
#elif HAVE_SUN_ACL /* Solaris POSIX.1e */
|
||||
#elif ARCHIVE_ACL_SUNOS /* Solaris POSIX.1e */
|
||||
aclent_t aclp_posix1e[] = {
|
||||
{ USER_OBJ, -1, 4 | 2 | 1 },
|
||||
{ USER, 1, 4 | 2 },
|
||||
@ -2526,13 +2533,22 @@ setTestAcl(const char *path)
|
||||
{ OTHER_OBJ, -1, 4 | 2 | 1 }
|
||||
};
|
||||
#endif
|
||||
#if HAVE_FREEBSD_NFS4_ACL /* FreeBSD NFS4 */
|
||||
#if ARCHIVE_ACL_FREEBSD /* FreeBSD NFS4 */
|
||||
const char *acltext_nfs4 = "user:1:rwpaRcs::allow:1,"
|
||||
"group:15:rxaRcs::allow:15,"
|
||||
"owner@:rwpxaARWcCos::allow,"
|
||||
"group@:rwpxaRcs::allow,"
|
||||
"everyone@:rxaRcs::allow";
|
||||
#elif HAVE_SUN_NFS4_ACL /* Solaris NFS4 */
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
const char *acltext_nfs4 = "owner:rwpxaARWcCoS::mask,"
|
||||
"group:rwpxaRcS::mask,"
|
||||
"other:rxaRcS::mask,"
|
||||
"user:1:rwpaRcS::allow,"
|
||||
"group:15:rxaRcS::allow,"
|
||||
"owner@:rwpxaARWcCoS::allow,"
|
||||
"group@:rwpxaRcS::allow,"
|
||||
"everyone@:rxaRcS::allow";
|
||||
#elif ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFS4 */
|
||||
ace_t aclp_nfs4[] = {
|
||||
{ 1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA |
|
||||
ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | ACE_READ_ACL |
|
||||
@ -2553,7 +2569,7 @@ setTestAcl(const char *path)
|
||||
ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE,
|
||||
ACE_EVERYONE, ACE_ACCESS_ALLOWED_ACE_TYPE }
|
||||
};
|
||||
#elif HAVE_DARWIN_ACL /* Mac OS X */
|
||||
#elif ARCHIVE_ACL_DARWIN /* Mac OS X */
|
||||
acl_entry_t aclent;
|
||||
acl_permset_t permset;
|
||||
const uid_t uid = 1;
|
||||
@ -2571,14 +2587,19 @@ setTestAcl(const char *path)
|
||||
ACL_SYNCHRONIZE
|
||||
#endif
|
||||
};
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
#endif /* ARCHIVE_ACL_DARWIN */
|
||||
|
||||
#if HAVE_FREEBSD_NFS4_ACL
|
||||
#if ARCHIVE_ACL_FREEBSD
|
||||
acl = acl_from_text(acltext_nfs4);
|
||||
failure("acl_from_text() error: %s", strerror(errno));
|
||||
if (assert(acl != NULL) == 0)
|
||||
return (0);
|
||||
#elif HAVE_DARWIN_ACL
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
richacl = richacl_from_text(acltext_nfs4, NULL, NULL);
|
||||
failure("richacl_from_text() error: %s", strerror(errno));
|
||||
if (assert(richacl != NULL) == 0)
|
||||
return (0);
|
||||
#elif ARCHIVE_ACL_DARWIN
|
||||
acl = acl_init(1);
|
||||
failure("acl_init() error: %s", strerror(errno));
|
||||
if (assert(acl != NULL) == 0)
|
||||
@ -2605,33 +2626,36 @@ setTestAcl(const char *path)
|
||||
failure("acl_set_permset() error: %s", strerror(errno));
|
||||
if (assertEqualInt(r, 0) == 0)
|
||||
goto testacl_free;
|
||||
r = mbr_identifier_to_uuid(ID_TYPE_UID, &uid, sizeof(uid_t), uuid);
|
||||
failure("mbr_identifier_to_uuid() error: %s", strerror(errno));
|
||||
r = mbr_uid_to_uuid(uid, uuid);
|
||||
failure("mbr_uid_to_uuid() error: %s", strerror(errno));
|
||||
if (assertEqualInt(r, 0) == 0)
|
||||
goto testacl_free;
|
||||
r = acl_set_qualifier(aclent, uuid);
|
||||
failure("acl_set_qualifier() error: %s", strerror(errno));
|
||||
if (assertEqualInt(r, 0) == 0)
|
||||
goto testacl_free;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
#endif /* ARCHIVE_ACL_DARWIN */
|
||||
|
||||
#if HAVE_NFS4_ACL
|
||||
#if HAVE_FREEBSD_NFS4_ACL
|
||||
#if ARCHIVE_ACL_NFS4
|
||||
#if ARCHIVE_ACL_FREEBSD
|
||||
r = acl_set_file(path, ACL_TYPE_NFS4, acl);
|
||||
acl_free(acl);
|
||||
#elif HAVE_SUN_NFS4_ACL
|
||||
#elif ARCHIVE_ACL_LIBRICHACL
|
||||
r = richacl_set_file(path, richacl);
|
||||
richacl_free(richacl);
|
||||
#elif ARCHIVE_ACL_SUNOS_NFS4
|
||||
r = acl(path, ACE_SETACL,
|
||||
(int)(sizeof(aclp_nfs4)/sizeof(aclp_nfs4[0])), aclp_nfs4);
|
||||
#elif HAVE_DARWIN_ACL
|
||||
#elif ARCHIVE_ACL_DARWIN
|
||||
r = acl_set_file(path, ACL_TYPE_EXTENDED, acl);
|
||||
acl_free(acl);
|
||||
#endif
|
||||
if (r == 0)
|
||||
return (ARCHIVE_TEST_ACL_TYPE_NFS4);
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
#endif /* ARCHIVE_ACL_NFS4 */
|
||||
|
||||
#if HAVE_POSIX_ACL || HAVE_SUN_ACL
|
||||
#if HAVE_POSIX_ACL
|
||||
#if ARCHIVE_ACL_POSIX1E
|
||||
#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL
|
||||
acl = acl_from_text(acltext_posix1e);
|
||||
failure("acl_from_text() error: %s", strerror(errno));
|
||||
if (assert(acl != NULL) == 0)
|
||||
@ -2639,7 +2663,7 @@ setTestAcl(const char *path)
|
||||
|
||||
r = acl_set_file(path, ACL_TYPE_ACCESS, acl);
|
||||
acl_free(acl);
|
||||
#elif HAVE_SUN_ACL
|
||||
#elif ARCHIVE_ACL_SUNOS
|
||||
r = acl(path, SETACL,
|
||||
(int)(sizeof(aclp_posix1e)/sizeof(aclp_posix1e[0])), aclp_posix1e);
|
||||
#endif
|
||||
@ -2647,12 +2671,12 @@ setTestAcl(const char *path)
|
||||
return (ARCHIVE_TEST_ACL_TYPE_POSIX1E);
|
||||
else
|
||||
return (0);
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_SUN_ACL */
|
||||
#if HAVE_DARWIN_ACL
|
||||
#endif /* ARCHIVE_ACL_POSIX1E */
|
||||
#if ARCHIVE_ACL_DARWIN
|
||||
testacl_free:
|
||||
acl_free(acl);
|
||||
#endif
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
|
||||
#endif /* ARCHIVE_ACL_SUPPORT */
|
||||
(void)path; /* UNUSED */
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user