aboutsummaryrefslogtreecommitdiff
path: root/contrib/libarchive
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2017-02-02 00:50:46 +0000
committerMartin Matuska <mm@FreeBSD.org>2017-02-02 00:50:46 +0000
commit9f3de9e26d9bc05f05e6b6a3a081da7551f27f0b (patch)
tree567871f1339238690d922467a9b8ea39c5bd7a5b /contrib/libarchive
parentcb23468e75163477cf6b9ba2624f2078339a15d1 (diff)
parent91360634ece33ffde0dc7c89bdb0ba8a0eb97d66 (diff)
downloadsrc-9f3de9e26d9bc05f05e6b6a3a081da7551f27f0b.tar.gz
src-9f3de9e26d9bc05f05e6b6a3a081da7551f27f0b.zip
MFV r313071:
Sync libarchive with vendor Vendor changes (relevant to FreeBSD): - support extracting NFSv4 ACLs from Solaris tar archives - bugfixes and optimizations in the ACL code - multiple fixes in the test suite - typo and other small bugfixes 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 101675) - iso 9660 reader: missing free in parse_file_info() (partial 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_local_file_header() MFC after: 1 week X-MFC with: 310866, 310868, 310870, 311899
Notes
Notes: svn path=/head/; revision=313074
Diffstat (limited to 'contrib/libarchive')
-rw-r--r--contrib/libarchive/NEWS4
-rw-r--r--contrib/libarchive/libarchive/archive_acl.c35
-rw-r--r--contrib/libarchive/libarchive/archive_acl_private.h1
-rw-r--r--contrib/libarchive/libarchive/archive_entry.c2
-rw-r--r--contrib/libarchive/libarchive/archive_entry_strmode.c2
-rw-r--r--contrib/libarchive/libarchive/archive_platform.h19
-rw-r--r--contrib/libarchive/libarchive/archive_random.c2
-rw-r--r--contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c721
-rw-r--r--contrib/libarchive/libarchive/archive_read_open_filename.c20
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_filter_lz4.c5
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_filter_program.c2
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_cab.c2
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_cpio.c3
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_iso9660.c26
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_lha.c3
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_mtree.c8
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_tar.c11
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_warc.c2
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_xar.c6
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_zip.c2
-rw-r--r--contrib/libarchive/libarchive/archive_write_add_filter_program.c1
-rw-r--r--contrib/libarchive/libarchive/archive_write_disk_acl.c409
-rw-r--r--contrib/libarchive/libarchive/archive_write_disk_posix.c48
-rw-r--r--contrib/libarchive/libarchive/archive_write_open.311
-rw-r--r--contrib/libarchive/libarchive/archive_write_set_format_gnutar.c8
-rw-r--r--contrib/libarchive/libarchive/archive_write_set_format_iso9660.c8
-rw-r--r--contrib/libarchive/libarchive/archive_write_set_format_xar.c1
-rw-r--r--contrib/libarchive/libarchive/test/main.c8
-rw-r--r--contrib/libarchive/libarchive/test/test.h26
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c (renamed from contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c)468
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c (renamed from contrib/libarchive/libarchive/test/test_acl_freebsd_posix1e.c)366
-rw-r--r--contrib/libarchive/libarchive/test/test_acl_text.c14
-rw-r--r--contrib/libarchive/libarchive/test/test_archive_string.c24
-rw-r--r--contrib/libarchive/libarchive/test/test_compat_gtar.c2
-rw-r--r--contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c297
-rw-r--r--contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu220
-rw-r--r--contrib/libarchive/libarchive/test/test_fuzz.c4
-rw-r--r--contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c12
-rw-r--r--contrib/libarchive/libarchive/test/test_read_filter_lzop.c9
-rw-r--r--contrib/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c8
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_zip.c5
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_zip_comment_stored.c2
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_zip_mac_metadata.c2
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_zip_malformed.c1
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_zip_nested.c2
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_zip_padded.c2
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_zip_sfx.c2
-rw-r--r--contrib/libarchive/libarchive/test/test_write_disk_secure746.c3
-rw-r--r--contrib/libarchive/libarchive/test/test_write_filter_lz4.c2
-rw-r--r--contrib/libarchive/libarchive/test/test_write_filter_lzop.c6
-rw-r--r--contrib/libarchive/libarchive/test/test_write_format_zip_large.c1
-rw-r--r--contrib/libarchive/libarchive/test/test_write_format_zip_zip64.c2
-rw-r--r--contrib/libarchive/tar/test/test_option_uid_uname.c8
-rw-r--r--contrib/libarchive/tar/util.c1
54 files changed, 2440 insertions, 419 deletions
diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS
index 4d875b2a9df5..7b5c31f75c7d 100644
--- a/contrib/libarchive/NEWS
+++ b/contrib/libarchive/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()
diff --git a/contrib/libarchive/libarchive/archive_acl.c b/contrib/libarchive/libarchive/archive_acl.c
index 7c682095962a..1e9ddbb24119 100644
--- a/contrib/libarchive/libarchive/archive_acl.c
+++ b/contrib/libarchive/libarchive/archive_acl.c
@@ -349,6 +349,15 @@ archive_acl_count(struct archive_acl *acl, int want_type)
}
/*
+ * 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
* non-extended ACL entries of that type.
@@ -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;
diff --git a/contrib/libarchive/libarchive/archive_acl_private.h b/contrib/libarchive/libarchive/archive_acl_private.h
index 0aac6fff2d9d..ef0b0234cc1a 100644
--- a/contrib/libarchive/libarchive/archive_acl_private.h
+++ b/contrib/libarchive/libarchive/archive_acl_private.h
@@ -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 **);
diff --git a/contrib/libarchive/libarchive/archive_entry.c b/contrib/libarchive/libarchive/archive_entry.c
index cd6152ba28bb..556c402af73f 100644
--- a/contrib/libarchive/libarchive/archive_entry.c
+++ b/contrib/libarchive/libarchive/archive_entry.c
@@ -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));
}
/*
diff --git a/contrib/libarchive/libarchive/archive_entry_strmode.c b/contrib/libarchive/libarchive/archive_entry_strmode.c
index 8d7006a054fb..d80a7d431cb7 100644
--- a/contrib/libarchive/libarchive/archive_entry_strmode.c
+++ b/contrib/libarchive/libarchive/archive_entry_strmode.c
@@ -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);
diff --git a/contrib/libarchive/libarchive/archive_platform.h b/contrib/libarchive/libarchive/archive_platform.h
index 76816c4d76c8..31383db6850d 100644
--- a/contrib/libarchive/libarchive/archive_platform.h
+++ b/contrib/libarchive/libarchive/archive_platform.h
@@ -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
/*
diff --git a/contrib/libarchive/libarchive/archive_random.c b/contrib/libarchive/libarchive/archive_random.c
index a20b9b111510..357f9733a870 100644
--- a/contrib/libarchive/libarchive/archive_random.c
+++ b/contrib/libarchive/libarchive/archive_random.c
@@ -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);
}
diff --git a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
index 87b121ac3076..63aa6171f0a1 100644
--- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -38,6 +38,11 @@ __FBSDID("$FreeBSD$");
#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$");
#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 **);
+
+static void add_trivial_nfs4_acl(struct archive_entry *);
+#endif
-#ifdef HAVE_POSIX_ACL
+#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,71 +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.
@@ -643,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;
@@ -661,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:
@@ -683,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
*/
@@ -724,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)
@@ -736,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) {
@@ -746,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,
@@ -774,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)
@@ -792,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) || \
diff --git a/contrib/libarchive/libarchive/archive_read_open_filename.c b/contrib/libarchive/libarchive/archive_read_open_filename.c
index b2d52aaae5dd..64b017976209 100644
--- a/contrib/libarchive/libarchive/archive_read_open_filename.c
+++ b/contrib/libarchive/libarchive/archive_read_open_filename.c
@@ -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
diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c b/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c
index 4c66ed04dc95..663e2d3d601f 100644
--- a/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c
+++ b/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c
@@ -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) {
diff --git a/contrib/libarchive/libarchive/archive_read_support_filter_program.c b/contrib/libarchive/libarchive/archive_read_support_filter_program.c
index 66dc2f424f85..b8bf12886f34 100644
--- a/contrib/libarchive/libarchive/archive_read_support_filter_program.c
+++ b/contrib/libarchive/libarchive/archive_read_support_filter_program.c
@@ -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\"",
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_cab.c b/contrib/libarchive/libarchive/archive_read_support_format_cab.c
index 2bdc1e2850e9..e2f8c6b70aeb 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_cab.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_cab.c
@@ -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)
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_cpio.c b/contrib/libarchive/libarchive/archive_read_support_format_cpio.c
index 2a5a829c115f..e19c7110fd48 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_cpio.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_cpio.c
@@ -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);
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c b/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c
index 8c7e9eb41219..ebbfc2fa5c2b 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c
@@ -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
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_lha.c b/contrib/libarchive/libarchive/archive_read_support_format_lha.c
index 52a5531b0ff9..d77a7c2e4766 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_lha.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_lha.c
@@ -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");
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
index 02c12517a5be..179f1615a829 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
@@ -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);
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libarchive/libarchive/archive_read_support_format_tar.c
index 54c2ea7c35ca..446d005fffa0 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_tar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_tar.c
@@ -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,
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_warc.c b/contrib/libarchive/libarchive/archive_read_support_format_warc.c
index 8eda519eb149..30cdaf9dbb74 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_warc.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_warc.c
@@ -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 */
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_xar.c b/contrib/libarchive/libarchive/archive_read_support_format_xar.c
index 47ed064bc627..d3002af718cf 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_xar.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_xar.c
@@ -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;
diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c
index 3388395a3f35..53373ff9fbee 100644
--- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c
+++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c
@@ -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);
}
}
}
diff --git a/contrib/libarchive/libarchive/archive_write_add_filter_program.c b/contrib/libarchive/libarchive/archive_write_add_filter_program.c
index 31a1b6f96786..55b5e8ecdf82 100644
--- a/contrib/libarchive/libarchive/archive_write_add_filter_program.c
+++ b/contrib/libarchive/libarchive/archive_write_add_filter_program.c
@@ -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);
}
diff --git a/contrib/libarchive/libarchive/archive_write_disk_acl.c b/contrib/libarchive/libarchive/archive_write_disk_acl.c
index 706ab62a07c8..311aebf0331f 100644
--- a/contrib/libarchive/libarchive/archive_write_disk_acl.c
+++ b/contrib/libarchive/libarchive/archive_write_disk_acl.c
@@ -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:
+ ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
+ 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:
+ ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
+ 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:
- acl_set_tag_type(acl_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:
- acl_set_tag_type(acl_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 @@ exit_free:
acl_free(acl);
return (ret);
}
-#endif
+#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c
index e6116537e205..a799524d4934 100644
--- a/contrib/libarchive/libarchive/archive_write_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c
@@ -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
diff --git a/contrib/libarchive/libarchive/archive_write_open.3 b/contrib/libarchive/libarchive/archive_write_open.3
index a52959b98fcb..457873e61483 100644
--- a/contrib/libarchive/libarchive/archive_write_open.3
+++ b/contrib/libarchive/libarchive/archive_write_open.3
@@ -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 ,
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c b/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c
index a9c41236ee68..2d858c9f752c 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c
@@ -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)
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c b/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c
index 1d1f04e00f44..4e910979e096 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c
@@ -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
diff --git a/contrib/libarchive/libarchive/archive_write_set_format_xar.c b/contrib/libarchive/libarchive/archive_write_set_format_xar.c
index c9f5ac239582..495f0d441e5c 100644
--- a/contrib/libarchive/libarchive/archive_write_set_format_xar.c
+++ b/contrib/libarchive/libarchive/archive_write_set_format_xar.c
@@ -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);
}
diff --git a/contrib/libarchive/libarchive/test/main.c b/contrib/libarchive/libarchive/test/main.c
index a0fbb9ee7915..d75f1ab4fcc5 100644
--- a/contrib/libarchive/libarchive/test/main.c
+++ b/contrib/libarchive/libarchive/test/main.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;
diff --git a/contrib/libarchive/libarchive/test/test.h b/contrib/libarchive/libarchive/test/test.h
index 01034e451d16..dc3f59048a1b 100644
--- a/contrib/libarchive/libarchive/test/test.h
+++ b/contrib/libarchive/libarchive/test/test.h
@@ -121,6 +121,32 @@
#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.
*/
#undef DEFINE_TEST
diff --git a/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c b/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
index 4e68623c1722..01c1dc589f6f 100644
--- a/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c
+++ b/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
@@ -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,53 +699,109 @@ 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");
+ 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;
}
- failure("acl_set_file(): errno = %d (%s)",
- errno, strerror(errno));
- assertEqualInt(0, n);
+ acl_free(acl);
+#endif
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
@@ -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 */
}
diff --git a/contrib/libarchive/libarchive/test/test_acl_freebsd_posix1e.c b/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
index 7e5212ac01fd..f3e1722f711d 100644
--- a/contrib/libarchive/libarchive/test/test_acl_freebsd_posix1e.c
+++ b/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
@@ -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");
+ 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;
}
- failure("acl_set_fd(): errno = %d (%s)",
- errno, strerror(errno));
+ 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) {
+ 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("This filesystem does not support POSIX.1e ACLs");
+ skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
- failure("acl_set_fd(): errno = %d (%s)",
- errno, strerror(errno));
+
+ 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
}
diff --git a/contrib/libarchive/libarchive/test/test_acl_text.c b/contrib/libarchive/libarchive/test/test_acl_text.c
index 2781e6ea5663..23d991e40338 100644
--- a/contrib/libarchive/libarchive/test/test_acl_text.c
+++ b/contrib/libarchive/libarchive/test/test_acl_text.c
@@ -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);
}
diff --git a/contrib/libarchive/libarchive/test/test_archive_string.c b/contrib/libarchive/libarchive/test/test_archive_string.c
index 9e3f90702dbc..7fa743ba9ed2 100644
--- a/contrib/libarchive/libarchive/test/test_archive_string.c
+++ b/contrib/libarchive/libarchive/test/test_archive_string.c
@@ -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)
diff --git a/contrib/libarchive/libarchive/test/test_compat_gtar.c b/contrib/libarchive/libarchive/test/test_compat_gtar.c
index b33e6ab6534b..975b824c4ba0 100644
--- a/contrib/libarchive/libarchive/test/test_compat_gtar.c
+++ b/contrib/libarchive/libarchive/test/test_compat_gtar.c
@@ -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)
diff --git a/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c b/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c
index d4654d02f769..3d063c1db9e6 100644
--- a/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c
+++ b/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c
@@ -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
@@ -26,101 +27,239 @@
__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);
-
- 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);
+ 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_OTHER, tag);
- assertEqualInt(-1, qual);
- assert(name == NULL);
-
- 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");
+ /* 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_MASK, tag);
- assertEqualInt(-1, qual);
- assertEqualString(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_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));
diff --git a/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu b/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu
index 229b335679aa..028dd61a4015 100644
--- a/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu
+++ b/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu
@@ -1,61 +1,163 @@
-$FreeBSD$
-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
diff --git a/contrib/libarchive/libarchive/test/test_fuzz.c b/contrib/libarchive/libarchive/test/test_fuzz.c
index b70a415ac4ad..e896f607e418 100644
--- a/contrib/libarchive/libarchive/test/test_fuzz.c
+++ b/contrib/libarchive/libarchive/test/test_fuzz.c
@@ -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);
diff --git a/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c b/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
index 31eb76b93123..c9aca8fa985d 100644
--- a/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
+++ b/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
@@ -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);
diff --git a/contrib/libarchive/libarchive/test/test_read_filter_lzop.c b/contrib/libarchive/libarchive/test/test_read_filter_lzop.c
index 86a5e6e84482..acce6a4c2052 100644
--- a/contrib/libarchive/libarchive/test/test_read_filter_lzop.c
+++ b/contrib/libarchive/libarchive/test/test_read_filter_lzop.c
@@ -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,
diff --git a/contrib/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c b/contrib/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c
index 3b0febbd785c..82eaf3539473 100644
--- a/contrib/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c
+++ b/contrib/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c
@@ -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));
diff --git a/contrib/libarchive/libarchive/test/test_read_format_zip.c b/contrib/libarchive/libarchive/test/test_read_format_zip.c
index 62a49baab8c4..29b3fc22a735 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_zip.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_zip.c
@@ -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)
diff --git a/contrib/libarchive/libarchive/test/test_read_format_zip_comment_stored.c b/contrib/libarchive/libarchive/test/test_read_format_zip_comment_stored.c
index d2b935de2d44..b92b2886cdda 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_zip_comment_stored.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_zip_comment_stored.c
@@ -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)
diff --git a/contrib/libarchive/libarchive/test/test_read_format_zip_mac_metadata.c b/contrib/libarchive/libarchive/test/test_read_format_zip_mac_metadata.c
index 97aa427b0348..99b7012328cb 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_zip_mac_metadata.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_zip_mac_metadata.c
@@ -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);
}
diff --git a/contrib/libarchive/libarchive/test/test_read_format_zip_malformed.c b/contrib/libarchive/libarchive/test/test_read_format_zip_malformed.c
index 2327d9149029..e14a3f5660da 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_zip_malformed.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_zip_malformed.c
@@ -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)
diff --git a/contrib/libarchive/libarchive/test/test_read_format_zip_nested.c b/contrib/libarchive/libarchive/test/test_read_format_zip_nested.c
index 6830afb716d7..5f6edf267443 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_zip_nested.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_zip_nested.c
@@ -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));
diff --git a/contrib/libarchive/libarchive/test/test_read_format_zip_padded.c b/contrib/libarchive/libarchive/test/test_read_format_zip_padded.c
index dae88abba53e..2094eca3557a 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_zip_padded.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_zip_padded.c
@@ -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);
}
/*
diff --git a/contrib/libarchive/libarchive/test/test_read_format_zip_sfx.c b/contrib/libarchive/libarchive/test/test_read_format_zip_sfx.c
index d5992d395658..dc76ef9b3826 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_zip_sfx.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_zip_sfx.c
@@ -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);
}
diff --git a/contrib/libarchive/libarchive/test/test_write_disk_secure746.c b/contrib/libarchive/libarchive/test/test_write_disk_secure746.c
index 460aafef12c5..5ce1fd9c4c43 100644
--- a/contrib/libarchive/libarchive/test/test_write_disk_secure746.c
+++ b/contrib/libarchive/libarchive/test/test_write_disk_secure746.c
@@ -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
}
diff --git a/contrib/libarchive/libarchive/test/test_write_filter_lz4.c b/contrib/libarchive/libarchive/test/test_write_filter_lz4.c
index a04369841709..4f2135a31507 100644
--- a/contrib/libarchive/libarchive/test/test_write_filter_lz4.c
+++ b/contrib/libarchive/libarchive/test/test_write_filter_lz4.c
@@ -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)));
diff --git a/contrib/libarchive/libarchive/test/test_write_filter_lzop.c b/contrib/libarchive/libarchive/test/test_write_filter_lzop.c
index a32932c69773..92db7bf3dc43 100644
--- a/contrib/libarchive/libarchive/test/test_write_filter_lzop.c
+++ b/contrib/libarchive/libarchive/test/test_write_filter_lzop.c
@@ -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,
diff --git a/contrib/libarchive/libarchive/test/test_write_format_zip_large.c b/contrib/libarchive/libarchive/test/test_write_format_zip_large.c
index d73dd62dee19..88788b56d50d 100644
--- a/contrib/libarchive/libarchive/test/test_write_format_zip_large.c
+++ b/contrib/libarchive/libarchive/test/test_write_format_zip_large.c
@@ -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);
}
diff --git a/contrib/libarchive/libarchive/test/test_write_format_zip_zip64.c b/contrib/libarchive/libarchive/test/test_write_format_zip_zip64.c
index b83aeab5316a..c5f00a2e5d8d 100644
--- a/contrib/libarchive/libarchive/test/test_write_format_zip_zip64.c
+++ b/contrib/libarchive/libarchive/test/test_write_format_zip_zip64.c
@@ -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));
}
diff --git a/contrib/libarchive/tar/test/test_option_uid_uname.c b/contrib/libarchive/tar/test/test_option_uid_uname.c
index 0a8a9bb27a8c..80c061961488 100644
--- a/contrib/libarchive/tar/test/test_option_uid_uname.c
+++ b/contrib/libarchive/tar/test/test_option_uid_uname.c
@@ -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);
diff --git a/contrib/libarchive/tar/util.c b/contrib/libarchive/tar/util.c
index f845600193a0..84dc53f7dcad 100644
--- a/contrib/libarchive/tar/util.c
+++ b/contrib/libarchive/tar/util.c
@@ -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;
}