mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-01 12:19:28 +00:00
Update vendor/libarchive to git d77b577b2d5aa259fca06313c4940e1e61ab1e0e
Vendor changes (relevant to FreeBSD): - bugfixes, improvemens and optimizations in ACL code - NFSv4 ACLs can now be extracted from Solaris tar archives Security fixes: - cab reader: endless loop when parsing MSZIP signature (OSS-Fuzz 335) - LHA reader: heap-buffer-overflow in lha_read_file_header_1() (CVE-2017-5601) - LZ4 reader: null-pointer dereference in lz4_filter_read_legacy_stream() (OSS-Fuzz 453) - mtree reader: heap-buffer-overflow in detect_form() (OSS-Fuzz 421, 443) - WARC reader: heap-buffer-overflow in xstrpisotime() (OSS-Fuzz 382, 458) Memory leak fixes: - ACL support: free memory allocated by acl_get_qualifier() - disk writer: missing free in create_filesystem_object() - file reader: fd leak (Coverity 1016755) - gnutar writer: fix free in archive_write_gnutar_header() (Coverity 1016752) - iso 9660 reader: missing free in parse_file_info() (part. Coverity 1016754) - program reader: missing free in __archive_read_program() - program writer: missing free in __archive_write_program_free() - xar reader: missing free in xar_cleanup() - xar reader: missing frees in expat_xmlattr_setup() (Coverity 1229979-1229981) - xar writer: missing free in file_free() - zip reader: missing free in zip_read_locazip_read_local_file_header()
This commit is contained in:
parent
2a59734ec2
commit
91360634ec
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/libarchive/dist/; revision=313071
13
.travis.yml
13
.travis.yml
@ -1,6 +1,14 @@
|
||||
language: C
|
||||
sudo: required
|
||||
sudo: false
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libacl1-dev
|
||||
- libbz2-dev
|
||||
- liblzma-dev
|
||||
- libzip-dev
|
||||
- lzop
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
@ -16,8 +24,7 @@ matrix:
|
||||
compiler: gcc
|
||||
before_install:
|
||||
- if [ `uname` = "Darwin" ]; then brew update; fi
|
||||
- if [ `uname` = "Linux" ]; then sudo apt-get install -y libbz2-dev libzip-dev liblzma-dev liblzo2-dev; fi
|
||||
install:
|
||||
- if [ `uname` = "Darwin" ]; then brew install xz lzo lz4; fi
|
||||
- if [ `uname` = "Darwin" ]; then brew install xz lzop lz4; fi
|
||||
script:
|
||||
- build/ci_build.sh
|
||||
|
@ -179,13 +179,15 @@ include(CTest)
|
||||
|
||||
OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
|
||||
OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
|
||||
OPTION(ENABLE_LZMA "Enable the use of the system found LZMA library if found" ON)
|
||||
OPTION(ENABLE_ZLIB "Enable the use of the system found ZLIB library if found" ON)
|
||||
OPTION(ENABLE_BZip2 "Enable the use of the system found BZip2 library if found" ON)
|
||||
OPTION(ENABLE_LIBXML2 "Enable the use of the system found libxml2 library if found" ON)
|
||||
OPTION(ENABLE_EXPAT "Enable the use of the system found EXPAT library if found" ON)
|
||||
OPTION(ENABLE_PCREPOSIX "Enable the use of the system found PCREPOSIX library if found" ON)
|
||||
OPTION(ENABLE_LibGCC "Enable the use of the system found LibGCC library if found" ON)
|
||||
OPTION(ENABLE_LZO "Enable the use of the system LZO library if found" OFF)
|
||||
OPTION(ENABLE_LZMA "Enable the use of the system LZMA library if found" ON)
|
||||
|
||||
OPTION(ENABLE_ZLIB "Enable the use of the system ZLIB library if found" ON)
|
||||
OPTION(ENABLE_BZip2 "Enable the use of the system BZip2 library if found" ON)
|
||||
OPTION(ENABLE_LIBXML2 "Enable the use of the system libxml2 library if found" ON)
|
||||
OPTION(ENABLE_EXPAT "Enable the use of the system EXPAT library if found" ON)
|
||||
OPTION(ENABLE_PCREPOSIX "Enable the use of the system PCREPOSIX library if found" ON)
|
||||
OPTION(ENABLE_LibGCC "Enable the use of the system LibGCC library if found" ON)
|
||||
# CNG is used for encrypt/decrypt Zip archives on Windows.
|
||||
OPTION(ENABLE_CNG "Enable the use of CNG(Crypto Next Generation)" ON)
|
||||
|
||||
@ -477,15 +479,19 @@ ENDIF(LIBLZMA_FOUND)
|
||||
#
|
||||
# Find LZO2
|
||||
#
|
||||
IF (LZO2_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
SET(LZO2_FIND_QUIETLY TRUE)
|
||||
ENDIF (LZO2_INCLUDE_DIR)
|
||||
IF(ENABLE_LZO)
|
||||
IF (LZO2_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
SET(LZO2_FIND_QUIETLY TRUE)
|
||||
ENDIF (LZO2_INCLUDE_DIR)
|
||||
|
||||
FIND_PATH(LZO2_INCLUDE_DIR lzo/lzoconf.h)
|
||||
FIND_LIBRARY(LZO2_LIBRARY NAMES lzo2 liblzo2)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZO2 DEFAULT_MSG LZO2_LIBRARY LZO2_INCLUDE_DIR)
|
||||
FIND_PATH(LZO2_INCLUDE_DIR lzo/lzoconf.h)
|
||||
FIND_LIBRARY(LZO2_LIBRARY NAMES lzo2 liblzo2)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZO2 DEFAULT_MSG LZO2_LIBRARY LZO2_INCLUDE_DIR)
|
||||
ELSE(ENABLE_LZO)
|
||||
SET(LIBZMA_FOUND FALSE) # Override cached value
|
||||
ENDIF(ENABLE_LZO)
|
||||
IF(LZO2_FOUND)
|
||||
SET(HAVE_LIBLZO2 1)
|
||||
SET(HAVE_LZO_LZOCONF_H 1)
|
||||
@ -608,7 +614,7 @@ IF(ENABLE_CNG)
|
||||
ELSE(ENABLE_CNG)
|
||||
UNSET(HAVE_BCRYPT_H CACHE)
|
||||
ENDIF(ENABLE_CNG)
|
||||
# Following files need windwos.h, so we should test it after windows.h test.
|
||||
# Following files need windows.h, so we should test it after windows.h test.
|
||||
LA_CHECK_INCLUDE_FILE("wincrypt.h" HAVE_WINCRYPT_H)
|
||||
LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H)
|
||||
|
||||
@ -1605,10 +1611,29 @@ IF(ENABLE_ACL)
|
||||
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_ACL_TYPE_NFS4)
|
||||
|
||||
# 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_ACL_USER)
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/types.h>
|
||||
#include <sys/acl.h>
|
||||
int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_ACL_TYPE_EXTENDED)
|
||||
|
||||
# Solaris and derivates ACLs
|
||||
CHECK_LIBRARY_EXISTS(sec "acl_get" "" HAVE_LIBSEC)
|
||||
IF(HAVE_LIBSEC)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "sec")
|
||||
FIND_LIBRARY(SEC_LIBRARY NAMES sec)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${SEC_LIBRARY})
|
||||
ENDIF(HAVE_LIBSEC)
|
||||
#
|
||||
CHECK_TYPE_EXISTS(aclent_t "${INCLUDES}" HAVE_ACLENT_T)
|
||||
CHECK_TYPE_EXISTS(ace_t "${INCLUDES}" HAVE_ACE_T)
|
||||
CHECK_FUNCTION_EXISTS(acl_get HAVE_FACL_GET)
|
||||
CHECK_FUNCTION_EXISTS(facl_get HAVE_FACL_GET)
|
||||
CHECK_FUNCTION_EXISTS(acl_set HAVE_FACL_SET)
|
||||
CHECK_FUNCTION_EXISTS(facl_set HAVE_FACL_SET)
|
||||
ELSE(ENABLE_ACL)
|
||||
# If someone runs cmake, then disables ACL support, we need
|
||||
# to forcibly override the cached values for these.
|
||||
@ -1623,7 +1648,15 @@ ELSE(ENABLE_ACL)
|
||||
SET(HAVE_ACL_SET_FD FALSE)
|
||||
SET(HAVE_ACL_SET_FD_NP FALSE)
|
||||
SET(HAVE_ACL_SET_FILE FALSE)
|
||||
SET(HAVE_ACL_TYPE_NFS4 FALSE)
|
||||
SET(HAVE_ACL_USER FALSE)
|
||||
SET(HAVE_ACL_TYPE_EXTENDED FALSE)
|
||||
SET(HAVE_ACL_GET FALSE)
|
||||
SET(HAVE_ACLENT_T FALSE)
|
||||
SET(HAVE_ACE_T FALSE)
|
||||
SET(HAVE_FACL_GET FALSE)
|
||||
SET(HAVE_ACL_SET FALSE)
|
||||
SET(HAVE_FACL_SET FALSE)
|
||||
ENDIF(ENABLE_ACL)
|
||||
|
||||
#
|
||||
|
@ -323,10 +323,10 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/main.c \
|
||||
libarchive/test/read_open_memory.c \
|
||||
libarchive/test/test.h \
|
||||
libarchive/test/test_acl_freebsd_posix1e.c \
|
||||
libarchive/test/test_acl_freebsd_nfs4.c \
|
||||
libarchive/test/test_acl_nfs4.c \
|
||||
libarchive/test/test_acl_pax.c \
|
||||
libarchive/test/test_acl_platform_nfs4.c \
|
||||
libarchive/test/test_acl_platform_posix1e.c \
|
||||
libarchive/test/test_acl_posix1e.c \
|
||||
libarchive/test/test_acl_text.c \
|
||||
libarchive/test/test_archive_api_feature.c \
|
||||
|
4
NEWS
4
NEWS
@ -1,3 +1,7 @@
|
||||
Jan 29, 2017: Limited NFSv4 ACL support for Mac OS (Darwin)
|
||||
|
||||
Jan 10, 2017: POSIX.1e and NFSv4 ACL support for Solaris and derivates
|
||||
|
||||
Dec 27, 2016: NFSv4 ACL read and write support for pax
|
||||
Deprecated functions: archive_entry_acl_text(), archive_entry_acl_text_w()
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
ACTIONS=
|
||||
BUILD_SYSTEM="${BUILD_SYSTEM:-autotools}"
|
||||
MAKE="${MAKE:-make}"
|
||||
CMAKE="${CMAKE:-cmake}"
|
||||
CURDIR=`pwd`
|
||||
SRCDIR="${SRCDIR:-`pwd`}"
|
||||
RET=0
|
||||
@ -79,21 +81,21 @@ for action in ${ACTIONS}; do
|
||||
configure)
|
||||
case "${BUILD_SYSTEM}" in
|
||||
autotools) "${SRCDIR}/configure" ${CONFIGURE_ARGS} ;;
|
||||
cmake) cmake ${CONFIGURE_ARGS} "${SRCDIR}" ;;
|
||||
cmake) ${CMAKE} ${CONFIGURE_ARGS} "${SRCDIR}" ;;
|
||||
esac
|
||||
RET="$?"
|
||||
;;
|
||||
build)
|
||||
make ${MAKE_ARGS}
|
||||
${MAKE} ${MAKE_ARGS}
|
||||
RET="$?"
|
||||
;;
|
||||
test)
|
||||
case "${BUILD_SYSTEM}" in
|
||||
autotools)
|
||||
make ${MAKE_ARGS} check LOG_DRIVER="${SRCDIR}/build/ci_test_driver"
|
||||
${MAKE} ${MAKE_ARGS} check LOG_DRIVER="${SRCDIR}/build/ci_test_driver"
|
||||
;;
|
||||
cmake)
|
||||
make ${MAKE_ARGS} test
|
||||
${MAKE} ${MAKE_ARGS} test
|
||||
;;
|
||||
esac
|
||||
RET="$?"
|
||||
|
@ -104,8 +104,8 @@ trap "st=141; $do_exit" 13
|
||||
trap "st=143; $do_exit" 15
|
||||
|
||||
# Test script is run here.
|
||||
"$@" | tee $log_file 2>&1
|
||||
estatus=$?
|
||||
( "$@"; echo "$?" > $log_file.s ) | tee $log_file 2>&1
|
||||
estatus=`cat $log_file.s`
|
||||
|
||||
if test $enable_hard_errors = no && test $estatus -eq 99; then
|
||||
tweaked_estatus=1
|
||||
|
@ -326,6 +326,12 @@ typedef uint64_t uintmax_t;
|
||||
/* Define to 1 if you have the `acl_set_file' function. */
|
||||
#cmakedefine HAVE_ACL_SET_FILE 1
|
||||
|
||||
/* True for FreeBSD with NFSv4 ACL support */
|
||||
#cmakedefine HAVE_ACL_TYPE_NFS4 1
|
||||
|
||||
/* True for MacOS ACL support */
|
||||
#cmakedefine HAVE_ACL_TYPE_EXTENDED 1
|
||||
|
||||
/* True for systems with POSIX ACL support */
|
||||
#cmakedefine HAVE_ACL_USER 1
|
||||
|
||||
|
23
configure.ac
23
configure.ac
@ -379,9 +379,9 @@ if test "x$with_lzma" != "xno"; then
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([lzo2],
|
||||
AS_HELP_STRING([--without-lzo2], [Don't build support for lzop through liblzo2]))
|
||||
AS_HELP_STRING([--with-lzo2], [Build with LZO support from liblzo2]))
|
||||
|
||||
if test "x$with_lzo2" != "xno"; then
|
||||
if test "x$with_lzo2" == "xyes"; then
|
||||
AC_CHECK_HEADERS([lzo/lzoconf.h lzo/lzo1x.h])
|
||||
AC_CHECK_LIB(lzo2,lzo1x_decompress_safe)
|
||||
fi
|
||||
@ -724,12 +724,31 @@ if test "x$enable_acl" != "xno"; then
|
||||
#endif
|
||||
])
|
||||
|
||||
# Check for ACL_TYPE_NFS4
|
||||
AC_CHECK_DECL([ACL_TYPE_NFS4],
|
||||
[AC_DEFINE(HAVE_ACL_TYPE_NFS4, 1, [True for FreeBSD with NFSv4 ACL support])],
|
||||
[],
|
||||
[#include <sys/acl.h>])
|
||||
|
||||
# MacOS has an acl.h that isn't POSIX. It can be detected by
|
||||
# checking for ACL_USER
|
||||
AC_CHECK_DECL([ACL_USER],
|
||||
[AC_DEFINE(HAVE_ACL_USER, 1, [True for systems with POSIX ACL support])],
|
||||
[],
|
||||
[#include <sys/acl.h>])
|
||||
|
||||
# MacOS has ACL_TYPE_EXTENDED instead
|
||||
AC_CHECK_DECL([ACL_TYPE_EXTENDED],
|
||||
[AC_DEFINE(HAVE_ACL_TYPE_EXTENDED, 1, [True for MacOS ACL support])],
|
||||
[],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/acl.h>])
|
||||
|
||||
# Solaris and derivates ACLs
|
||||
AC_CHECK_LIB([sec], [acl_get])
|
||||
AC_CHECK_TYPES([aclent_t], [], [], [[#include <sys/acl.h>]])
|
||||
AC_CHECK_TYPES([ace_t], [], [], [[#include <sys/acl.h>]])
|
||||
AC_CHECK_FUNCS(acl_get facl_get acl_set facl_set)
|
||||
fi
|
||||
|
||||
# Additional requirements
|
||||
|
@ -168,15 +168,33 @@ SET(libarchive_MANS
|
||||
archive_entry_time.3
|
||||
archive_read.3
|
||||
archive_read_add_passphrase.3
|
||||
archive_read_data.3
|
||||
archive_read_disk.3
|
||||
archive_read_extract.3
|
||||
archive_read_filter.3
|
||||
archive_read_format.3
|
||||
archive_read_free.3
|
||||
archive_read_header.3
|
||||
archive_read_new.3
|
||||
archive_read_open.3
|
||||
archive_read_set_options.3
|
||||
archive_util.3
|
||||
archive_write.3
|
||||
archive_write_blocksize.3
|
||||
archive_write_data.3
|
||||
archive_write_disk.3
|
||||
archive_write_filter.3
|
||||
archive_write_finish_entry.3
|
||||
archive_write_format.3
|
||||
archive_write_free.3
|
||||
archive_write_header.3
|
||||
archive_write_new.3
|
||||
archive_write_open.3
|
||||
archive_write_set_options.3
|
||||
archive_write_set_passphrase.3
|
||||
cpio.5
|
||||
libarchive.3
|
||||
libarchive_changes.3
|
||||
libarchive_internals.3
|
||||
libarchive-formats.5
|
||||
mtree.5
|
||||
|
@ -348,6 +348,15 @@ archive_acl_count(struct archive_acl *acl, int want_type)
|
||||
return (count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a bitmask of stored ACL types in an ACL list
|
||||
*/
|
||||
int
|
||||
archive_acl_types(struct archive_acl *acl)
|
||||
{
|
||||
return (acl->acl_types);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for reading entries from the ACL data. Returns a count
|
||||
* of entries matching "want_type", or zero if there are no
|
||||
@ -1144,7 +1153,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
|
||||
const wchar_t *s, *st;
|
||||
|
||||
int numfields, fields, n, r, ret;
|
||||
int numfields, fields, n, r, sol, ret;
|
||||
int type, types, tag, permset, id;
|
||||
size_t len;
|
||||
wchar_t sep;
|
||||
@ -1192,6 +1201,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
}
|
||||
|
||||
n = 0;
|
||||
sol = 0;
|
||||
id = -1;
|
||||
permset = 0;
|
||||
name.start = name.end = NULL;
|
||||
@ -1263,6 +1273,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
&& ismode_w(field[n + 1].start,
|
||||
field[n + 1].end, &permset)) {
|
||||
/* This is Solaris-style "other:rwx" */
|
||||
sol = 1;
|
||||
} else if (fields == (n + 3) &&
|
||||
field[n + 1].start < field[n + 1].end) {
|
||||
/* Invalid mask or other field */
|
||||
@ -1287,9 +1298,12 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Without "default:" we expect mode in field 2 */
|
||||
if (permset == 0 && !ismode_w(field[n + 2].start,
|
||||
field[n + 2].end, &permset)) {
|
||||
/*
|
||||
* Without "default:" we expect mode in field 2
|
||||
* Exception: Solaris other and mask fields
|
||||
*/
|
||||
if (permset == 0 && !ismode_w(field[n + 2 - sol].start,
|
||||
field[n + 2 - sol].end, &permset)) {
|
||||
/* Invalid mode, skip entry */
|
||||
ret = ARCHIVE_WARN;
|
||||
continue;
|
||||
@ -1615,7 +1629,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
} field[6], name;
|
||||
|
||||
const char *s, *st;
|
||||
int numfields, fields, n, r, ret;
|
||||
int numfields, fields, n, r, sol, ret;
|
||||
int type, types, tag, permset, id;
|
||||
size_t len;
|
||||
char sep;
|
||||
@ -1663,6 +1677,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
}
|
||||
|
||||
n = 0;
|
||||
sol = 0;
|
||||
id = -1;
|
||||
permset = 0;
|
||||
name.start = name.end = NULL;
|
||||
@ -1734,6 +1749,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
&& ismode(field[n + 1].start,
|
||||
field[n + 1].end, &permset)) {
|
||||
/* This is Solaris-style "other:rwx" */
|
||||
sol = 1;
|
||||
} else if (fields == (n + 3) &&
|
||||
field[n + 1].start < field[n + 1].end) {
|
||||
/* Invalid mask or other field */
|
||||
@ -1758,9 +1774,12 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Without "default:" we expect mode in field 2 */
|
||||
if (permset == 0 && !ismode(field[n + 2].start,
|
||||
field[n + 2].end, &permset)) {
|
||||
/*
|
||||
* Without "default:" we expect mode in field 3
|
||||
* Exception: Solaris other and mask fields
|
||||
*/
|
||||
if (permset == 0 && !ismode(field[n + 2 - sol].start,
|
||||
field[n + 2 - sol].end, &permset)) {
|
||||
/* Invalid mode, skip entry */
|
||||
ret = ARCHIVE_WARN;
|
||||
continue;
|
||||
|
@ -56,6 +56,7 @@ struct archive_acl {
|
||||
void archive_acl_clear(struct archive_acl *);
|
||||
void archive_acl_copy(struct archive_acl *, struct archive_acl *);
|
||||
int archive_acl_count(struct archive_acl *, int);
|
||||
int archive_acl_types(struct archive_acl *);
|
||||
int archive_acl_reset(struct archive_acl *, int);
|
||||
int archive_acl_next(struct archive *, struct archive_acl *, int,
|
||||
int *, int *, int *, int *, const char **);
|
||||
|
@ -1447,7 +1447,7 @@ archive_entry_acl_add_entry_w(struct archive_entry *entry,
|
||||
int
|
||||
archive_entry_acl_types(struct archive_entry *entry)
|
||||
{
|
||||
return ((&entry->acl)->acl_types);
|
||||
return (archive_acl_types(&entry->acl));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -80,7 +80,7 @@ archive_entry_strmode(struct archive_entry *entry)
|
||||
if (mode & 0001) bp[9] = 't';
|
||||
else bp[9] = 'T';
|
||||
}
|
||||
if (archive_entry_acl_count(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS))
|
||||
if (archive_entry_acl_types(entry) != 0)
|
||||
bp[10] = '+';
|
||||
|
||||
return (bp);
|
||||
|
@ -147,8 +147,25 @@
|
||||
* 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 && HAVE_ACL_USER
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
|
||||
#if HAVE_ACL_USER
|
||||
#define HAVE_POSIX_ACL 1
|
||||
#elif HAVE_ACL_TYPE_EXTENDED
|
||||
#define HAVE_DARWIN_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_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
|
||||
#define HAVE_SUN_ACL 1
|
||||
#endif
|
||||
|
||||
/* Define if platform supports NFSv4 ACLs */
|
||||
#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
|
||||
#define HAVE_NFS4_ACL 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -80,7 +80,7 @@ archive_random(void *buf, size_t nbytes)
|
||||
|
||||
success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT);
|
||||
if (!success && GetLastError() == NTE_BAD_KEYSET) {
|
||||
if (!success && GetLastError() == (DWORD)NTE_BAD_KEYSET) {
|
||||
success = CryptAcquireContext(&hProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_NEWKEYSET);
|
||||
}
|
||||
|
@ -38,6 +38,11 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
#include <membership.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_EXTATTR_H
|
||||
#include <sys/extattr.h>
|
||||
#endif
|
||||
@ -118,6 +123,15 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_entry_from_file.c 2010
|
||||
#define ACL_GET_PERM acl_get_perm_np
|
||||
#endif
|
||||
|
||||
/* NFSv4 platform ACL type */
|
||||
#if HAVE_SUN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
|
||||
#elif HAVE_DARWIN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
|
||||
#elif HAVE_ACL_TYPE_NFS4
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
|
||||
#endif
|
||||
|
||||
static int setup_acls(struct archive_read_disk *,
|
||||
struct archive_entry *, int *fd);
|
||||
static int setup_mac_metadata(struct archive_read_disk *,
|
||||
@ -405,17 +419,38 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
static int translate_guid(struct archive *, acl_entry_t,
|
||||
int *, int *, const char **);
|
||||
|
||||
#ifdef HAVE_POSIX_ACL
|
||||
static void add_trivial_nfs4_acl(struct archive_entry *);
|
||||
#endif
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
static int
|
||||
sun_acl_is_trivial(acl_t *, mode_t, int *trivialp);
|
||||
#endif
|
||||
|
||||
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
|
||||
static int translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
|
||||
struct archive_entry *entry,
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl,
|
||||
#else
|
||||
acl_t acl,
|
||||
#endif
|
||||
int archive_entry_acl_type);
|
||||
|
||||
static int
|
||||
setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
acl_t acl;
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl;
|
||||
#else
|
||||
acl_t acl;
|
||||
#endif
|
||||
int r;
|
||||
|
||||
accpath = archive_entry_sourcepath(entry);
|
||||
@ -440,17 +475,20 @@ setup_acls(struct archive_read_disk *a,
|
||||
|
||||
acl = NULL;
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_NFS4_ACL
|
||||
/* Try NFSv4 ACL first. */
|
||||
if (*fd >= 0)
|
||||
#if HAVE_ACL_GET_FD_NP
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
|
||||
#if HAVE_SUN_ACL
|
||||
/* Solaris reads both POSIX.1e and NFSv4 ACL here */
|
||||
facl_get(*fd, 0, &acl);
|
||||
#elif HAVE_ACL_GET_FD_NP
|
||||
acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
|
||||
#else
|
||||
acl = acl_get_fd(*fd);
|
||||
#endif
|
||||
#if HAVE_ACL_GET_LINK_NP
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
|
||||
acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
|
||||
#else
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
@ -459,12 +497,24 @@ setup_acls(struct archive_read_disk *a,
|
||||
acl = NULL;
|
||||
#endif
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_NFS4);
|
||||
#if HAVE_SUN_ACL
|
||||
/* Solaris reads both POSIX.1e and NFSv4 ACLs here */
|
||||
acl_get(accpath, 0, &acl);
|
||||
#else
|
||||
acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
|
||||
#endif
|
||||
|
||||
#if HAVE_ACL_IS_TRIVIAL_NP
|
||||
if (acl != NULL && acl_is_trivial_np(acl, &r) == 0) {
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (r) {
|
||||
|
||||
#if HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (acl != NULL) {
|
||||
#if HAVE_SUN_ACL
|
||||
if (sun_acl_is_trivial(acl, archive_entry_mode(entry),
|
||||
&r) == 0 && r == 1)
|
||||
#elif HAVE_ACL_IS_TRIVIAL_NP
|
||||
if (acl_is_trivial_np(acl, &r) == 0 && r == 1)
|
||||
#endif
|
||||
{
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
/*
|
||||
@ -474,17 +524,35 @@ setup_acls(struct archive_read_disk *a,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL */
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
|
||||
acl_free(acl);
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
#if HAVE_SUN_ACL
|
||||
"Couldn't translate ACLs: %s", accpath);
|
||||
#else
|
||||
"Couldn't translate NFSv4 ACLs: %s", accpath);
|
||||
#endif
|
||||
}
|
||||
#if HAVE_DARWIN_ACL
|
||||
/*
|
||||
* 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_count(entry,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0)
|
||||
add_trivial_nfs4_acl(entry);
|
||||
#endif
|
||||
return (r);
|
||||
}
|
||||
#endif /* ACL_TYPE_NFS4 */
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
#if HAVE_POSIX_ACL
|
||||
/* This code path is skipped on MacOS and Solaris */
|
||||
|
||||
/* Retrieve access ACL from file. */
|
||||
if (*fd >= 0)
|
||||
@ -513,8 +581,7 @@ setup_acls(struct archive_read_disk *a,
|
||||
#endif
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
if (r != ARCHIVE_OK) {
|
||||
@ -544,72 +611,560 @@ setup_acls(struct archive_read_disk *a,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_POSIX_ACL */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate system ACL into libarchive internal structure.
|
||||
* Translate system ACL permissions into libarchive internal structure
|
||||
*/
|
||||
|
||||
static struct {
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
} acl_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
{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}
|
||||
#if HAVE_SUN_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},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#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_ACL_TYPE_NFS4 /* 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 */
|
||||
};
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_NFS4_ACL
|
||||
/*
|
||||
* Translate system NFSv4 inheritance flags into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
} acl_inherit_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
#if HAVE_SUN_ACL /* Solaris 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},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
|
||||
#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_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
#endif
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
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;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
|
||||
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;
|
||||
pwd = getpwuuid(q);
|
||||
if (pwd == NULL) {
|
||||
*ae_id = ugid;
|
||||
*ae_name = NULL;
|
||||
} else {
|
||||
*ae_id = pwd->pw_uid;
|
||||
*ae_name = archive_read_disk_uname(a, *ae_id);
|
||||
}
|
||||
} else if (idtype == ID_TYPE_GID) {
|
||||
*ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
grp = getgruuid(q);
|
||||
if (grp == NULL) {
|
||||
*ae_id = ugid;
|
||||
*ae_name = NULL;
|
||||
} else {
|
||||
*ae_id = grp->gr_gid;
|
||||
*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;
|
||||
}
|
||||
#elif HAVE_SUN_ACL
|
||||
/*
|
||||
* Check if acl is trivial
|
||||
* This is a FreeBSD acl_is_trivial_np() implementation for Solaris
|
||||
*/
|
||||
static int
|
||||
sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
|
||||
{
|
||||
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];
|
||||
|
||||
if (acl == NULL || trivialp == NULL)
|
||||
return (-1);
|
||||
|
||||
*trivialp = 0;
|
||||
|
||||
/* ACL_IS_TRIVIAL flag must be set for both POSIX.1e and NFSv4 ACLs */
|
||||
if ((acl->acl_flags & ACL_IS_TRIVIAL) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
|
||||
* FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
|
||||
* incuding mask.
|
||||
*/
|
||||
if (acl->acl_type == ACLENT_T) {
|
||||
if (acl->acl_cnt == 4)
|
||||
*trivialp = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (acl->acl_type != ACE_T || acl->acl_entry_size != sizeof(ace_t))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* 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 (acl->acl_cnt != p)
|
||||
return (0);
|
||||
|
||||
p = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (tace[i].a_access_mask != 0) {
|
||||
ace = &((ace_t *)acl->acl_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 &&
|
||||
((acl->acl_flags & ACL_IS_DIR) == 0 ||
|
||||
(tace[i].a_access_mask & wperm) == 0 ||
|
||||
ace->a_access_mask !=
|
||||
(tace[i].a_access_mask | ACE_DELETE_CHILD))))
|
||||
return (0);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
*trivialp = 1;
|
||||
return (0);
|
||||
}
|
||||
#endif /* HAVE_SUN_ACL */
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
/*
|
||||
* Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
|
||||
*/
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t *acl, 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;
|
||||
ace_t *ace;
|
||||
|
||||
(void)default_entry_acl_type;
|
||||
|
||||
if (acl->acl_cnt <= 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
for (e = 0; e < acl->acl_cnt; e++) {
|
||||
ae_name = NULL;
|
||||
ae_tag = 0;
|
||||
ae_perm = 0;
|
||||
|
||||
if (acl->acl_type == ACE_T) {
|
||||
ace = &((ace_t *)acl->acl_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 < (int)(sizeof(acl_inherit_map) /
|
||||
sizeof(acl_inherit_map[0])); ++i) {
|
||||
if ((ace->a_flags &
|
||||
acl_inherit_map[i].platform_inherit) != 0)
|
||||
ae_perm |=
|
||||
acl_inherit_map[i].archive_inherit;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)(sizeof(acl_perm_map) /
|
||||
sizeof(acl_perm_map[0])); ++i) {
|
||||
if ((ace->a_access_mask &
|
||||
acl_perm_map[i].platform_perm) != 0)
|
||||
ae_perm |=
|
||||
acl_perm_map[i].archive_perm;
|
||||
}
|
||||
} else {
|
||||
aclent = &((aclent_t *)acl->acl_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;
|
||||
}
|
||||
|
||||
if ((aclent->a_perm & 1) != 0)
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
if ((aclent->a_perm & 2) != 0)
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
|
||||
if ((aclent->a_perm & 4) != 0)
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_READ;
|
||||
} /* default_entry_acl_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4 */
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag, ae_id, ae_name);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
/*
|
||||
* Translate POSIX.1e (Linux), FreeBSD (both POSIX.1e and NFSv4) and
|
||||
* MacOS (NFSv4 only) 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;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
acl_entry_type_t acl_type;
|
||||
acl_flagset_t acl_flagset;
|
||||
int brand;
|
||||
#endif
|
||||
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
|
||||
acl_flagset_t acl_flagset;
|
||||
#endif
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
int i, entry_acl_type;
|
||||
int r, s, ae_id, ae_tag, ae_perm;
|
||||
#if !HAVE_DARWIN_ACL
|
||||
void *q;
|
||||
#endif
|
||||
const char *ae_name;
|
||||
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_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.
|
||||
@ -644,14 +1199,19 @@ translate_acl(struct archive_read_disk *a,
|
||||
}
|
||||
#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) {
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
while (s == 0)
|
||||
#else /* FreeBSD, Linux */
|
||||
while (s == 1)
|
||||
#endif
|
||||
{
|
||||
ae_id = -1;
|
||||
ae_name = NULL;
|
||||
ae_perm = 0;
|
||||
@ -662,14 +1222,25 @@ translate_acl(struct archive_read_disk *a,
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_tag) {
|
||||
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
|
||||
case ACL_USER:
|
||||
ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
|
||||
ae_name = archive_read_disk_uname(&a->archive, ae_id);
|
||||
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:
|
||||
ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
|
||||
ae_name = archive_read_disk_gname(&a->archive, ae_id);
|
||||
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:
|
||||
@ -684,21 +1255,44 @@ translate_acl(struct archive_read_disk *a,
|
||||
case ACL_OTHER:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
case ACL_EVERYONE:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
break;
|
||||
#endif
|
||||
#else /* HAVE_DARWIN_ACL */
|
||||
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;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
/* Skip if translate_guid() above failed */
|
||||
if (r != 0) {
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HAVE_DARWIN_ACL
|
||||
// XXX acl_type maps to allow/deny/audit/YYYY bits
|
||||
entry_acl_type = default_entry_acl_type;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#endif
|
||||
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
|
||||
if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
/*
|
||||
* acl_get_entry_type_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
@ -725,6 +1319,7 @@ translate_acl(struct archive_read_disk *a,
|
||||
"Invalid NFSv4 ACL entry type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#endif /* HAVE_ACL_TYPE_NFS4 */
|
||||
|
||||
/*
|
||||
* Libarchive stores "flag" (NFSv4 inheritance bits)
|
||||
@ -737,7 +1332,7 @@ translate_acl(struct archive_read_disk *a,
|
||||
"Failed to get flagset from a NFSv4 ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
||||
r = acl_get_flag_np(acl_flagset,
|
||||
acl_inherit_map[i].platform_inherit);
|
||||
if (r == -1) {
|
||||
@ -747,9 +1342,9 @@ translate_acl(struct archive_read_disk *a,
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_inherit_map[i].archive_inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL */
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
@ -775,15 +1370,18 @@ translate_acl(struct archive_read_disk *a,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
#if !HAVE_DARWIN_ACL
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get next ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#else
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
#else /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
|
||||
static int
|
||||
setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
@ -793,7 +1391,7 @@ setup_acls(struct archive_read_disk *a,
|
||||
(void)fd; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif
|
||||
#endif /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
|
||||
|
||||
#if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
|
||||
HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \
|
||||
|
@ -222,7 +222,7 @@ file_open(struct archive *a, void *client_data)
|
||||
void *buffer;
|
||||
const char *filename = NULL;
|
||||
const wchar_t *wfilename = NULL;
|
||||
int fd;
|
||||
int fd = -1;
|
||||
int is_disk_like = 0;
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */
|
||||
@ -277,7 +277,7 @@ file_open(struct archive *a, void *client_data)
|
||||
#else
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unexpedted operation in archive_read_open_filename");
|
||||
return (ARCHIVE_FATAL);
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
if (fstat(fd, &st) != 0) {
|
||||
@ -287,7 +287,7 @@ file_open(struct archive *a, void *client_data)
|
||||
else
|
||||
archive_set_error(a, errno, "Can't stat '%s'",
|
||||
filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -356,11 +356,9 @@ file_open(struct archive *a, void *client_data)
|
||||
mine->block_size = new_block_size;
|
||||
}
|
||||
buffer = malloc(mine->block_size);
|
||||
if (mine == NULL || buffer == NULL) {
|
||||
if (buffer == NULL) {
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
free(mine);
|
||||
free(buffer);
|
||||
return (ARCHIVE_FATAL);
|
||||
goto fail;
|
||||
}
|
||||
mine->buffer = buffer;
|
||||
mine->fd = fd;
|
||||
@ -372,6 +370,14 @@ file_open(struct archive *a, void *client_data)
|
||||
mine->use_lseek = 1;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
fail:
|
||||
/*
|
||||
* Don't close file descriptors not opened or ones pointing referring
|
||||
* to `FNT_STDIN`.
|
||||
*/
|
||||
if (fd != -1 && fd != 0)
|
||||
close(fd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
@ -706,6 +706,11 @@ lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p)
|
||||
/* Make sure we have a whole block. */
|
||||
read_buf = __archive_read_filter_ahead(self->upstream,
|
||||
4 + compressed, NULL);
|
||||
if (read_buf == NULL) {
|
||||
archive_set_error(&(self->archive->archive),
|
||||
ARCHIVE_ERRNO_MISC, "truncated lz4 input");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
ret = LZ4_decompress_safe(read_buf + 4, state->out_block,
|
||||
compressed, (int)state->out_block_size);
|
||||
if (ret < 0) {
|
||||
|
@ -430,6 +430,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
&state->child_stdout);
|
||||
if (child == -1) {
|
||||
free(state->out_buf);
|
||||
archive_string_free(&state->description);
|
||||
free(state);
|
||||
archive_set_error(&self->archive->archive, EINVAL,
|
||||
"Can't initialize filter; unable to run program \"%s\"",
|
||||
@ -441,6 +442,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
if (state->child == NULL) {
|
||||
child_stop(self, state);
|
||||
free(state->out_buf);
|
||||
archive_string_free(&state->description);
|
||||
free(state);
|
||||
archive_set_error(&self->archive->archive, EINVAL,
|
||||
"Can't initialize filter; unable to run program \"%s\"",
|
||||
|
@ -1495,6 +1495,8 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
|
||||
|
||||
/* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */
|
||||
if (mszip > 0) {
|
||||
if (bytes_avail <= 0)
|
||||
goto nomszip;
|
||||
if (bytes_avail <= mszip) {
|
||||
if (mszip == 2) {
|
||||
if (cab->stream.next_in[0] != 0x43)
|
||||
|
@ -434,7 +434,8 @@ archive_read_format_cpio_read_header(struct archive_read *a,
|
||||
* header. XXX */
|
||||
|
||||
/* Compare name to "TRAILER!!!" to test for end-of-archive. */
|
||||
if (namelength == 11 && strcmp((const char *)h, "TRAILER!!!") == 0) {
|
||||
if (namelength == 11 && memcmp((const char *)h, "TRAILER!!!",
|
||||
11) == 0) {
|
||||
/* TODO: Store file location of start of block. */
|
||||
archive_clear_error(&a->archive);
|
||||
return (ARCHIVE_EOF);
|
||||
|
@ -1864,7 +1864,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
if ((file->utf16be_name = malloc(name_len)) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory for file name");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
memcpy(file->utf16be_name, p, name_len);
|
||||
file->utf16be_bytes = name_len;
|
||||
@ -1943,10 +1943,8 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
file->symlink_continues = 0;
|
||||
rr_start += iso9660->suspOffset;
|
||||
r = parse_rockridge(a, file, rr_start, rr_end);
|
||||
if (r != ARCHIVE_OK) {
|
||||
free(file);
|
||||
return (NULL);
|
||||
}
|
||||
if (r != ARCHIVE_OK)
|
||||
goto fail;
|
||||
/*
|
||||
* A file size of symbolic link files in ISO images
|
||||
* made by makefs is not zero and its location is
|
||||
@ -1990,7 +1988,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge RE");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
/*
|
||||
* Sanity check: file does not have "CL" extension.
|
||||
@ -1999,7 +1997,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge RE and CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
/*
|
||||
* Sanity check: The file type must be a directory.
|
||||
@ -2008,7 +2006,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge RE");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
} else if (parent != NULL && parent->rr_moved)
|
||||
file->rr_moved_has_re_only = 0;
|
||||
@ -2022,7 +2020,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
/*
|
||||
* Sanity check: The file type must be a regular file.
|
||||
@ -2031,7 +2029,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
parent->subdirs++;
|
||||
/* Overwrite an offset and a number of this "CL" entry
|
||||
@ -2049,7 +2047,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (file->cl_offset == file->offset ||
|
||||
@ -2057,7 +2055,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2088,6 +2086,10 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
#endif
|
||||
register_file(iso9660, file);
|
||||
return (file);
|
||||
fail:
|
||||
archive_string_free(&file->name);
|
||||
free(file);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -924,6 +924,9 @@ lha_read_file_header_1(struct archive_read *a, struct lha *lha)
|
||||
/* Get a real compressed file size. */
|
||||
lha->compsize -= extdsize - 2;
|
||||
|
||||
if (lha->compsize < 0)
|
||||
goto invalid; /* Invalid compressed file size */
|
||||
|
||||
if (sum_calculated != headersum) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"LHa header sum error");
|
||||
|
@ -715,13 +715,13 @@ detect_form(struct archive_read *a, int *is_form_d)
|
||||
}
|
||||
} else
|
||||
break;
|
||||
} else if (strncmp(p, "/set", 4) == 0) {
|
||||
} else if (len > 4 && strncmp(p, "/set", 4) == 0) {
|
||||
if (bid_keyword_list(p+4, len-4, 0, 0) <= 0)
|
||||
break;
|
||||
/* This line continues. */
|
||||
if (p[len-nl-1] == '\\')
|
||||
multiline = 2;
|
||||
} else if (strncmp(p, "/unset", 6) == 0) {
|
||||
} else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
|
||||
if (bid_keyword_list(p+6, len-6, 1, 0) <= 0)
|
||||
break;
|
||||
/* This line continues. */
|
||||
@ -1019,11 +1019,11 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
if (*p != '/') {
|
||||
r = process_add_entry(a, mtree, &global, p, len,
|
||||
&last_entry, is_form_d);
|
||||
} else if (strncmp(p, "/set", 4) == 0) {
|
||||
} else if (len > 4 && strncmp(p, "/set", 4) == 0) {
|
||||
if (p[4] != ' ' && p[4] != '\t')
|
||||
break;
|
||||
r = process_global_set(a, &global, p);
|
||||
} else if (strncmp(p, "/unset", 6) == 0) {
|
||||
} else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
|
||||
if (p[6] != ' ' && p[6] != '\t')
|
||||
break;
|
||||
r = process_global_unset(a, &global, p);
|
||||
|
@ -944,7 +944,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
||||
{
|
||||
const struct archive_entry_header_ustar *header;
|
||||
size_t size;
|
||||
int err;
|
||||
int err, acl_type;
|
||||
int64_t type;
|
||||
char *acl, *p;
|
||||
|
||||
@ -989,11 +989,12 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
||||
switch ((int)type & ~0777777) {
|
||||
case 01000000:
|
||||
/* POSIX.1e ACL */
|
||||
acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
break;
|
||||
case 03000000:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Solaris NFSv4 ACLs not supported");
|
||||
return (ARCHIVE_WARN);
|
||||
/* NFSv4 ACL */
|
||||
acl_type = ARCHIVE_ENTRY_ACL_TYPE_NFS4;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Malformed Solaris ACL attribute (unsupported type %o)",
|
||||
@ -1023,7 +1024,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
||||
}
|
||||
archive_strncpy(&(tar->localname), acl, p - acl);
|
||||
err = archive_acl_from_text_l(archive_entry_acl(entry),
|
||||
tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, tar->sconv_acl);
|
||||
tar->localname.s, acl_type, tar->sconv_acl);
|
||||
if (err != ARCHIVE_OK) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
|
@ -534,7 +534,7 @@ xstrpisotime(const char *s, char **endptr)
|
||||
|
||||
/* as a courtesy to our callers, and since this is a non-standard
|
||||
* routine, we skip leading whitespace */
|
||||
while (isspace((unsigned char)*s))
|
||||
while (isblank((unsigned char)*s))
|
||||
++s;
|
||||
|
||||
/* read year */
|
||||
|
@ -933,6 +933,7 @@ xar_cleanup(struct archive_read *a)
|
||||
}
|
||||
for (i = 0; i < xar->file_queue.used; i++)
|
||||
file_free(xar->file_queue.files[i]);
|
||||
free(xar->file_queue.files);
|
||||
while (xar->unknowntags != NULL) {
|
||||
struct unknown_tag *tag;
|
||||
|
||||
@ -3047,7 +3048,7 @@ xml2_read_cb(void *context, char *buffer, int len)
|
||||
struct xar *xar;
|
||||
const void *d;
|
||||
size_t outbytes;
|
||||
size_t used;
|
||||
size_t used = 0;
|
||||
int r;
|
||||
|
||||
a = (struct archive_read *)context;
|
||||
@ -3171,6 +3172,9 @@ expat_xmlattr_setup(struct archive_read *a,
|
||||
value = strdup(atts[1]);
|
||||
if (attr == NULL || name == NULL || value == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
free(attr);
|
||||
free(name);
|
||||
free(value);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
attr->name = name;
|
||||
|
@ -905,6 +905,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
archive_wstrcat(&s, wp);
|
||||
archive_wstrappend_wchar(&s, L'/');
|
||||
archive_entry_copy_pathname_w(entry, s.s);
|
||||
archive_wstring_free(&s);
|
||||
}
|
||||
} else {
|
||||
cp = archive_entry_pathname(entry);
|
||||
@ -915,6 +916,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
archive_strcat(&s, cp);
|
||||
archive_strappend_char(&s, '/');
|
||||
archive_entry_set_pathname(entry, s.s);
|
||||
archive_string_free(&s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -891,7 +891,7 @@ __la_dosmaperr(unsigned long e)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)sizeof(doserrors)/sizeof(doserrors[0]); i++)
|
||||
for (i = 0; i < (int)(sizeof(doserrors)/sizeof(doserrors[0])); i++)
|
||||
{
|
||||
if (doserrors[i].winerr == e)
|
||||
{
|
||||
|
@ -218,16 +218,20 @@
|
||||
#define S_IWUSR _S_IWUSR
|
||||
#define S_IRUSR _S_IRUSR
|
||||
#endif
|
||||
#ifndef S_IRWXG
|
||||
#define S_IRWXG _S_IRWXG
|
||||
#define S_IXGRP _S_IXGRP
|
||||
#define S_IWGRP _S_IWGRP
|
||||
#endif
|
||||
#ifndef S_IRGRP
|
||||
#define S_IRGRP _S_IRGRP
|
||||
#endif
|
||||
#ifndef S_IRWXO
|
||||
#define S_IRWXO _S_IRWXO
|
||||
#define S_IXOTH _S_IXOTH
|
||||
#define S_IWOTH _S_IWOTH
|
||||
#define S_IROTH _S_IROTH
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -200,6 +200,7 @@ __archive_write_program_free(struct archive_write_program_data *data)
|
||||
if (data->child)
|
||||
CloseHandle(data->child);
|
||||
#endif
|
||||
free(data->program_name);
|
||||
free(data->child_buf);
|
||||
free(data);
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
|
||||
#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
|
||||
@ -43,7 +46,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
|
||||
#include "archive_acl_private.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
|
||||
#ifndef HAVE_POSIX_ACL
|
||||
#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,
|
||||
@ -56,47 +59,111 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
|
||||
#elif HAVE_DARWIN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
|
||||
#elif HAVE_ACL_TYPE_NFS4
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
|
||||
#endif
|
||||
|
||||
static int set_acl(struct archive *, int fd, const char *,
|
||||
struct archive_acl *,
|
||||
acl_type_t, int archive_entry_acl_type, const char *tn);
|
||||
|
||||
/*
|
||||
* XXX TODO: What about ACL types other than ACCESS and DEFAULT?
|
||||
*/
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl)
|
||||
{
|
||||
int ret;
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) > 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
||||
#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, ACLENT_T,
|
||||
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 */
|
||||
/* Simultaeous POSIX.1e and NFSv4 is not supported */
|
||||
return (ret);
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
|
||||
}
|
||||
#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,
|
||||
ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
return (ret);
|
||||
#endif
|
||||
} else
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate system ACL permissions into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
} acl_perm_map[] = {
|
||||
#if HAVE_SUN_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},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#else /* POSIX.1e ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4 /* 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},
|
||||
@ -114,13 +181,32 @@ static struct {
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_NFS4_ACL
|
||||
/*
|
||||
* Translate system NFSv4 inheritance flags into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
} acl_inherit_map[] = {
|
||||
#if HAVE_SUN_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},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
|
||||
#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},
|
||||
@ -128,23 +214,36 @@ static struct {
|
||||
{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_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
#endif
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
acl_type_t acl_type, int ae_requested_type, const char *tname)
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
aclent_t *aclent;
|
||||
ace_t *ace;
|
||||
int e, r;
|
||||
acl_t *acl;
|
||||
#else
|
||||
acl_t acl;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
|
||||
acl_flagset_t acl_flagset;
|
||||
int r;
|
||||
#endif
|
||||
#endif /* HAVE_SUN_ACL */
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
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;
|
||||
@ -155,32 +254,165 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
acl = NULL;
|
||||
acl = malloc(sizeof(acl_t));
|
||||
if (acl == NULL) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (acl_type == ACE_T)
|
||||
acl->acl_entry_size = sizeof(ace_t);
|
||||
else if (acl_type == ACLENT_T)
|
||||
acl->acl_entry_size = sizeof(aclent_t);
|
||||
else {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ACL type");
|
||||
acl_free(acl);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
acl->acl_type = acl_type;
|
||||
acl->acl_cnt = entries;
|
||||
|
||||
acl->acl_aclp = malloc(entries * acl->acl_entry_size);
|
||||
if (acl->acl_aclp == NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Can't allocate memory for acl buffer");
|
||||
acl_free(acl);
|
||||
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
|
||||
ace = NULL;
|
||||
aclent = NULL;
|
||||
if (acl->acl_type == ACE_T) {
|
||||
ace = &((ace_t *)acl->acl_aclp)[e];
|
||||
ace->a_who = -1;
|
||||
ace->a_access_mask = 0;
|
||||
ace->a_flags = 0;
|
||||
} else {
|
||||
aclent = &((aclent_t *)acl->acl_aclp)[e];
|
||||
aclent->a_id = -1;
|
||||
aclent->a_type = 0;
|
||||
aclent->a_perm = 0;
|
||||
}
|
||||
#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:
|
||||
acl_set_tag_type(acl_entry, ACL_USER);
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
acl_set_qualifier(acl_entry, &ae_uid);
|
||||
if (acl->acl_type == ACE_T)
|
||||
ace->a_who = ae_uid;
|
||||
else {
|
||||
aclent->a_id = ae_uid;
|
||||
aclent->a_type |= USER;
|
||||
}
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP);
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
acl_set_qualifier(acl_entry, &ae_gid);
|
||||
if (acl->acl_type == ACE_T) {
|
||||
ace->a_who = ae_gid;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
} else {
|
||||
aclent->a_id = ae_gid;
|
||||
aclent->a_type |= GROUP;
|
||||
}
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
if (acl->acl_type == ACE_T)
|
||||
ace->a_flags |= ACE_OWNER;
|
||||
else
|
||||
aclent->a_type |= USER_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
if (acl->acl_type == ACE_T) {
|
||||
ace->a_flags |= ACE_GROUP;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
} else
|
||||
aclent->a_type |= GROUP_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
aclent->a_type |= CLASS_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
aclent->a_type |= OTHER_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
ace->a_flags |= ACE_EVERYONE;
|
||||
break;
|
||||
#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;
|
||||
@ -193,11 +425,13 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
acl_set_tag_type(acl_entry, ACL_OTHER);
|
||||
break;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4 /* 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");
|
||||
@ -205,9 +439,45 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL
|
||||
r = 0;
|
||||
switch (ae_type) {
|
||||
#if HAVE_SUN_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;
|
||||
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;
|
||||
@ -224,20 +494,35 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
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,
|
||||
"Unknown 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
|
||||
#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL */
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl->acl_type == ACLENT_T) {
|
||||
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;
|
||||
} else
|
||||
#else
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get ACL permission set");
|
||||
@ -250,9 +535,13 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_SUN_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 (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,
|
||||
@ -260,10 +549,20 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
if (acl_type == ACL_TYPE_NFS4) {
|
||||
#if HAVE_NFS4_ACL
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl_type == ACE_T)
|
||||
#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
|
||||
*/
|
||||
@ -279,8 +578,13 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
||||
#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,
|
||||
@ -288,19 +592,29 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
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_ACL_SET_FD_NP || HAVE_ACL_SET_FD
|
||||
#if HAVE_ACL_SET_FD_NP
|
||||
if (fd >= 0) {
|
||||
#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_set(fd, acl) == 0)
|
||||
#elif HAVE_ACL_SET_FD_NP
|
||||
if (acl_set_fd_np(fd, acl, acl_type) == 0)
|
||||
#else /* HAVE_ACL_SET_FD */
|
||||
if (fd >= 0 && acl_type == ACL_TYPE_ACCESS) {
|
||||
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
|
||||
if (acl_set_fd(fd, acl) == 0)
|
||||
#endif
|
||||
ret = ARCHIVE_OK;
|
||||
@ -314,13 +628,16 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD */
|
||||
#if HAVE_ACL_SET_LINK_NP
|
||||
if (acl_set_link_np(name, acl_type, acl) != 0) {
|
||||
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl_set(name, acl) != 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) {
|
||||
if (acl_set_file(name, acl_type, acl) != 0)
|
||||
#endif
|
||||
{
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
@ -334,4 +651,4 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
acl_free(acl);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
|
||||
|
@ -110,6 +110,18 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/fcntl1.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro to cast st_mtime and time_t to an int64 so that 2 numbers can reliably be compared.
|
||||
*
|
||||
* It assumes that the input is an integer type of no more than 64 bits.
|
||||
* If the number is less than zero, t must be a signed type, so it fits in
|
||||
* int64_t. Otherwise, it's a nonnegative value so we can cast it to uint64_t
|
||||
* without loss. But it could be a large unsigned value, so we have to clip it
|
||||
* to INT64_MAX.*
|
||||
*/
|
||||
#define to_int64_time(t) \
|
||||
((t) < 0 ? (int64_t)(t) : (uint64_t)(t) > (uint64_t)INT64_MAX ? INT64_MAX : (int64_t)(t))
|
||||
|
||||
#if __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && HAVE_QUARANTINE_H
|
||||
@ -1690,10 +1702,25 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
* ACLs that prevent attribute changes (including time).
|
||||
*/
|
||||
if (a->todo & TODO_ACLS) {
|
||||
int r2 = archive_write_disk_set_acls(&a->archive, a->fd,
|
||||
archive_entry_pathname(a->entry),
|
||||
archive_entry_acl(a->entry));
|
||||
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 (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));
|
||||
if (r2 < ret) ret = r2;
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
finish_metadata:
|
||||
@ -2065,6 +2092,7 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
archive_set_error(&a->archive, error_number, "%s",
|
||||
error_string.s);
|
||||
free(linkname_copy);
|
||||
archive_string_free(&error_string);
|
||||
/*
|
||||
* EPERM is more appropriate than error_number for our
|
||||
* callers
|
||||
@ -2077,6 +2105,7 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
archive_set_error(&a->archive, error_number, "%s",
|
||||
error_string.s);
|
||||
free(linkname_copy);
|
||||
archive_string_free(&error_string);
|
||||
/*
|
||||
* EPERM is more appropriate than error_number for our
|
||||
* callers
|
||||
@ -2084,6 +2113,7 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
return (EPERM);
|
||||
}
|
||||
free(linkname_copy);
|
||||
archive_string_free(&error_string);
|
||||
r = link(linkname, a->name) ? errno : 0;
|
||||
/*
|
||||
* New cpio and pax formats allow hardlink entries
|
||||
@ -2252,8 +2282,12 @@ _archive_write_disk_close(struct archive *_a)
|
||||
if (p->fixup & TODO_MODE_BASE)
|
||||
chmod(p->name, p->mode);
|
||||
if (p->fixup & TODO_ACLS)
|
||||
archive_write_disk_set_acls(&a->archive,
|
||||
-1, p->name, &p->acl);
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
if (p->mac_metadata == NULL ||
|
||||
p->mac_metadata_size == 0)
|
||||
#endif
|
||||
archive_write_disk_set_acls(&a->archive,
|
||||
-1, p->name, &p->acl);
|
||||
if (p->fixup & TODO_FFLAGS)
|
||||
set_fflags_platform(a, -1, p->name,
|
||||
p->mode, p->fflags_set, 0);
|
||||
@ -4125,10 +4159,10 @@ older(struct stat *st, struct archive_entry *entry)
|
||||
{
|
||||
/* First, test the seconds and return if we have a definite answer. */
|
||||
/* Definitely older. */
|
||||
if (st->st_mtime < archive_entry_mtime(entry))
|
||||
if (to_int64_time(st->st_mtime) < to_int64_time(archive_entry_mtime(entry)))
|
||||
return (1);
|
||||
/* Definitely younger. */
|
||||
if (st->st_mtime > archive_entry_mtime(entry))
|
||||
if (to_int64_time(st->st_mtime) > to_int64_time(archive_entry_mtime(entry)))
|
||||
return (0);
|
||||
/* If this platform supports fractional seconds, try those. */
|
||||
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
|
@ -66,6 +66,7 @@ Freeze the settings, open the archive, and prepare for writing entries.
|
||||
This is the most generic form of this function, which accepts
|
||||
pointers to three callback functions which will be invoked by
|
||||
the compression layer to write the constructed archive.
|
||||
This does not alter the default archive padding.
|
||||
.It Fn archive_write_open_fd
|
||||
A convenience form of
|
||||
.Fn archive_write_open
|
||||
@ -123,12 +124,21 @@ is currently in use.
|
||||
You should be careful to ensure that this variable
|
||||
remains allocated until after the archive is
|
||||
closed.
|
||||
This function will disable padding unless you
|
||||
have specifically set the block size.
|
||||
.El
|
||||
More information about the
|
||||
.Va struct archive
|
||||
object and the overall design of the library can be found in the
|
||||
.Xr libarchive 3
|
||||
overview.
|
||||
.Pp
|
||||
Note that the convenience forms above vary in how
|
||||
they block the output.
|
||||
See
|
||||
.Xr archive_write_blocksize 3
|
||||
if you need to control the block size used for writes
|
||||
or the end-of-file padding behavior.
|
||||
.\"
|
||||
.Sh CLIENT CALLBACKS
|
||||
To use this library, you will need to define and register
|
||||
@ -226,6 +236,7 @@ functions.
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_write 3 ,
|
||||
.Xr archive_write_blocksize 3 ,
|
||||
.Xr archive_write_filter 3 ,
|
||||
.Xr archive_write_format 3 ,
|
||||
.Xr archive_write_new 3 ,
|
||||
|
@ -478,15 +478,15 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
archive_entry_set_pathname(temp, "././@LongLink");
|
||||
archive_entry_set_size(temp, length);
|
||||
ret = archive_format_gnutar_header(a, buff, temp, 'K');
|
||||
archive_entry_free(temp);
|
||||
if (ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
ret = __archive_write_output(a, buff, 512);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
if (ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
archive_entry_free(temp);
|
||||
/* Write name and trailing null byte. */
|
||||
ret = __archive_write_output(a, gnutar->linkname, length);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
if (ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
/* Pad to 512 bytes */
|
||||
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
|
||||
@ -508,12 +508,12 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
archive_entry_set_pathname(temp, "././@LongLink");
|
||||
archive_entry_set_size(temp, length);
|
||||
ret = archive_format_gnutar_header(a, buff, temp, 'L');
|
||||
archive_entry_free(temp);
|
||||
if (ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
ret = __archive_write_output(a, buff, 512);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
archive_entry_free(temp);
|
||||
/* Write pathname + trailing null byte. */
|
||||
ret = __archive_write_output(a, pathname, length);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
|
@ -2524,7 +2524,8 @@ get_tmfromtime(struct tm *tm, time_t *t)
|
||||
tzset();
|
||||
localtime_r(t, tm);
|
||||
#elif HAVE__LOCALTIME64_S
|
||||
_localtime64_s(tm, t);
|
||||
__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
|
||||
_localtime64_s(tm, &tmp_t);
|
||||
#else
|
||||
memcpy(tm, localtime(t), sizeof(*tm));
|
||||
#endif
|
||||
@ -2553,7 +2554,7 @@ set_date_time(unsigned char *p, time_t t)
|
||||
static void
|
||||
set_date_time_null(unsigned char *p)
|
||||
{
|
||||
memset(p, '0', 16);
|
||||
memset(p, (int)'0', 16);
|
||||
p[16] = 0;
|
||||
}
|
||||
|
||||
@ -4073,7 +4074,8 @@ write_information_block(struct archive_write *a)
|
||||
memset(info.s, 0, info_size);
|
||||
opt = 0;
|
||||
#if defined(HAVE__CTIME64_S)
|
||||
_ctime64_s(buf, sizeof(buf), &(iso9660->birth_time));
|
||||
__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
|
||||
_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
|
||||
#elif defined(HAVE_CTIME_R)
|
||||
ctime_r(&(iso9660->birth_time), buf);
|
||||
#else
|
||||
|
@ -1961,6 +1961,7 @@ file_free(struct file *file)
|
||||
archive_string_free(&(file->basename));
|
||||
archive_string_free(&(file->symlink));
|
||||
archive_string_free(&(file->script));
|
||||
archive_entry_free(file->entry);
|
||||
free(file);
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,10 @@ IF(ENABLE_TEST)
|
||||
main.c
|
||||
read_open_memory.c
|
||||
test.h
|
||||
test_acl_freebsd_nfs4.c
|
||||
test_acl_freebsd_posix1e.c
|
||||
test_acl_nfs4.c
|
||||
test_acl_pax.c
|
||||
test_acl_platform_nfs4.c
|
||||
test_acl_platform_posix1e.c
|
||||
test_acl_posix1e.c
|
||||
test_acl_text.c
|
||||
test_archive_api_feature.c
|
||||
|
@ -216,6 +216,12 @@ invalid_parameter_handler(const wchar_t * expression,
|
||||
unsigned int line, uintptr_t pReserved)
|
||||
{
|
||||
/* nop */
|
||||
// Silence unused-parameter compiler warnings.
|
||||
(void)expression;
|
||||
(void)function;
|
||||
(void)file;
|
||||
(void)line;
|
||||
(void)pReserved;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1412,6 +1418,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
|
||||
failure_start(file, line, "assertFileMode not yet implemented for Windows");
|
||||
(void)mode; /* UNUSED */
|
||||
(void)r; /* UNUSED */
|
||||
(void)pathname; /* UNUSED */
|
||||
(void)expected_mode; /* UNUSED */
|
||||
#else
|
||||
{
|
||||
struct stat st;
|
||||
|
@ -120,6 +120,32 @@
|
||||
#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_ACL_USER
|
||||
#define HAVE_POSIX_ACL 1
|
||||
#elif HAVE_ACL_TYPE_EXTENDED
|
||||
#define HAVE_DARWIN_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_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
|
||||
#define HAVE_SUN_ACL 1
|
||||
#endif
|
||||
|
||||
/* Define if platform supports NFSv4 ACLs */
|
||||
#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
|
||||
#define HAVE_NFS4_ACL 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Redefine DEFINE_TEST for use in defining the test functions.
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2010 Tim Kientzle
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,10 +26,15 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 8
|
||||
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
|
||||
#define _ACL_PRIVATE
|
||||
#include <sys/acl.h>
|
||||
#if HAVE_DARWIN_ACL
|
||||
#include <membership.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_NFS4_ACL
|
||||
struct myacl_t {
|
||||
int type;
|
||||
int permset;
|
||||
@ -38,11 +44,12 @@ struct myacl_t {
|
||||
};
|
||||
|
||||
static struct myacl_t acls_reg[] = {
|
||||
#if !HAVE_DARWIN_ACL
|
||||
/* For this test, we need the file owner to be able to read and write the ACL. */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
|
||||
|
||||
#endif
|
||||
/* An entry for each type. */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
|
||||
@ -84,17 +91,53 @@ 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
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
|
||||
#else /* MacOS - mode 0654 */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
|
||||
#endif
|
||||
};
|
||||
|
||||
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
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
|
||||
#endif
|
||||
|
||||
/* An entry for each type. */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
@ -144,6 +187,9 @@ static struct myacl_t acls_dir[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
|
||||
ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
|
||||
ARCHIVE_ENTRY_ACL_USER, 305, "user305" },
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
@ -161,12 +207,47 @@ 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
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
|
||||
#else /* MacOS - mode 0654 */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
|
||||
#endif
|
||||
};
|
||||
|
||||
static const int acls_dir_cnt = (int)(sizeof(acls_dir)/sizeof(acls_dir[0]));
|
||||
|
||||
static void
|
||||
set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
|
||||
{
|
||||
@ -188,9 +269,50 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
|
||||
}
|
||||
|
||||
static int
|
||||
#ifdef HAVE_SUN_ACL
|
||||
acl_permset_to_bitmap(uint32_t a_access_mask)
|
||||
#else
|
||||
acl_permset_to_bitmap(acl_permset_t opaque_ps)
|
||||
#endif
|
||||
{
|
||||
static struct { int machine; int portable; } perms[] = {
|
||||
#ifdef HAVE_SUN_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},
|
||||
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE},
|
||||
#else /* FreeBSD NFSv4 ACL permissions */
|
||||
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
|
||||
{ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
|
||||
{ACL_READ, ARCHIVE_ENTRY_ACL_READ},
|
||||
@ -210,51 +332,201 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
|
||||
{ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
|
||||
{ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
|
||||
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
};
|
||||
int i, permset = 0;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
|
||||
#if HAVE_SUN_ACL
|
||||
if (a_access_mask & perms[i].machine)
|
||||
#else
|
||||
if (acl_get_perm_np(opaque_ps, perms[i].machine))
|
||||
#endif
|
||||
permset |= perms[i].portable;
|
||||
return permset;
|
||||
}
|
||||
|
||||
static int
|
||||
#if HAVE_SUN_ACL
|
||||
acl_flagset_to_bitmap(uint16_t a_flags)
|
||||
#else
|
||||
acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
|
||||
#endif
|
||||
{
|
||||
static struct { int machine; int portable; } flags[] = {
|
||||
#if HAVE_SUN_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},
|
||||
{ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
|
||||
#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}
|
||||
#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},
|
||||
#endif
|
||||
};
|
||||
int i, flagset = 0;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
|
||||
#if HAVE_SUN_ACL
|
||||
if (a_flags & flags[i].machine)
|
||||
#else
|
||||
if (acl_get_flag_np(opaque_fs, flags[i].machine))
|
||||
#endif
|
||||
flagset |= flags[i].portable;
|
||||
return flagset;
|
||||
}
|
||||
|
||||
static int
|
||||
#if HAVE_SUN_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_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_ACL */
|
||||
int perms;
|
||||
|
||||
#if HAVE_SUN_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_ACL
|
||||
switch (ace->a_type) {
|
||||
case ACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
return (0);
|
||||
break;
|
||||
case ACE_ACCESS_DENIED_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
|
||||
return (0);
|
||||
break;
|
||||
case ACE_SYSTEM_AUDIT_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT)
|
||||
return (0);
|
||||
break;
|
||||
case ACE_SYSTEM_ALARM_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (ace->a_flags & ACE_OWNER) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
return (0);
|
||||
} else if (ace->a_flags & ACE_GROUP) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
return (0);
|
||||
} else if (ace->a_flags & ACE_EVERYONE) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
return (0);
|
||||
} else if (ace->a_flags & ACE_IDENTIFIER_GROUP) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
|
||||
return (0);
|
||||
if ((gid_t)myacl->qual != ace->a_who)
|
||||
return (0);
|
||||
} else {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
|
||||
return (0);
|
||||
if ((uid_t)myacl->qual != ace->a_who)
|
||||
return (0);
|
||||
}
|
||||
#elif HAVE_DARWIN_ACL
|
||||
r = 0;
|
||||
switch (tag_type) {
|
||||
case ACL_EXTENDED_ALLOW:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
return (0);
|
||||
break;
|
||||
case ACL_EXTENDED_DENY:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
q = acl_get_qualifier(aclent);
|
||||
if (q == NULL)
|
||||
return (0);
|
||||
r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
|
||||
acl_free(q);
|
||||
if (r != 0)
|
||||
return (0);
|
||||
switch (idtype) {
|
||||
case ID_TYPE_UID:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
|
||||
return (0);
|
||||
if ((uid_t)myacl->qual != ugid)
|
||||
return (0);
|
||||
break;
|
||||
case ID_TYPE_GID:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
|
||||
return (0);
|
||||
if ((gid_t)myacl->qual != ugid)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
#else /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
switch (entry_type) {
|
||||
case ACL_ENTRY_TYPE_ALLOW:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
return (0);
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_DENY:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
|
||||
return (0);
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_AUDIT:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT)
|
||||
return (0);
|
||||
case ACL_ENTRY_TYPE_ALARM:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM)
|
||||
return (0);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
||||
switch (tag_type) {
|
||||
case ACL_USER_OBJ:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
|
||||
@ -287,17 +559,29 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
|
||||
break;
|
||||
}
|
||||
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start, int end)
|
||||
compare_acls(
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl,
|
||||
#else
|
||||
acl_t acl,
|
||||
#endif
|
||||
struct myacl_t *myacls, const char *filename, int start, int end)
|
||||
{
|
||||
int *marker;
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
int matched;
|
||||
int i, n;
|
||||
#if HAVE_SUN_ACL
|
||||
int e;
|
||||
ace_t *acl_entry;
|
||||
#else
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
acl_entry_t acl_entry;
|
||||
#endif
|
||||
|
||||
n = end - start;
|
||||
marker = malloc(sizeof(marker[0]) * (n + 1));
|
||||
@ -313,10 +597,20 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
|
||||
* Iterate over acls in system acl object, try to match each
|
||||
* one with an item in the myacls array.
|
||||
*/
|
||||
while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
|
||||
#if HAVE_SUN_ACL
|
||||
for (e = 0; e < acl->acl_cnt; 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))
|
||||
#endif
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
acl_entry = &((ace_t *)acl->acl_aclp)[e];
|
||||
#else
|
||||
/* After the first time... */
|
||||
entry_id = ACL_NEXT_ENTRY;
|
||||
|
||||
#endif
|
||||
/* Search for a matching entry (tag and qualifier) */
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
if (acl_match(acl_entry, &myacls[marker[i]])) {
|
||||
@ -327,7 +621,8 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
|
||||
}
|
||||
}
|
||||
|
||||
failure("ACL entry on file %s that shouldn't be there", filename);
|
||||
failure("ACL entry on file %s that shouldn't be there",
|
||||
filename);
|
||||
assert(matched == 1);
|
||||
}
|
||||
|
||||
@ -368,7 +663,8 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
|
||||
* Iterate over acls in entry, try to match each
|
||||
* one with an item in the myacls array.
|
||||
*/
|
||||
assertEqualInt(n, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
assertEqualInt(n, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
while (ARCHIVE_OK == archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) {
|
||||
|
||||
@ -403,54 +699,110 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
|
||||
}
|
||||
free(marker);
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
/*
|
||||
* Verify ACL restore-to-disk. This test is FreeBSD-specific.
|
||||
* Verify ACL restore-to-disk. This test is Platform-specific.
|
||||
*/
|
||||
|
||||
DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
DEFINE_TEST(test_acl_platform_nfs4)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
skipping("FreeBSD-specific NFS4 ACL restore test");
|
||||
#elif __FreeBSD__ < 8
|
||||
skipping("NFS4 ACLs supported only on FreeBSD 8.0 and later");
|
||||
#if !HAVE_NFS4_ACL
|
||||
skipping("NFS4 ACLs are not supported on this platform");
|
||||
#else
|
||||
char buff[64];
|
||||
struct stat st;
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
int i, n;
|
||||
char *func;
|
||||
#if HAVE_DARWIN_ACL /* 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_ACL
|
||||
acl_t *acl;
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
#if HAVE_DARWIN_ACL
|
||||
acl_entry_t aclent;
|
||||
acl_permset_t permset;
|
||||
const uid_t uid = 1000;
|
||||
uuid_t uuid;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
acl_t acl;
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
|
||||
/*
|
||||
* First, do a quick manual set/read of ACL data to
|
||||
* verify that the local filesystem does support ACLs.
|
||||
* If it doesn't, we'll simply skip the remaining tests.
|
||||
*/
|
||||
#if HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4
|
||||
acl = acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl != NULL);
|
||||
#elif HAVE_DARWIN_ACL
|
||||
acl = acl_init(1);
|
||||
assert((void *)acl != NULL);
|
||||
assertEqualInt(0, acl_create_entry(&acl, &aclent));
|
||||
assertEqualInt(0, acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW));
|
||||
assertEqualInt(0, acl_get_permset(aclent, &permset));
|
||||
assertEqualInt(0, acl_add_perm(permset, ACL_READ_DATA));
|
||||
assertEqualInt(0, acl_add_perm(permset, ACL_WRITE_DATA));
|
||||
assertEqualInt(0, acl_add_perm(permset, ACL_APPEND_DATA));
|
||||
assertEqualInt(0, acl_add_perm(permset, ACL_EXECUTE));
|
||||
assertEqualInt(0, acl_set_permset(aclent, permset));
|
||||
assertEqualInt(0, mbr_identifier_to_uuid(ID_TYPE_UID, &uid,
|
||||
sizeof(uid_t), uuid));
|
||||
assertEqualInt(0, acl_set_qualifier(aclent, uuid));
|
||||
#endif
|
||||
|
||||
/* Create a test dir and try to set an ACL on it. */
|
||||
if (!assertMakeDir("pretest", 0755)) {
|
||||
#if !HAVE_SUN_ACL
|
||||
acl_free(acl);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
func = "acl_get()";
|
||||
n = acl_get("pretest", 0, &acl);
|
||||
#else
|
||||
func = "acl_set_file()";
|
||||
#if HAVE_DARWIN_ACL
|
||||
n = acl_set_file("pretest", ACL_TYPE_EXTENDED, acl);
|
||||
#else
|
||||
n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
|
||||
#endif
|
||||
acl_free(acl);
|
||||
if (n != 0 && errno == EOPNOTSUPP) {
|
||||
skipping("NFS4 ACL tests require that NFS4 ACLs"
|
||||
" be enabled on the filesystem");
|
||||
return;
|
||||
#endif
|
||||
if (n != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
if (errno == ENOSYS)
|
||||
#else
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL)
|
||||
#endif
|
||||
{
|
||||
skipping("NFS4 ACL is not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (n != 0 && errno == EINVAL) {
|
||||
skipping("This filesystem does not support NFS4 ACLs");
|
||||
return;
|
||||
}
|
||||
failure("acl_set_file(): errno = %d (%s)",
|
||||
errno, strerror(errno));
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl->acl_type != ACE_T) {
|
||||
acl_free(acl);
|
||||
skipping("NFS4 ACL is not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
acl_free(acl);
|
||||
#endif
|
||||
|
||||
/* Create a write-to-disk object. */
|
||||
assert(NULL != (a = archive_write_disk_new()));
|
||||
archive_write_disk_set_options(a,
|
||||
@ -464,7 +816,7 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
archive_entry_set_perm(ae, 0654);
|
||||
archive_entry_set_mtime(ae, 123456, 7890);
|
||||
archive_entry_set_size(ae, 0);
|
||||
set_acls(ae, acls_reg, 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
|
||||
set_acls(ae, acls_reg, 0, acls_reg_cnt);
|
||||
|
||||
/* Write the entry to disk, including ACLs. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
||||
@ -474,10 +826,10 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
archive_entry_set_filetype(ae, AE_IFDIR);
|
||||
archive_entry_set_perm(ae, 0654);
|
||||
archive_entry_set_mtime(ae, 123456, 7890);
|
||||
set_acls(ae, acls_dir, 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
|
||||
set_acls(ae, acls_dir, 0, acls_dir_cnt);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
||||
|
||||
for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
|
||||
for (i = 0; i < acls_dir_cnt; ++i) {
|
||||
sprintf(buff, "dir%d", i);
|
||||
archive_entry_set_pathname(ae, buff);
|
||||
archive_entry_set_filetype(ae, AE_IFDIR);
|
||||
@ -496,28 +848,62 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
/* Verify the data on disk. */
|
||||
assertEqualInt(0, stat("testall", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_get("testall", 0, &acl);
|
||||
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
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));
|
||||
assert(acl != (acl_t)NULL);
|
||||
compare_acls(acl, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
|
||||
#endif
|
||||
compare_acls(acl, acls_reg, "testall", 0, regcnt);
|
||||
acl_free(acl);
|
||||
|
||||
/* Verify single-permission dirs on disk. */
|
||||
for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
|
||||
sprintf(buff, "dir%d", i);
|
||||
assertEqualInt(0, stat(buff, &st));
|
||||
assertEqualInt(st.st_mtime, 123456 + i);
|
||||
acl = acl_get_file(buff, ACL_TYPE_NFS4);
|
||||
assert(acl != (acl_t)NULL);
|
||||
compare_acls(acl, acls_dir, buff, i, i + 1);
|
||||
acl_free(acl);
|
||||
for (i = 0; i < dircnt; ++i) {
|
||||
sprintf(buff, "dir%d", i);
|
||||
assertEqualInt(0, stat(buff, &st));
|
||||
assertEqualInt(st.st_mtime, 123456 + i);
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_get(buff, 0, &acl);
|
||||
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
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,
|
||||
strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
#endif
|
||||
compare_acls(acl, acls_dir, buff, i, i + 1);
|
||||
acl_free(acl);
|
||||
}
|
||||
|
||||
/* Verify "dirall" on disk. */
|
||||
assertEqualInt(0, stat("dirall", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_get("dirall", 0, &acl);
|
||||
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
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));
|
||||
assert(acl != (acl_t)NULL);
|
||||
compare_acls(acl, acls_dir, "dirall", 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
|
||||
#endif
|
||||
compare_acls(acl, acls_dir, "dirall", 0, dircnt);
|
||||
acl_free(acl);
|
||||
|
||||
/* Read and compare ACL via archive_read_disk */
|
||||
@ -528,7 +914,7 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
archive_entry_set_pathname(ae, "testall");
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_read_disk_entry_from_file(a, ae, -1, NULL));
|
||||
compare_entry_acls(ae, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
|
||||
compare_entry_acls(ae, acls_reg, "testall", 0, acls_reg_cnt);
|
||||
archive_entry_free(ae);
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
@ -539,9 +925,9 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
assert(ae != NULL);
|
||||
archive_entry_set_pathname(ae, "dirall");
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_read_disk_entry_from_file(a, ae, -1, NULL));
|
||||
compare_entry_acls(ae, acls_dir, "dirall", 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
|
||||
archive_read_disk_entry_from_file(a, ae, -1, NULL));
|
||||
compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt);
|
||||
archive_entry_free(ae);
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
#endif
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2008 Tim Kientzle
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,8 +26,14 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $");
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ > 4
|
||||
#if HAVE_POSIX_ACL || HAVE_SUN_ACL
|
||||
#include <sys/acl.h>
|
||||
#if HAVE_ACL_GET_PERM
|
||||
#include <acl/libacl.h>
|
||||
#define ACL_GET_PERM acl_get_perm
|
||||
#elif HAVE_ACL_GET_PERM_NP
|
||||
#define ACL_GET_PERM acl_get_perm_np
|
||||
#endif
|
||||
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -48,18 +55,34 @@ static struct archive_test_acl_t acls2[] = {
|
||||
};
|
||||
|
||||
static int
|
||||
acl_entry_get_perm(acl_entry_t aclent) {
|
||||
#if HAVE_SUN_ACL
|
||||
acl_entry_get_perm(aclent_t *aclent)
|
||||
#else
|
||||
acl_entry_get_perm(acl_entry_t aclent)
|
||||
#endif
|
||||
{
|
||||
int permset = 0;
|
||||
#if HAVE_POSIX_ACL
|
||||
acl_permset_t opaque_ps;
|
||||
#endif
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
if (aclent->a_perm & 1)
|
||||
permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
if (aclent->a_perm & 2)
|
||||
permset |= ARCHIVE_ENTRY_ACL_WRITE;
|
||||
if (aclent->a_perm & 4)
|
||||
permset |= ARCHIVE_ENTRY_ACL_READ;
|
||||
#else
|
||||
/* translate the silly opaque permset to a bitmap */
|
||||
acl_get_permset(aclent, &opaque_ps);
|
||||
if (acl_get_perm_np(opaque_ps, ACL_EXECUTE))
|
||||
if (ACL_GET_PERM(opaque_ps, ACL_EXECUTE))
|
||||
permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
if (acl_get_perm_np(opaque_ps, ACL_WRITE))
|
||||
if (ACL_GET_PERM(opaque_ps, ACL_WRITE))
|
||||
permset |= ARCHIVE_ENTRY_ACL_WRITE;
|
||||
if (acl_get_perm_np(opaque_ps, ACL_READ))
|
||||
if (ACL_GET_PERM(opaque_ps, ACL_READ))
|
||||
permset |= ARCHIVE_ENTRY_ACL_READ;
|
||||
#endif
|
||||
return permset;
|
||||
}
|
||||
|
||||
@ -105,45 +128,96 @@ acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_ta
|
||||
#endif
|
||||
|
||||
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) {
|
||||
switch (tag_type)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
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;
|
||||
}
|
||||
@ -151,13 +225,22 @@ acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
|
||||
}
|
||||
|
||||
static void
|
||||
#if HAVE_SUN_ACL
|
||||
compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n)
|
||||
#else
|
||||
compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
#endif
|
||||
{
|
||||
int *marker;
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
int matched;
|
||||
int i;
|
||||
#if HAVE_SUN_ACL
|
||||
int e;
|
||||
aclent_t *acl_entry;
|
||||
#else
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
acl_entry_t acl_entry;
|
||||
#endif
|
||||
|
||||
/* Count ACL entries in myacls array and allocate an indirect array. */
|
||||
marker = malloc(sizeof(marker[0]) * n);
|
||||
@ -170,9 +253,14 @@ 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
|
||||
for(e = 0; e < acl->acl_cnt; e++) {
|
||||
acl_entry = &((aclent_t *)acl->acl_aclp)[e];
|
||||
#else
|
||||
while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
|
||||
/* After the first time... */
|
||||
entry_id = ACL_NEXT_ENTRY;
|
||||
#endif
|
||||
|
||||
/* Search for a matching entry (tag and qualifier) */
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
@ -205,30 +293,41 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
|
||||
|
||||
/*
|
||||
* Verify ACL restore-to-disk. This test is FreeBSD-specific.
|
||||
* Verify ACL restore-to-disk. This test is Platform-specific.
|
||||
*/
|
||||
|
||||
DEFINE_TEST(test_acl_freebsd_posix1e_restore)
|
||||
DEFINE_TEST(test_acl_platform_posix1e_restore)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
skipping("FreeBSD-specific ACL restore test");
|
||||
#elif __FreeBSD__ < 5
|
||||
skipping("ACL restore supported only on FreeBSD 5.0 and later");
|
||||
#else
|
||||
#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
|
||||
skipping("POSIX.1e ACLs are not supported on this platform");
|
||||
#else /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
|
||||
struct stat st;
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
int n, fd;
|
||||
char *func;
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl, *acl2;
|
||||
#else
|
||||
acl_t acl;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* First, do a quick manual set/read of ACL data to
|
||||
* verify that the local filesystem does support ACLs.
|
||||
* If it doesn't, we'll simply skip the remaining tests.
|
||||
*/
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl);
|
||||
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl != NULL);
|
||||
/* Create a test file and try to set an ACL on it. */
|
||||
#endif
|
||||
|
||||
/* Create a test file and try ACL on it. */
|
||||
fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
failure("Could not create test file?!");
|
||||
if (!assert(fd >= 0)) {
|
||||
@ -236,21 +335,51 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
|
||||
return;
|
||||
}
|
||||
|
||||
n = acl_set_fd(fd, acl);
|
||||
acl_free(acl);
|
||||
if (n != 0 && errno == EOPNOTSUPP) {
|
||||
#if HAVE_SUN_ACL
|
||||
n = facl_get(fd, 0, &acl2);
|
||||
if (n != 0) {
|
||||
close(fd);
|
||||
skipping("ACL tests require that ACL support be enabled on the filesystem");
|
||||
acl_free(acl);
|
||||
}
|
||||
if (errno == ENOSYS) {
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
if (n != 0 && errno == EINVAL) {
|
||||
close(fd);
|
||||
skipping("This filesystem does not support POSIX.1e ACLs");
|
||||
return;
|
||||
}
|
||||
failure("acl_set_fd(): errno = %d (%s)",
|
||||
errno, strerror(errno));
|
||||
failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
if (acl2->acl_type != ACLENT_T) {
|
||||
acl_free(acl2);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
acl_free(acl2);
|
||||
|
||||
func = "facl_set()";
|
||||
n = facl_set(fd, acl);
|
||||
#else
|
||||
func = "acl_set_fd()";
|
||||
n = acl_set_fd(fd, acl);
|
||||
#endif
|
||||
acl_free(acl);
|
||||
if (n != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
if (errno == ENOSYS)
|
||||
#else
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL)
|
||||
#endif
|
||||
{
|
||||
close(fd);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
}
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
|
||||
#endif
|
||||
close(fd);
|
||||
|
||||
/* Create a write-to-disk object. */
|
||||
@ -275,28 +404,38 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
|
||||
/* Verify the data on disk. */
|
||||
assertEqualInt(0, stat("test0", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_get("test0", 0, &acl);
|
||||
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl = acl_get_file("test0", ACL_TYPE_ACCESS);
|
||||
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
#endif
|
||||
compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
acl_free(acl);
|
||||
#endif
|
||||
#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify ACL read-from-disk. This test is FreeBSD-specific.
|
||||
* Verify ACL read-from-disk. This test is Platform-specific.
|
||||
*/
|
||||
DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
skipping("FreeBSD-specific ACL read test");
|
||||
#elif __FreeBSD__ < 5
|
||||
skipping("ACL read supported only on FreeBSD 5.0 and later");
|
||||
#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
|
||||
skipping("POSIX.1e ACLs are not supported on this platform");
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
int n, fd;
|
||||
const char *acl1_text, *acl2_text;
|
||||
acl_t acl1, acl2;
|
||||
int n, fd, flags, dflags;
|
||||
char *func, *acl_text;
|
||||
const char *acl1_text, *acl2_text, *acl3_text;
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl, *acl1, *acl2, *acl3;
|
||||
#else
|
||||
acl_t acl1, acl2, acl3;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Manually construct a directory and two files with
|
||||
@ -305,6 +444,17 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
*/
|
||||
|
||||
/* Create a test file f1 with acl1 */
|
||||
#if HAVE_SUN_ACL
|
||||
acl1_text = "user::rwx,"
|
||||
"group::rwx,"
|
||||
"other:rwx,"
|
||||
"user:1:rw-,"
|
||||
"group:15:r-x,"
|
||||
"mask:rwx";
|
||||
n = acl_fromtext(acl1_text, &acl1);
|
||||
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl1_text = "user::rwx\n"
|
||||
"group::rwx\n"
|
||||
"other::rwx\n"
|
||||
@ -312,28 +462,59 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
"group:15:r-x\n"
|
||||
"mask::rwx";
|
||||
acl1 = acl_from_text(acl1_text);
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl1 != NULL);
|
||||
#endif
|
||||
fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
failure("Could not create test file?!");
|
||||
if (!assert(fd >= 0)) {
|
||||
acl_free(acl1);
|
||||
return;
|
||||
}
|
||||
n = acl_set_fd(fd, acl1);
|
||||
acl_free(acl1);
|
||||
if (n != 0 && errno == EOPNOTSUPP) {
|
||||
#if HAVE_SUN_ACL
|
||||
/* Check if Solars filesystem supports POSIX.1e ACLs */
|
||||
n = facl_get(fd, 0, &acl);
|
||||
if (n != 0)
|
||||
close(fd);
|
||||
skipping("ACL tests require that ACL support be enabled on the filesystem");
|
||||
if (n != 0 && errno == ENOSYS) {
|
||||
acl_free(acl1);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
if (n != 0 && errno == EINVAL) {
|
||||
close(fd);
|
||||
skipping("This filesystem does not support POSIX.1e ACLs");
|
||||
return;
|
||||
}
|
||||
failure("acl_set_fd(): errno = %d (%s)",
|
||||
errno, strerror(errno));
|
||||
failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
if (acl->acl_type != ACLENT_T) {
|
||||
acl_free(acl);
|
||||
acl_free(acl1);
|
||||
close(fd);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
|
||||
func = "facl_set()";
|
||||
n = facl_set(fd, acl1);
|
||||
#else
|
||||
func = "acl_set_fd()";
|
||||
n = acl_set_fd(fd, acl1);
|
||||
#endif
|
||||
acl_free(acl1);
|
||||
|
||||
if (n != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
if (errno == ENOSYS)
|
||||
#else
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL)
|
||||
#endif
|
||||
{
|
||||
close(fd);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
}
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
close(fd);
|
||||
|
||||
assertMakeDir("d", 0700);
|
||||
@ -349,6 +530,17 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
* to read ACLs, resulting in reading the ACL from a like-named
|
||||
* file in the wrong directory.
|
||||
*/
|
||||
#if HAVE_SUN_ACL
|
||||
acl2_text = "user::rwx,"
|
||||
"group::rwx,"
|
||||
"other:---,"
|
||||
"user:1:r--,"
|
||||
"group:15:r--,"
|
||||
"mask:rwx";
|
||||
n = acl_fromtext(acl2_text, &acl2);
|
||||
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl2_text = "user::rwx\n"
|
||||
"group::rwx\n"
|
||||
"other::---\n"
|
||||
@ -356,46 +548,106 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
"group:15:r--\n"
|
||||
"mask::rwx";
|
||||
acl2 = acl_from_text(acl2_text);
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl2 != NULL);
|
||||
#endif
|
||||
fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
failure("Could not create test file?!");
|
||||
if (!assert(fd >= 0)) {
|
||||
acl_free(acl2);
|
||||
return;
|
||||
}
|
||||
#if HAVE_SUN_ACL
|
||||
func = "facl_set()";
|
||||
n = facl_set(fd, acl2);
|
||||
#else
|
||||
func = "acl_set_fd()";
|
||||
n = acl_set_fd(fd, acl2);
|
||||
#endif
|
||||
acl_free(acl2);
|
||||
if (n != 0 && errno == EOPNOTSUPP) {
|
||||
if (n != 0)
|
||||
close(fd);
|
||||
skipping("ACL tests require that ACL support be enabled on the filesystem");
|
||||
return;
|
||||
}
|
||||
if (n != 0 && errno == EINVAL) {
|
||||
close(fd);
|
||||
skipping("This filesystem does not support POSIX.1e ACLs");
|
||||
return;
|
||||
}
|
||||
failure("acl_set_fd(): errno = %d (%s)",
|
||||
errno, strerror(errno));
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
close(fd);
|
||||
|
||||
/* Create directory d2 with default ACLs */
|
||||
assertMakeDir("d2", 0755);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
acl3_text = "user::rwx,"
|
||||
"group::r-x,"
|
||||
"other:r-x,"
|
||||
"user:2:r--,"
|
||||
"group:16:-w-,"
|
||||
"mask:rwx,"
|
||||
"default:user::rwx,"
|
||||
"default:user:1:r--,"
|
||||
"default:group::r-x,"
|
||||
"default:group:15:r--,"
|
||||
"default:mask:rwx,"
|
||||
"default:other:r-x";
|
||||
n = acl_fromtext(acl3_text, &acl3);
|
||||
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl3_text = "user::rwx\n"
|
||||
"user:1:r--\n"
|
||||
"group::r-x\n"
|
||||
"group:15:r--\n"
|
||||
"mask::rwx\n"
|
||||
"other::r-x";
|
||||
acl3 = acl_from_text(acl3_text);
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl3 != NULL);
|
||||
#endif
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
func = "acl_set()";
|
||||
n = acl_set("d2", acl3);
|
||||
#else
|
||||
func = "acl_set_file()";
|
||||
n = acl_set_file("d2", ACL_TYPE_DEFAULT, acl3);
|
||||
#endif
|
||||
acl_free(acl3);
|
||||
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
/* Create a read-from-disk object. */
|
||||
assert(NULL != (a = archive_read_disk_new()));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
|
||||
assert(NULL != (ae = archive_entry_new()));
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E
|
||||
| ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA
|
||||
| ARCHIVE_ENTRY_ACL_STYLE_SOLARIS;
|
||||
dflags = flags;
|
||||
#else
|
||||
flags = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
dflags = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
|
||||
#endif
|
||||
|
||||
/* Walk the dir until we see both of the files */
|
||||
while (ARCHIVE_OK == archive_read_next_header2(a, ae)) {
|
||||
archive_read_disk_descend(a);
|
||||
if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
|
||||
assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl1_text);
|
||||
|
||||
acl_text = archive_entry_acl_to_text(ae, NULL, flags);
|
||||
assertEqualString(acl_text, acl1_text);
|
||||
free(acl_text);
|
||||
} else if (strcmp(archive_entry_pathname(ae), "./d/f1") == 0) {
|
||||
assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl2_text);
|
||||
acl_text = archive_entry_acl_to_text(ae, NULL, flags);
|
||||
assertEqualString(acl_text, acl2_text);
|
||||
free(acl_text);
|
||||
} else if (strcmp(archive_entry_pathname(ae), "./d2") == 0) {
|
||||
acl_text = archive_entry_acl_to_text(ae, NULL, dflags);
|
||||
assertEqualString(acl_text, acl3_text);
|
||||
free(acl_text);
|
||||
}
|
||||
}
|
||||
|
||||
archive_free(a);
|
||||
archive_entry_free(ae);
|
||||
assertEqualInt(ARCHIVE_OK, archive_free(a));
|
||||
#endif
|
||||
}
|
@ -242,8 +242,8 @@ convert_s_to_ws(const char *s)
|
||||
static void
|
||||
compare_acl_text(struct archive_entry *ae, int flags, const char *s)
|
||||
{
|
||||
const char *text;
|
||||
const wchar_t *wtext;
|
||||
char *text;
|
||||
wchar_t *wtext;
|
||||
wchar_t *ws;
|
||||
ssize_t slen;
|
||||
|
||||
@ -257,9 +257,10 @@ compare_acl_text(struct archive_entry *ae, int flags, const char *s)
|
||||
assertEqualWString(wtext, ws);
|
||||
if (wtext != NULL) {
|
||||
assertEqualInt(wcslen(wtext), slen);
|
||||
free(ws);
|
||||
ws = NULL;
|
||||
}
|
||||
free(text);
|
||||
free(wtext);
|
||||
free(ws);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_from_text)
|
||||
@ -395,6 +396,9 @@ DEFINE_TEST(test_acl_from_text)
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
free(ws);
|
||||
archive_entry_free(ae);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_to_text)
|
||||
@ -453,4 +457,6 @@ DEFINE_TEST(test_acl_to_text)
|
||||
|
||||
/* NFSv4 ACLs like "getfacl -i" on FreeBSD */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[10]);
|
||||
|
||||
archive_entry_free(ae);
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ test_archive_string_ensure(void)
|
||||
|
||||
assert(&s == archive_string_ensure(&s, EXTENT + 1));
|
||||
assertNonNULLString(0, 2 * EXTENT, s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -92,6 +94,8 @@ test_archive_strcat(void)
|
||||
/* non-empty target, non-empty source */
|
||||
assert(&s == archive_strcat(&s, "baz"));
|
||||
assertExactString(8, EXTENT, "fubarbaz", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -109,6 +113,8 @@ test_archive_strappend_char(void)
|
||||
/* non-empty target */
|
||||
archive_strappend_char(&s, 'Y');
|
||||
assertExactString(2, EXTENT, "XY", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
/* archive_strnXXX() tests focus on length handling.
|
||||
@ -134,6 +140,8 @@ test_archive_strncat(void)
|
||||
/* long read is ok too! */
|
||||
assert(&s == archive_strncat(&s, "snafu", 8));
|
||||
assertExactString(13, EXTENT, "snafubarsnafu", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -155,6 +163,8 @@ test_archive_strncpy(void)
|
||||
/* long read is ok too! */
|
||||
assert(&s == archive_strncpy(&s, "snafu", 8));
|
||||
assertExactString(5, EXTENT, "snafu", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -176,6 +186,8 @@ test_archive_strcpy(void)
|
||||
/* dirty target, empty source */
|
||||
assert(&s == archive_strcpy(&s, ""));
|
||||
assertExactString(0, EXTENT, "", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -222,6 +234,11 @@ test_archive_string_concat(void)
|
||||
archive_string_concat(&t, &s);
|
||||
assertExactString(5, EXTENT, "snafu", s);
|
||||
assertExactString(5, EXTENT, "snafu", t);
|
||||
|
||||
archive_string_free(&v);
|
||||
archive_string_free(&u);
|
||||
archive_string_free(&t);
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -274,6 +291,11 @@ test_archive_string_copy(void)
|
||||
archive_string_copy(&t, &s);
|
||||
assertExactString(5, EXTENT, "fubar", s);
|
||||
assertExactString(5, EXTENT, "fubar", t);
|
||||
|
||||
archive_string_free(&v);
|
||||
archive_string_free(&u);
|
||||
archive_string_free(&t);
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -328,6 +350,8 @@ test_archive_string_sprintf(void)
|
||||
archive_string_empty(&s);
|
||||
archive_string_sprintf(&s, "%d", 1234567890);
|
||||
assertExactString(10, 8 * EXTENT, "1234567890", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string)
|
||||
|
@ -142,6 +142,8 @@ test_compat_gtar_2(void)
|
||||
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
|
||||
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_compat_gtar)
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -23,104 +24,242 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_compat_solaris_tar_acl.c 201247 2009-12-30 05:59:21Z kientzle $");
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Exercise support for reading Solaris-style ACL data
|
||||
* from tar archives.
|
||||
* Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created
|
||||
* with Solaris tar.
|
||||
*
|
||||
* This should work on all systems, regardless of whether local
|
||||
* filesystems support ACLs or not.
|
||||
* This should work on all systems, regardless of whether local filesystems
|
||||
* support ACLs or not.
|
||||
*/
|
||||
|
||||
static struct archive_test_acl_t acls0[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 71, "lp" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 666, "666" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 1000, "1000" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls1[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls3[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 12, "daemon" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 2, "bin" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 4, "adm" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls4[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
|
||||
ARCHIVE_ENTRY_ACL_USER, 1100, "1100" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 4, "adm" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_DELETE_CHILD |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
DEFINE_TEST(test_compat_solaris_tar_acl)
|
||||
{
|
||||
char name[] = "test_compat_solaris_tar_acl.tar";
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
const char *reference1 = "test_compat_solaris_tar_acl.tar";
|
||||
int type, permset, tag, qual;
|
||||
const char *name;
|
||||
|
||||
/* Sample file generated on Solaris 10 */
|
||||
extract_reference_file(reference1);
|
||||
/* Read archive file */
|
||||
assert(NULL != (a = archive_read_new()));
|
||||
assertA(0 == archive_read_support_format_all(a));
|
||||
assertA(0 == archive_read_support_filter_all(a));
|
||||
assertA(0 == archive_read_open_filename(a, reference1, 512));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name,
|
||||
10240));
|
||||
|
||||
/* Archive has 1 entry with some ACLs set on it. */
|
||||
/* First item has access ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
failure("One extended ACL should flag all ACLs to be returned.");
|
||||
assertEqualInt(7, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0644);
|
||||
failure("Basic ACLs should set mode to 0644, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assertEqualInt((archive_entry_mode(ae) & 0777), 0644);
|
||||
assertEqualInt(7, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(006, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_USER_OBJ, tag);
|
||||
assertEqualInt(-1, qual);
|
||||
assert(name == NULL);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0644);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(004, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_GROUP_OBJ, tag);
|
||||
assertEqualInt(-1, qual);
|
||||
assert(name == NULL);
|
||||
/* Second item has default and access ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0750);
|
||||
failure("Basic ACLs should set mode to 0750, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0750);
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0750);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(004, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_OTHER, tag);
|
||||
assertEqualInt(-1, qual);
|
||||
assert(name == NULL);
|
||||
/* Third item has NFS4 ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(001, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
|
||||
assertEqualInt(71, qual);
|
||||
assertEqualString(name, "lp");
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(004, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
|
||||
assertEqualInt(666, qual);
|
||||
assertEqualString(name, "666");
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(007, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
|
||||
assertEqualInt(1000, qual);
|
||||
assertEqualString(name, "trasz");
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(004, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_MASK, tag);
|
||||
assertEqualInt(-1, qual);
|
||||
assertEqualString(name, NULL);
|
||||
|
||||
assertEqualInt(ARCHIVE_EOF, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
/* Fourth item has NFS4 ACLs and inheritance flags */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(5, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
/* Close the archive. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
|
@ -1,61 +1,163 @@
|
||||
$FreeBSD: head/lib/libarchive/test/test_compat_solaris_tar_acl.tar.uu 191576 2009-04-27 18:27:54Z kientzle $
|
||||
begin 644 test_acl_solaris.tar
|
||||
M9FEL92UW:71H+7!O<VEX+6%C;',`````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````#`P,#`V-#0`,#`P,3<U,``P,#`P,#`P`#`P,#`P,#`P,30T
|
||||
M`#$Q,3<T-C`T,34W`#`P,34Q-S8`00``````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````!U<W1A<@`P,'1R87-Z
|
||||
M````````````````````````````````````<F]O=```````````````````
|
||||
M```````````````````P,#`P,C$P`#`P,#`P,3``````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````Q,#`P,#`W`'5S97(Z.G)W+2QU<V5R.FQP.BTM
|
||||
M>#HW,2QU<V5R.C8V-CIR+2TZ-C8V+'5S97(Z=')A<WHZ<G=X.C$P,#`L9W)O
|
||||
M=7`Z.G(M+2QM87-K.G(M+2QO=&AE<CIR+2T``````````3````````/-@```
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````!%&8`````````&L`````,3`P,#`P-P!U
|
||||
begin 644 test_compat_solaris_tar_acl.tar
|
||||
M9FEL92UW:71H+7!O<VEX+6%C;',
|
||||
M
|
||||
M # P,# V-#0 ,# P,3<U, P,# P,# P # P,# P,# P,30S
|
||||
M #$Q,3<T-C T,34W # P,30Q,C$ 00
|
||||
M
|
||||
M !U<W1A<@ P,
|
||||
M <F]O=
|
||||
M P,# P-#$T # P,# P,#,
|
||||
M
|
||||
M
|
||||
M
|
||||
M Q,# P,# W '5S97(Z.G)W+2QU<V5R.FQP.BTM
|
||||
M>#HW,2QU<V5R.C8V-CIR+2TZ-C8V+'5S97(Z,3 P,#IR=W@Z,3 P,"QG<F]U
|
||||
M<#HZ<BTM+&UA<VLZ<BTM+&]T:&5R.G(M+0 # !
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M (Q@@( &L ,3 P,# P-P!U
|
||||
M<V5R.CIR=RTL=7-E<CIL<#HM+7@Z-S$L=7-E<CHV-C8Z<BTM.C8V-BQU<V5R
|
||||
M.G1R87-Z.G)W>#HQ,#`P+&=R;W5P.CIR+2TL;6%S:SIR+69I;&4M=VET:"UP
|
||||
M;W-I>"UA8VQS````````````````````````````````````````````````
|
||||
M```````````````````````````````````````````````````````````P
|
||||
M,#`P-C0T`#`P,#$W-3``,#`P,#`P,``P,#`P,#`P,#`P,``Q,3$W-#8P-#$U
|
||||
M-P`P,#$U,30T`#``````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````=7-T87(`,#!T<F%S>@``````````````
|
||||
M`````````````````````')O;W0`````````````````````````````````
|
||||
M````,#`P,#(Q,``P,#`P,#$P````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
H````````````````````````````````````````````````````````
|
||||
`
|
||||
M.C$P,# Z<G=X.C$P,# L9W)O=7 Z.G(M+2QM87-K.G(M+69I;&4M=VET:"UP
|
||||
M;W-I>"UA8VQS
|
||||
M P
|
||||
M,# P-C0T # P,#$W-3 ,# P,# P, P,# P,# P,# P, Q,3$W-#8P-#$U
|
||||
M-P P,#$T,#<P #
|
||||
M
|
||||
M =7-T87( ,#
|
||||
M ')O;W0
|
||||
M ,# P,#0Q- P,# P,# S
|
||||
M
|
||||
M
|
||||
M
|
||||
M 9&ER+7=I=&@M<&]S:7@M86-L<R\
|
||||
M
|
||||
M # P,# W-3 ,# P,3<U, P,# P,# P # P,# P
|
||||
M,# P,S P #$S,#,V-3$R,C4T # P,30P,C, 00
|
||||
M
|
||||
M !U<W1A<@ P
|
||||
M, <F]O=
|
||||
M P,# P-#$T # P,# P,#,
|
||||
M
|
||||
M
|
||||
M
|
||||
M Q,# P,#$T '5S97(Z.G)W>"QU<V5R
|
||||
M.F)I;CIR=W@Z,BQG<F]U<#HZ<BUX+&=R;W5P.G-Y<SIR+7@Z,RQM87-K.G(M
|
||||
M>"QO=&AE<CHM+2TL9&5F875L='5S97(Z.G)W>"QD969A=6QT=7-E<CIB:6XZ
|
||||
M<G=X.C(L9&5F875L=&=R;W5P.CIR+7@L9&5F875L=&=R;W5P.G-Y<SIR+7@Z
|
||||
M,RQD969A=6QT;6%S:SIR=W@L9&5F875L=&]T:&5R.BTM+0 @ #C%
|
||||
M" @
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M &1I<BUW
|
||||
M:71H+7!O<VEX+6%C;',O
|
||||
M
|
||||
M P,# P-S4P # P,#$W-3 ,# P,# P, P,# P,# P,# P, Q,S S
|
||||
M-C4Q,C(U- P,#$T,# T #4
|
||||
M
|
||||
M =7-T87( ,#
|
||||
M ')O;W0
|
||||
M ,# P,#0Q- P,# P,# S
|
||||
M
|
||||
M
|
||||
M
|
||||
M 9FEL92UW:71H+6YF<W8T+6%C;',
|
||||
M
|
||||
M # P,# V-# ,# P,3<U, P,# P,# P
|
||||
M # P,# P,# P,S8T #$S,#,V-3$S-C0Q # P,30P,34 00
|
||||
M
|
||||
M !U
|
||||
M<W1A<@ P, <F]O=
|
||||
M P,# P-#$T # R,# P,#(
|
||||
M
|
||||
M
|
||||
M
|
||||
M S,# P,# V &=R;W5P.F1A
|
||||
M96UO;CIR=WAP+2UA05)78T-O<SHM+2TM+2TM.F1E;GDZ,3(L9W)O=7 Z8FEN
|
||||
M.G)W>' M+2TM+2TM+2US.BTM+2TM+2TZ86QL;W<Z,BQU<V5R.F%D;3IR+2TM
|
||||
M+2UA+5(M8RTM<SHM+2TM+2TM.F%L;&]W.C0L;W=N97) .G)W+7 M+6%!4E=C
|
||||
M0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7! .G(M+2TM+6$M4BUC+2US.BTM+2TM
|
||||
M+2TZ86QL;W<L979E<GEO;F5 .BTM+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL
|
||||
M;W< &@
|
||||
M
|
||||
M F-8(" #[ #,P,# P,#8
|
||||
M9W)O=7 Z9&%E;6]N.G)W>' M+6%!4E=C0V]S.BTM+2TM+2TZ9&5N>3HQ,BQG
|
||||
M<F]U<#IB:6XZ<G=X<"TM+2TM+2TM+7,Z+2TM+2TM+3IA;&QO=SHR+'5S97(Z
|
||||
M861M.G(M+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL;W<Z-"QO=VYE<D Z<G<M
|
||||
M<&9I;&4M=VET:"UN9G-V-"UA8VQS
|
||||
M
|
||||
M P,# P-C0P # P,#$W-3 ,# P,# P, P,# P,# P,# P
|
||||
M, Q,S S-C4Q,S8T,0 P,#$S-S4W #
|
||||
M
|
||||
M =7-T87( ,#
|
||||
M ')O;W0
|
||||
M ,# P,#0Q- P,C P,# R
|
||||
M
|
||||
M
|
||||
M
|
||||
M 9&ER+7=I=&@M;F9S=C0M86-L<R\
|
||||
M
|
||||
M # P,# W-3 ,# P,# P, P
|
||||
M,# P,# P # P,# P,# P,S$T #$S,#,V-3$S-S,U # P,30V,C, 00
|
||||
M
|
||||
M
|
||||
M !U<W1A<@ P,')O;W0
|
||||
M<F]O= P,# P-#$T # R,# P
|
||||
M,#(
|
||||
M
|
||||
M
|
||||
M S,# P,# U '5S
|
||||
M97(Z,3$P,#IR=WAP+2UA05)78T-O<SIF9&DM+2TM.F%L;&]W.C$Q,# L9W)O
|
||||
M=7 Z861M.G(M+2TM+6$M4BUC+2US.F9D+2TM+2TZ86QL;W<Z-"QO=VYE<D Z
|
||||
M<G=X<"U$84%25V-#;W,Z+2TM+2TM+3IA;&QO=RQG<F]U<$ Z<BUX+2TM82U2
|
||||
M+6,M+7,Z+2TM+2TM+3IA;&QO=RQE=F5R>6]N94 Z+2TM+2TM82U2+6,M+7,Z
|
||||
M+2TM+2TM+3IA;&QO=P 4
|
||||
M
|
||||
M "HUP@( -, ,S P,# P-0!U<V5R.C$Q,# Z<G=X
|
||||
M<"TM84%25V-#;W,Z9F1I+2TM+3IA;&QO=SHQ,3 P+&=R;W5P.F%D;3IR+2TM
|
||||
M+2UA+5(M8RTM<SIF9"TM+2TM.F%L;&]W.C0L;W=N97) .G)W>' M1&%!4E=C
|
||||
M0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7! .G(M>"TM+6$M4BUC+2US.BTM+2TM
|
||||
M+2TZ86QL;W<L979E<GEO;F5 .BTM+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL
|
||||
M;W< &1I<BUW:71H+6YF<W8T+6%C;',O
|
||||
M
|
||||
M P,# P-S4P # P,# P,# ,# P,# P, P,# P
|
||||
M,# P,# P, Q,S S-C4Q,S<S-0 P,#$T-3<W #4
|
||||
M
|
||||
M =7-T87(
|
||||
M,#!R;V]T ')O;W0
|
||||
M ,# P,#0Q- P,C P,# R
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
-
|
||||
|
||||
end
|
||||
|
@ -406,10 +406,12 @@ DEFINE_TEST(test_fuzz_tar)
|
||||
"test_read_format_tar_empty_filename.tar",
|
||||
NULL
|
||||
};
|
||||
#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H
|
||||
static const char *fileset9[] = {
|
||||
"test_compat_lzop_1.tar.lzo",
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
static const struct files filesets[] = {
|
||||
{0, fileset1}, /* Exercise bzip2 decompressor. */
|
||||
{1, fileset1},
|
||||
@ -420,7 +422,9 @@ DEFINE_TEST(test_fuzz_tar)
|
||||
{0, fileset6}, /* Exercise xz decompressor. */
|
||||
{0, fileset7},
|
||||
{0, fileset8},
|
||||
#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H
|
||||
{0, fileset9}, /* Exercise lzo decompressor. */
|
||||
#endif
|
||||
{1, NULL}
|
||||
};
|
||||
test_fuzz(filesets);
|
||||
|
@ -1320,11 +1320,13 @@ test_callbacks(void)
|
||||
assertUtimes("cb", 886622, 0, 886622, 0);
|
||||
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
if (assert((a = archive_read_disk_new()) != NULL)) {
|
||||
assert((a = archive_read_disk_new()) != NULL);
|
||||
if (a == NULL) {
|
||||
archive_entry_free(ae);
|
||||
return;
|
||||
}
|
||||
if (assert((m = archive_match_new()) != NULL)) {
|
||||
assert((m = archive_match_new()) != NULL);
|
||||
if (m == NULL) {
|
||||
archive_entry_free(ae);
|
||||
archive_read_free(a);
|
||||
archive_match_free(m);
|
||||
@ -1377,6 +1379,10 @@ test_callbacks(void)
|
||||
/* Close the disk object. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
|
||||
/* Reset name filter */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_disk_set_matching(a, NULL, NULL, NULL));
|
||||
|
||||
/*
|
||||
* Test2: Traversals with a metadata filter.
|
||||
*/
|
||||
@ -1394,7 +1400,7 @@ test_callbacks(void)
|
||||
while (file_count--) {
|
||||
archive_entry_clear(ae);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
|
||||
failure("File 'cb/f1' should be exclueded");
|
||||
failure("File 'cb/f1' should be excluded");
|
||||
assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0);
|
||||
if (strcmp(archive_entry_pathname(ae), "cb") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
|
||||
|
@ -39,13 +39,16 @@ DEFINE_TEST(test_read_filter_lzop)
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
r = archive_read_support_filter_lzop(a);
|
||||
if (r != ARCHIVE_OK) {
|
||||
if (r == ARCHIVE_WARN && !canLzop()) {
|
||||
if (!canLzop()) {
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
skipping("lzop compression is not supported "
|
||||
"on this platform");
|
||||
} else
|
||||
return;
|
||||
} else if (r != ARCHIVE_WARN) {
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
return;
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
|
@ -36,12 +36,16 @@ DEFINE_TEST(test_read_filter_lzop_multiple_parts)
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
r = archive_read_support_filter_lzop(a);
|
||||
if (r != ARCHIVE_OK) {
|
||||
if (r == ARCHIVE_WARN && !canLzop()) {
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
if (!canLzop()) {
|
||||
skipping("lzop compression is not supported "
|
||||
"on this platform");
|
||||
} else if (r == ARCHIVE_WARN) {
|
||||
skipping("lzop multiple parts decoding is not "
|
||||
"supported via external program");
|
||||
|
||||
} else
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
|
@ -126,6 +126,7 @@ test_basic(void)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
|
||||
verify_basic(a, 0);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -195,6 +196,7 @@ test_info_zip_ux(void)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
|
||||
verify_info_zip_ux(a, 0);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -258,6 +260,7 @@ test_extract_length_at_end(void)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
|
||||
verify_extract_length_at_end(a, 0);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -294,6 +297,8 @@ test_symlink(void)
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip)
|
||||
|
@ -63,6 +63,8 @@ verify(const char *refname)
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_comment_stored)
|
||||
|
@ -112,4 +112,6 @@ DEFINE_TEST(test_read_format_zip_mac_metadata)
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ test_malformed1(void)
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
free(p);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_malformed)
|
||||
|
@ -65,6 +65,8 @@ DEFINE_TEST(test_read_format_zip_nested)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
|
||||
/* Inspect inner Zip. */
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
|
@ -53,6 +53,8 @@ verify_padded_archive(const char *refname)
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -60,4 +60,6 @@ DEFINE_TEST(test_read_format_zip_sfx)
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
@ -72,6 +72,9 @@ DEFINE_TEST(test_write_disk_secure746a)
|
||||
|
||||
/* Verify that target file contents are unchanged. */
|
||||
assertTextFileContents("unmodified", "../target/foo");
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_FATAL, archive_write_close(a));
|
||||
archive_write_free(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ DEFINE_TEST(test_write_filter_lz4)
|
||||
} else {
|
||||
assertEqualInt(ARCHIVE_OK, r);
|
||||
}
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
buffsize = 2000000;
|
||||
assert(NULL != (buff = (char *)malloc(buffsize)));
|
||||
@ -299,6 +300,7 @@ test_options(const char *options)
|
||||
} else {
|
||||
assertEqualInt(ARCHIVE_OK, r);
|
||||
}
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
buffsize = 2000000;
|
||||
assert(NULL != (buff = (char *)malloc(buffsize)));
|
||||
|
@ -43,12 +43,12 @@ DEFINE_TEST(test_write_filter_lzop)
|
||||
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
r = archive_write_add_filter_lzop(a);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
if (r != ARCHIVE_OK) {
|
||||
if (canLzop() && r == ARCHIVE_WARN)
|
||||
use_prog = 1;
|
||||
else {
|
||||
skipping("lzop writing not supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -92,7 +92,7 @@ DEFINE_TEST(test_write_filter_lzop)
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
r = archive_read_support_filter_lzop(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
if (r == ARCHIVE_WARN && !use_prog) {
|
||||
skipping("Can't verify lzop writing by reading back;"
|
||||
" lzop reading not fully supported on this platform");
|
||||
} else {
|
||||
@ -212,7 +212,7 @@ DEFINE_TEST(test_write_filter_lzop)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
r = archive_read_support_filter_lzop(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
if (r == ARCHIVE_WARN && !use_prog) {
|
||||
skipping("lzop reading not fully supported on this platform");
|
||||
} else {
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
|
@ -470,5 +470,6 @@ DEFINE_TEST(test_write_format_zip_large)
|
||||
assertEqualMem(cd_start, "PK\001\002", 4);
|
||||
|
||||
fileblocks_free(fileblocks);
|
||||
free(buff);
|
||||
free(nulldata);
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ verify_zip_filesize(uint64_t size, int expected)
|
||||
archive_entry_set_size(ae, size);
|
||||
assertEqualInt(expected, archive_write_header(a, ae));
|
||||
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Don't actually write 4GB! ;-) */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
|
||||
}
|
||||
|
@ -45,25 +45,25 @@ DEFINE_TEST(test_option_uid_uname)
|
||||
/* Again with both --uid and --uname */
|
||||
failure("Error invoking %s c", testprog);
|
||||
assertEqualInt(0,
|
||||
systemf("%s cf archive2 --uid=17 --uname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt",
|
||||
systemf("%s cf archive2 --uid=65123 --uname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt",
|
||||
testprog));
|
||||
assertEmptyFile("stdout2.txt");
|
||||
assertEmptyFile("stderr2.txt");
|
||||
data = slurpfile(&s, "archive2");
|
||||
/* Should force uid and uname fields in ustar header. */
|
||||
assertEqualMem(data + 108, "000021 \0", 8);
|
||||
assertEqualMem(data + 108, "177143 \0", 8);
|
||||
assertEqualMem(data + 265, "foofoofoo\0", 10);
|
||||
free(data);
|
||||
|
||||
/* Again with just --uid */
|
||||
failure("Error invoking %s c", testprog);
|
||||
assertEqualInt(0,
|
||||
systemf("%s cf archive3 --uid=17 --format=ustar file >stdout3.txt 2>stderr3.txt",
|
||||
systemf("%s cf archive3 --uid=65123 --format=ustar file >stdout3.txt 2>stderr3.txt",
|
||||
testprog));
|
||||
assertEmptyFile("stdout3.txt");
|
||||
assertEmptyFile("stderr3.txt");
|
||||
data = slurpfile(&s, "archive3");
|
||||
assertEqualMem(data + 108, "000021 \0", 8);
|
||||
assertEqualMem(data + 108, "177143 \0", 8);
|
||||
/* Uname field in ustar header should be empty. */
|
||||
assertEqualMem(data + 265, "\0", 1);
|
||||
free(data);
|
||||
|
@ -140,6 +140,7 @@ safe_fprintf(FILE *f, const char *fmt, ...)
|
||||
} else {
|
||||
/* Leave fmtbuff pointing to the truncated
|
||||
* string in fmtbuff_stack. */
|
||||
fmtbuff = fmtbuff_stack;
|
||||
length = sizeof(fmtbuff_stack) - 1;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user