svn commit: r313570 - in stable/11: . contrib/libarchive contrib/libarchive/cpio contrib/libarchive/libarchive contrib/libarchive/libarchive/test contrib/libarchive/tar contrib/libarchive/tar/test ...
Martin Matuska
mm at FreeBSD.org
Sat Feb 11 00:54:18 UTC 2017
Author: mm
Date: Sat Feb 11 00:54:16 2017
New Revision: 313570
URL: https://svnweb.freebsd.org/changeset/base/313570
Log:
MFC r310866,310868,310870,311903,313074:
Sync libarchive with vendor.
MFC r310866:
PR #771: Add NFSv4 ACL support to pax and restricted pax
NFSv4 ACL information may now be stored to and restored from tar archives.
ACL must be non-trivial and supported by the underlying filesystem, e.g.
natively by ZFS or by UFS with the NFSv4 ACL enable flag set.
MFC r310868:
PR #843: Fix memory leak of struct archive_entry in cpio/cpio.c
PR #851: Spelling fixes
Fix two protoypes in manual page archive_read_disk.3
MFC r310870:
Use __LA_DEPRECATED macro with functions deprecated in 379867e
MFC r311903:
#691: Support for SCHILY.xattr extended attributes
#854: Spelling fixes
Multiple fixes in ACL code:
- prefer acl_set_fd_np() to acl_set_fd()
- if acl_set_fd_np() fails, do no fallback to acl_set_file()
- do not warn if trying to write ACLs to a filesystem without ACL support
- fix id handling in archive_acl_(from_to)_text*() for NFSv4 ACLs
MFC r313074:
- 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()
List of all libarchive issues at OSS-Fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/list?can=1&q=libarchive
Security: CVE-2017-5601
Added:
stable/11/contrib/libarchive/libarchive/test/test_acl_pax_nfs4.tar.uu
- copied unchanged from r310866, head/contrib/libarchive/libarchive/test/test_acl_pax_nfs4.tar.uu
stable/11/contrib/libarchive/libarchive/test/test_acl_pax_posix1e.tar.uu
- copied unchanged from r310866, head/contrib/libarchive/libarchive/test/test_acl_pax_posix1e.tar.uu
stable/11/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
- copied unchanged from r313074, head/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
stable/11/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
- copied unchanged from r313074, head/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
stable/11/contrib/libarchive/libarchive/test/test_acl_text.c
- copied, changed from r310866, head/contrib/libarchive/libarchive/test/test_acl_text.c
stable/11/contrib/libarchive/libarchive/test/test_compat_star_acl.c
- copied unchanged from r310866, head/contrib/libarchive/libarchive/test/test_compat_star_acl.c
stable/11/contrib/libarchive/libarchive/test/test_compat_star_acl_nfs4.tar.uu
- copied unchanged from r310866, head/contrib/libarchive/libarchive/test/test_compat_star_acl_nfs4.tar.uu
stable/11/contrib/libarchive/libarchive/test/test_read_pax_schily_xattr.c
- copied unchanged from r311903, head/contrib/libarchive/libarchive/test/test_read_pax_schily_xattr.c
stable/11/contrib/libarchive/libarchive/test/test_read_pax_schily_xattr.tar.uu
- copied unchanged from r311903, head/contrib/libarchive/libarchive/test/test_read_pax_schily_xattr.tar.uu
Deleted:
stable/11/contrib/libarchive/libarchive/test/test_acl_freebsd_nfs4.c
stable/11/contrib/libarchive/libarchive/test/test_acl_freebsd_posix1e.c
stable/11/contrib/libarchive/libarchive/test/test_acl_pax.tar.uu
stable/11/contrib/libarchive/libarchive/test/test_compat_star_acl_posix1e.c
Modified:
stable/11/ObsoleteFiles.inc
stable/11/contrib/libarchive/NEWS
stable/11/contrib/libarchive/cpio/cpio.c
stable/11/contrib/libarchive/libarchive/archive_acl.c
stable/11/contrib/libarchive/libarchive/archive_acl_private.h
stable/11/contrib/libarchive/libarchive/archive_entry.c
stable/11/contrib/libarchive/libarchive/archive_entry.h
stable/11/contrib/libarchive/libarchive/archive_entry_acl.3
stable/11/contrib/libarchive/libarchive/archive_entry_locale.h
stable/11/contrib/libarchive/libarchive/archive_entry_strmode.c
stable/11/contrib/libarchive/libarchive/archive_match.c
stable/11/contrib/libarchive/libarchive/archive_platform.h
stable/11/contrib/libarchive/libarchive/archive_random.c
stable/11/contrib/libarchive/libarchive/archive_rb.c
stable/11/contrib/libarchive/libarchive/archive_read_disk.3
stable/11/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
stable/11/contrib/libarchive/libarchive/archive_read_disk_posix.c
stable/11/contrib/libarchive/libarchive/archive_read_open_filename.c
stable/11/contrib/libarchive/libarchive/archive_read_support_filter_lz4.c
stable/11/contrib/libarchive/libarchive/archive_read_support_filter_lzop.c
stable/11/contrib/libarchive/libarchive/archive_read_support_filter_program.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_7zip.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_cab.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_cpio.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_lha.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_rar.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_tar.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_warc.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_xar.c
stable/11/contrib/libarchive/libarchive/archive_read_support_format_zip.c
stable/11/contrib/libarchive/libarchive/archive_string.c
stable/11/contrib/libarchive/libarchive/archive_string.h
stable/11/contrib/libarchive/libarchive/archive_string_composition.h
stable/11/contrib/libarchive/libarchive/archive_write.c
stable/11/contrib/libarchive/libarchive/archive_write_add_filter_program.c
stable/11/contrib/libarchive/libarchive/archive_write_add_filter_xz.c
stable/11/contrib/libarchive/libarchive/archive_write_disk_acl.c
stable/11/contrib/libarchive/libarchive/archive_write_disk_posix.c
stable/11/contrib/libarchive/libarchive/archive_write_open.3
stable/11/contrib/libarchive/libarchive/archive_write_set_format_7zip.c
stable/11/contrib/libarchive/libarchive/archive_write_set_format_gnutar.c
stable/11/contrib/libarchive/libarchive/archive_write_set_format_iso9660.c
stable/11/contrib/libarchive/libarchive/archive_write_set_format_pax.c
stable/11/contrib/libarchive/libarchive/archive_write_set_format_warc.c
stable/11/contrib/libarchive/libarchive/archive_write_set_format_xar.c
stable/11/contrib/libarchive/libarchive/archive_write_set_format_zip.c
stable/11/contrib/libarchive/libarchive/libarchive-formats.5
stable/11/contrib/libarchive/libarchive/tar.5
stable/11/contrib/libarchive/libarchive/test/main.c
stable/11/contrib/libarchive/libarchive/test/test.h
stable/11/contrib/libarchive/libarchive/test/test_acl_nfs4.c
stable/11/contrib/libarchive/libarchive/test/test_acl_pax.c
stable/11/contrib/libarchive/libarchive/test/test_acl_posix1e.c
stable/11/contrib/libarchive/libarchive/test/test_archive_read_add_passphrase.c
stable/11/contrib/libarchive/libarchive/test/test_archive_string.c
stable/11/contrib/libarchive/libarchive/test/test_compat_gtar.c
stable/11/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.c
stable/11/contrib/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu
stable/11/contrib/libarchive/libarchive/test/test_compat_uudecode.c
stable/11/contrib/libarchive/libarchive/test/test_fuzz.c
stable/11/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
stable/11/contrib/libarchive/libarchive/test/test_read_filter_lzop.c
stable/11/contrib/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_7zip.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_cpio_afio.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_isorr_bz2.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_comment_stored.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_filename.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_mac_metadata.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_malformed.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_nested.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_padded.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_sfx.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_traditional_encryption_data.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_winzip_aes.c
stable/11/contrib/libarchive/libarchive/test/test_read_format_zip_winzip_aes_large.c
stable/11/contrib/libarchive/libarchive/test/test_sparse_basic.c
stable/11/contrib/libarchive/libarchive/test/test_write_disk_secure746.c
stable/11/contrib/libarchive/libarchive/test/test_write_filter_lz4.c
stable/11/contrib/libarchive/libarchive/test/test_write_filter_lzop.c
stable/11/contrib/libarchive/libarchive/test/test_write_format_iso9660.c
stable/11/contrib/libarchive/libarchive/test/test_write_format_iso9660_zisofs.c
stable/11/contrib/libarchive/libarchive/test/test_write_format_zip_large.c
stable/11/contrib/libarchive/libarchive/test/test_write_format_zip_zip64.c
stable/11/contrib/libarchive/libarchive/xxhash.c
stable/11/contrib/libarchive/tar/test/test_option_uid_uname.c
stable/11/contrib/libarchive/tar/util.c
stable/11/lib/libarchive/config_freebsd.h
stable/11/lib/libarchive/tests/Makefile
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/ObsoleteFiles.inc
==============================================================================
--- stable/11/ObsoleteFiles.inc Fri Feb 10 23:12:38 2017 (r313569)
+++ stable/11/ObsoleteFiles.inc Sat Feb 11 00:54:16 2017 (r313570)
@@ -38,6 +38,8 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20170211: libarchive ACL pax test renamed to test_acl_pax_posix1e.tar.uu
+OLD_FILES+=usr/tests/lib/libarchive/test_acl_pax.tar.uu
# 20170103: libbsnmptools.so made into an INTERNALLIB
OLD_FILES+=usr/lib/libbsnmptools.a
OLD_FILES+=usr/lib/libbsnmptools_p.a
Modified: stable/11/contrib/libarchive/NEWS
==============================================================================
--- stable/11/contrib/libarchive/NEWS Fri Feb 10 23:12:38 2017 (r313569)
+++ stable/11/contrib/libarchive/NEWS Sat Feb 11 00:54:16 2017 (r313570)
@@ -1,3 +1,10 @@
+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()
+
Oct 26, 2016: Remove liblzmadec support
Oct 23, 2016: libarchive 3.2.2 released
Modified: stable/11/contrib/libarchive/cpio/cpio.c
==============================================================================
--- stable/11/contrib/libarchive/cpio/cpio.c Fri Feb 10 23:12:38 2017 (r313569)
+++ stable/11/contrib/libarchive/cpio/cpio.c Sat Feb 11 00:54:16 2017 (r313570)
@@ -703,6 +703,7 @@ file_to_archive(struct cpio *cpio, const
lafe_warnc(0, "%s",
archive_error_string(cpio->archive_read_disk));
if (r <= ARCHIVE_FAILED) {
+ archive_entry_free(entry);
cpio->return_value = 1;
return (r);
}
Modified: stable/11/contrib/libarchive/libarchive/archive_acl.c
==============================================================================
--- stable/11/contrib/libarchive/libarchive/archive_acl.c Fri Feb 10 23:12:38 2017 (r313569)
+++ stable/11/contrib/libarchive/libarchive/archive_acl.c Sat Feb 11 00:54:16 2017 (r313570)
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2010 Tim Kientzle
+ * Copyright (c) 2016 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,23 +56,31 @@ static struct archive_acl_entry *acl_new
static int archive_acl_add_entry_len_l(struct archive_acl *acl,
int type, int permset, int tag, int id, const char *name,
size_t len, struct archive_string_conv *sc);
+static int archive_acl_text_want_type(struct archive_acl *acl, int flags);
+static ssize_t archive_acl_text_len(struct archive_acl *acl, int want_type,
+ int flags, int wide, struct archive *a,
+ struct archive_string_conv *sc);
static int isint_w(const wchar_t *start, const wchar_t *end, int *result);
static int ismode_w(const wchar_t *start, const wchar_t *end, int *result);
+static int is_nfs4_flags_w(const wchar_t *start, const wchar_t *end,
+ int *result);
+static int is_nfs4_perms_w(const wchar_t *start, const wchar_t *end,
+ int *result);
static void next_field_w(const wchar_t **wp, const wchar_t **start,
const wchar_t **end, wchar_t *sep);
-static int prefix_w(const wchar_t *start, const wchar_t *end,
- const wchar_t *test);
-static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
- const wchar_t *wname, int perm, int id);
+static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
+ int tag, int flags, const wchar_t *wname, int perm, int id);
static void append_id_w(wchar_t **wp, int id);
static int isint(const char *start, const char *end, int *result);
static int ismode(const char *start, const char *end, int *result);
+static int is_nfs4_flags(const char *start, const char *end,
+ int *result);
+static int is_nfs4_perms(const char *start, const char *end,
+ int *result);
static void next_field(const char **p, const char **start,
const char **end, char *sep);
-static int prefix_c(const char *start, const char *end,
- const char *test);
-static void append_entry(char **p, const char *prefix, int tag,
- const char *name, int perm, int id);
+static void append_entry(char **p, const char *prefix, int type,
+ int tag, int flags, const char *name, int perm, int id);
static void append_id(char **p, int id);
void
@@ -340,6 +349,15 @@ archive_acl_count(struct archive_acl *ac
}
/*
+ * 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.
@@ -375,8 +393,8 @@ archive_acl_reset(struct archive_acl *ac
* standard permissions and include them in the returned list.
*/
int
-archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type, int *type,
- int *permset, int *tag, int *id, const char **name)
+archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type,
+ int *type, int *permset, int *tag, int *id, const char **name)
{
*name = NULL;
*id = -1;
@@ -441,130 +459,273 @@ archive_acl_next(struct archive *a, stru
}
/*
- * Generate a text version of the ACL. The flags parameter controls
- * the style of the generated ACL.
+ * Determine what type of ACL do we want
*/
-const wchar_t *
-archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
+static int
+archive_acl_text_want_type(struct archive_acl *acl, int flags)
{
- int count;
- size_t length;
- const wchar_t *wname;
- const wchar_t *prefix;
- wchar_t separator;
- struct archive_acl_entry *ap;
- int id, r;
- wchar_t *wp;
+ int want_type;
- if (acl->acl_text_w != NULL) {
- free (acl->acl_text_w);
- acl->acl_text_w = NULL;
+ /* Check if ACL is NFSv4 */
+ if ((acl->acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ /* NFSv4 should never mix with POSIX.1e */
+ if ((acl->acl_types & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0)
+ return (0);
+ else
+ return (ARCHIVE_ENTRY_ACL_TYPE_NFS4);
}
- separator = L',';
+ /* Now deal with POSIX.1e ACLs */
+
+ want_type = 0;
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
+ want_type |= ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
+ want_type |= ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
+
+ /* By default we want both access and default ACLs */
+ if (want_type == 0)
+ return (ARCHIVE_ENTRY_ACL_TYPE_POSIX1E);
+
+ return (want_type);
+}
+
+/*
+ * Calculate ACL text string length
+ */
+static ssize_t
+archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
+ int wide, struct archive *a, struct archive_string_conv *sc) {
+ struct archive_acl_entry *ap;
+ const char *name;
+ const wchar_t *wname;
+ int count, idlen, tmp, r;
+ ssize_t length;
+ size_t len;
+
count = 0;
length = 0;
- ap = acl->acl_head;
- while (ap != NULL) {
- if ((ap->type & flags) != 0) {
- count++;
- if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) &&
- (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))
- length += 8; /* "default:" */
- length += 5; /* tag name */
- length += 1; /* colon */
- r = archive_mstring_get_wcs(a, &ap->name, &wname);
- if (r == 0 && wname != NULL)
- length += wcslen(wname);
- else if (r < 0 && errno == ENOMEM)
- return (NULL);
- else
- length += sizeof(uid_t) * 3 + 1;
- length ++; /* colon */
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & want_type) == 0)
+ continue;
+ /*
+ * Filemode-mapping ACL entries are stored exclusively in
+ * ap->mode so they should not be in the list
+ */
+ if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
+ && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
+ || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
+ || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
+ continue;
+ count++;
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0
+ && (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
+ length += 8; /* "default:" */
+ switch (ap->tag) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ length += 6; /* "owner@" */
+ break;
+ }
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_USER:
+ case ARCHIVE_ENTRY_ACL_MASK:
+ length += 4; /* "user", "mask" */
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ length += 6; /* "group@" */
+ break;
+ }
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ length += 5; /* "group", "other" */
+ break;
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
+ length += 9; /* "everyone@" */
+ break;
+ }
+ length += 1; /* colon after tag */
+ if (ap->tag == ARCHIVE_ENTRY_ACL_USER ||
+ ap->tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ if (wide) {
+ r = archive_mstring_get_wcs(a, &ap->name,
+ &wname);
+ if (r == 0 && wname != NULL)
+ length += wcslen(wname);
+ else if (r < 0 && errno == ENOMEM)
+ return (0);
+ else
+ length += sizeof(uid_t) * 3 + 1;
+ } else {
+ r = archive_mstring_get_mbs_l(&ap->name, &name,
+ &len, sc);
+ if (r != 0)
+ return (0);
+ if (len > 0 && name != NULL)
+ length += len;
+ else
+ length += sizeof(uid_t) * 3 + 1;
+ }
+ length += 1; /* colon after user or group name */
+ } else if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4)
+ length += 1; /* 2nd colon empty user,group or other */
+
+ if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0)
+ && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0)
+ && (ap->tag == ARCHIVE_ENTRY_ACL_OTHER
+ || ap->tag == ARCHIVE_ENTRY_ACL_MASK)) {
+ /* Solaris has no colon after other: and mask: */
+ length = length - 1;
+ }
+
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ /* rwxpdDaARWcCos:fdinSFI:deny */
+ length += 27;
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DENY) == 0)
+ length += 1; /* allow, alarm, audit */
+ } else
length += 3; /* rwx */
+
+ if ((ap->tag == ARCHIVE_ENTRY_ACL_USER ||
+ ap->tag == ARCHIVE_ENTRY_ACL_GROUP) &&
+ (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0) {
length += 1; /* colon */
- length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1;
- length ++; /* newline */
+ /* ID digit count */
+ idlen = 1;
+ tmp = ap->id;
+ while (tmp > 9) {
+ tmp = tmp / 10;
+ idlen++;
+ }
+ length += idlen;
}
- ap = ap->next;
+ length ++; /* entry separator */
}
- if (count > 0 && ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) {
- length += 10; /* "user::rwx\n" */
- length += 11; /* "group::rwx\n" */
- length += 11; /* "other::rwx\n" */
- }
+ /* Add filemode-mapping access entries to the length */
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ if ((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0) {
+ /* "user::rwx\ngroup::rwx\nother:rwx\n" */
+ length += 31;
+ } else {
+ /* "user::rwx\ngroup::rwx\nother::rwx\n" */
+ length += 32;
+ }
+ } else if (count == 0)
+ return (0);
- if (count == 0)
+ /* The terminating character is included in count */
+ return (length);
+}
+
+/*
+ * Generate a wide text version of the ACL. The flags parameter controls
+ * the type and style of the generated ACL.
+ */
+wchar_t *
+archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
+ struct archive *a)
+{
+ int count;
+ ssize_t length;
+ size_t len;
+ const wchar_t *wname;
+ const wchar_t *prefix;
+ wchar_t separator;
+ struct archive_acl_entry *ap;
+ int id, r, want_type;
+ wchar_t *wp, *ws;
+
+ want_type = archive_acl_text_want_type(acl, flags);
+
+ /* Both NFSv4 and POSIX.1 types found */
+ if (want_type == 0)
+ return (NULL);
+
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)
+ flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
+
+ length = archive_acl_text_len(acl, want_type, flags, 1, a, NULL);
+
+ if (length == 0)
return (NULL);
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA)
+ separator = L',';
+ else
+ separator = L'\n';
+
/* Now, allocate the string and actually populate it. */
- wp = acl->acl_text_w = (wchar_t *)malloc(length * sizeof(wchar_t));
- if (wp == NULL)
+ wp = ws = (wchar_t *)malloc(length * sizeof(wchar_t));
+ if (wp == NULL) {
+ if (errno == ENOMEM)
+ __archive_errx(1, "No memory");
return (NULL);
+ }
count = 0;
- if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
+
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL,
acl->mode & 0700, -1);
- *wp++ = ',';
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL,
+ *wp++ = separator;
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL,
acl->mode & 0070, -1);
- *wp++ = ',';
- append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL,
+ *wp++ = separator;
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_OTHER, flags, NULL,
acl->mode & 0007, -1);
count += 3;
-
- ap = acl->acl_head;
- while (ap != NULL) {
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- r = archive_mstring_get_wcs(a, &ap->name, &wname);
- if (r == 0) {
- *wp++ = separator;
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
- id = ap->id;
- else
- id = -1;
- append_entry_w(&wp, NULL, ap->tag, wname,
- ap->permset, id);
- count++;
- } else if (r < 0 && errno == ENOMEM)
- return (NULL);
- }
- ap = ap->next;
- }
}
-
- if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT)
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & want_type) == 0)
+ continue;
+ /*
+ * Filemode-mapping ACL entries are stored exclusively in
+ * ap->mode so they should not be in the list
+ */
+ if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
+ && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
+ || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
+ || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
+ continue;
+ if (ap->type == ARCHIVE_ENTRY_ACL_TYPE_DEFAULT &&
+ (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0)
prefix = L"default:";
else
prefix = NULL;
- ap = acl->acl_head;
- count = 0;
- while (ap != NULL) {
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
- r = archive_mstring_get_wcs(a, &ap->name, &wname);
- if (r == 0) {
- if (count > 0)
- *wp++ = separator;
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
- id = ap->id;
- else
- id = -1;
- append_entry_w(&wp, prefix, ap->tag,
- wname, ap->permset, id);
- count ++;
- } else if (r < 0 && errno == ENOMEM)
- return (NULL);
- }
- ap = ap->next;
- }
+ r = archive_mstring_get_wcs(a, &ap->name, &wname);
+ if (r == 0) {
+ if (count > 0)
+ *wp++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
+ wname, ap->permset, id);
+ count++;
+ } else if (r < 0 && errno == ENOMEM)
+ return (NULL);
}
- return (acl->acl_text_w);
-}
+ /* Add terminating character */
+ *wp++ = L'\0';
+
+ len = wcslen(ws);
+ if ((ssize_t)len > (length - 1))
+ __archive_errx(1, "Buffer overrun");
+
+ if (text_len != NULL)
+ *text_len = len;
+
+ return (ws);
+}
static void
append_id_w(wchar_t **wp, int id)
@@ -577,8 +738,8 @@ append_id_w(wchar_t **wp, int id)
}
static void
-append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
- const wchar_t *wname, int perm, int id)
+append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
+ int tag, int flags, const wchar_t *wname, int perm, int id)
{
if (prefix != NULL) {
wcscpy(*wp, prefix);
@@ -588,6 +749,10 @@ append_entry_w(wchar_t **wp, const wchar
case ARCHIVE_ENTRY_ACL_USER_OBJ:
wname = NULL;
id = -1;
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ wcscpy(*wp, L"owner@");
+ break;
+ }
/* FALLTHROUGH */
case ARCHIVE_ENTRY_ACL_USER:
wcscpy(*wp, L"user");
@@ -595,6 +760,10 @@ append_entry_w(wchar_t **wp, const wchar
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
wname = NULL;
id = -1;
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ wcscpy(*wp, L"group@");
+ break;
+ }
/* FALLTHROUGH */
case ARCHIVE_ENTRY_ACL_GROUP:
wcscpy(*wp, L"group");
@@ -609,154 +778,210 @@ append_entry_w(wchar_t **wp, const wchar
wname = NULL;
id = -1;
break;
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
+ wcscpy(*wp, L"everyone@");
+ wname = NULL;
+ id = -1;
+ break;
}
*wp += wcslen(*wp);
*(*wp)++ = L':';
- if (wname != NULL) {
- wcscpy(*wp, wname);
+ if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) ||
+ tag == ARCHIVE_ENTRY_ACL_USER ||
+ tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ if (wname != NULL) {
+ wcscpy(*wp, wname);
+ *wp += wcslen(*wp);
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER
+ || tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ append_id_w(wp, id);
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0)
+ id = -1;
+ }
+ /* Solaris style has no second colon after other and mask */
+ if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0)
+ || (tag != ARCHIVE_ENTRY_ACL_OTHER
+ && tag != ARCHIVE_ENTRY_ACL_MASK))
+ *(*wp)++ = L':';
+ }
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
+ /* POSIX.1e ACL perms */
+ *(*wp)++ = (perm & 0444) ? L'r' : L'-';
+ *(*wp)++ = (perm & 0222) ? L'w' : L'-';
+ *(*wp)++ = (perm & 0111) ? L'x' : L'-';
+ } else {
+ /* NFS4 ACL perms */
+ *(*wp)++ = (perm & (ARCHIVE_ENTRY_ACL_READ_DATA |
+ ARCHIVE_ENTRY_ACL_LIST_DIRECTORY)) ? L'r' : L'-';
+ *(*wp)++ = (perm & (ARCHIVE_ENTRY_ACL_WRITE_DATA |
+ ARCHIVE_ENTRY_ACL_ADD_FILE)) ? L'w' : L'-';
+ *(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_EXECUTE) ? L'x' : L'-';
+ *(*wp)++ = (perm & (ARCHIVE_ENTRY_ACL_APPEND_DATA |
+ ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY)) ? L'p' : L'-';
+ *(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_DELETE) ? L'd' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_DELETE_CHILD) ? L'D' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES) ? L'a' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES) ? L'A' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS) ? L'R' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS) ? L'W' : L'-';
+ *(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_READ_ACL) ? L'c' : L'-';
+ *(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_WRITE_ACL) ? L'C' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_WRITE_OWNER) ? L'o' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_SYNCHRONIZE) ? L's' : L'-';
+ *(*wp)++ = L':';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT) ? L'f' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT) ? L'd' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY) ? L'i' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT) ? L'n' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS) ? L'S' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS) ? L'F' : L'-';
+ *(*wp)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_INHERITED) ? L'I' : L'-';
+ *(*wp)++ = L':';
+ switch (type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+ wcscpy(*wp, L"allow");
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+ wcscpy(*wp, L"deny");
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+ wcscpy(*wp, L"audit");
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+ wcscpy(*wp, L"alarm");
+ break;
+ default:
+ break;
+ }
*wp += wcslen(*wp);
- } else if (tag == ARCHIVE_ENTRY_ACL_USER
- || tag == ARCHIVE_ENTRY_ACL_GROUP) {
- append_id_w(wp, id);
- id = -1;
}
- *(*wp)++ = L':';
- *(*wp)++ = (perm & 0444) ? L'r' : L'-';
- *(*wp)++ = (perm & 0222) ? L'w' : L'-';
- *(*wp)++ = (perm & 0111) ? L'x' : L'-';
if (id != -1) {
*(*wp)++ = L':';
append_id_w(wp, id);
}
- **wp = L'\0';
}
-int
-archive_acl_text_l(struct archive_acl *acl, int flags,
- const char **acl_text, size_t *acl_text_len,
+/*
+ * Generate a text version of the ACL. The flags parameter controls
+ * the type and style of the generated ACL.
+ */
+char *
+archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
struct archive_string_conv *sc)
{
int count;
- size_t length;
+ ssize_t length;
+ size_t len;
const char *name;
const char *prefix;
char separator;
struct archive_acl_entry *ap;
- size_t len;
- int id, r;
- char *p;
+ int id, r, want_type;
+ char *p, *s;
- if (acl->acl_text != NULL) {
- free (acl->acl_text);
- acl->acl_text = NULL;
- }
+ want_type = archive_acl_text_want_type(acl, flags);
- *acl_text = NULL;
- if (acl_text_len != NULL)
- *acl_text_len = 0;
- separator = ',';
- count = 0;
- length = 0;
- ap = acl->acl_head;
- while (ap != NULL) {
- if ((ap->type & flags) != 0) {
- count++;
- if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) &&
- (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))
- length += 8; /* "default:" */
- length += 5; /* tag name */
- length += 1; /* colon */
- r = archive_mstring_get_mbs_l(
- &ap->name, &name, &len, sc);
- if (r != 0)
- return (-1);
- if (len > 0 && name != NULL)
- length += len;
- else
- length += sizeof(uid_t) * 3 + 1;
- length ++; /* colon */
- length += 3; /* rwx */
- length += 1; /* colon */
- length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1;
- length ++; /* newline */
- }
- ap = ap->next;
- }
+ /* Both NFSv4 and POSIX.1 types found */
+ if (want_type == 0)
+ return (NULL);
- if (count > 0 && ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) {
- length += 10; /* "user::rwx\n" */
- length += 11; /* "group::rwx\n" */
- length += 11; /* "other::rwx\n" */
- }
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)
+ flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
- if (count == 0)
- return (0);
+ length = archive_acl_text_len(acl, want_type, flags, 0, NULL, sc);
+
+ if (length == 0)
+ return (NULL);
+
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA)
+ separator = ',';
+ else
+ separator = '\n';
/* Now, allocate the string and actually populate it. */
- p = acl->acl_text = (char *)malloc(length);
- if (p == NULL)
- return (-1);
+ p = s = (char *)malloc(length * sizeof(char));
+ if (p == NULL) {
+ if (errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (NULL);
+ }
count = 0;
- if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
- append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
+
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL,
acl->mode & 0700, -1);
- *p++ = ',';
- append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL,
+ *p++ = separator;
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL,
acl->mode & 0070, -1);
- *p++ = ',';
- append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL,
+ *p++ = separator;
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_OTHER, flags, NULL,
acl->mode & 0007, -1);
count += 3;
-
- for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) == 0)
- continue;
- r = archive_mstring_get_mbs_l(
- &ap->name, &name, &len, sc);
- if (r != 0)
- return (-1);
- *p++ = separator;
- if (name == NULL || (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)) {
- id = ap->id;
- } else {
- id = -1;
- }
- append_entry(&p, NULL, ap->tag, name,
- ap->permset, id);
- count++;
- }
}
-
- if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT)
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & want_type) == 0)
+ continue;
+ /*
+ * Filemode-mapping ACL entries are stored exclusively in
+ * ap->mode so they should not be in the list
+ */
+ if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
+ && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
+ || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
+ || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
+ continue;
+ if (ap->type == ARCHIVE_ENTRY_ACL_TYPE_DEFAULT &&
+ (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0)
prefix = "default:";
else
prefix = NULL;
- count = 0;
- for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) == 0)
- continue;
- r = archive_mstring_get_mbs_l(
- &ap->name, &name, &len, sc);
- if (r != 0)
- return (-1);
- if (count > 0)
- *p++ = separator;
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
- id = ap->id;
- else
- id = -1;
- append_entry(&p, prefix, ap->tag,
- name, ap->permset, id);
- count ++;
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (NULL);
+ if (count > 0)
+ *p++ = separator;
+ if (name == NULL ||
+ (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)) {
+ id = ap->id;
+ } else {
+ id = -1;
}
+ append_entry(&p, prefix, ap->type, ap->tag, flags, name,
+ ap->permset, id);
+ count++;
}
- *acl_text = acl->acl_text;
- if (acl_text_len != NULL)
- *acl_text_len = strlen(acl->acl_text);
- return (0);
+ /* Add terminating character */
+ *p++ = '\0';
+
+ len = strlen(s);
+
+ if ((ssize_t)len > (length - 1))
+ __archive_errx(1, "Buffer overrun");
+
+ if (text_len != NULL)
+ *text_len = len;
+
+ return (s);
}
static void
@@ -770,8 +995,8 @@ append_id(char **p, int id)
}
static void
-append_entry(char **p, const char *prefix, int tag,
- const char *name, int perm, int id)
+append_entry(char **p, const char *prefix, int type,
+ int tag, int flags, const char *name, int perm, int id)
{
if (prefix != NULL) {
strcpy(*p, prefix);
@@ -781,6 +1006,10 @@ append_entry(char **p, const char *prefi
case ARCHIVE_ENTRY_ACL_USER_OBJ:
name = NULL;
id = -1;
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ strcpy(*p, "owner@");
+ break;
+ }
/* FALLTHROUGH */
case ARCHIVE_ENTRY_ACL_USER:
strcpy(*p, "user");
@@ -788,6 +1017,10 @@ append_entry(char **p, const char *prefi
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
name = NULL;
id = -1;
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
+ strcpy(*p, "group@");
+ break;
+ }
/* FALLTHROUGH */
case ARCHIVE_ENTRY_ACL_GROUP:
strcpy(*p, "group");
@@ -802,48 +1035,147 @@ append_entry(char **p, const char *prefi
name = NULL;
id = -1;
break;
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
+ strcpy(*p, "everyone@");
+ name = NULL;
+ id = -1;
+ break;
}
*p += strlen(*p);
*(*p)++ = ':';
- if (name != NULL) {
- strcpy(*p, name);
+ if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) ||
+ tag == ARCHIVE_ENTRY_ACL_USER ||
+ tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ if (name != NULL) {
+ strcpy(*p, name);
+ *p += strlen(*p);
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER
+ || tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ append_id(p, id);
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0)
+ id = -1;
+ }
+ /* Solaris style has no second colon after other and mask */
+ if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0)
+ || (tag != ARCHIVE_ENTRY_ACL_OTHER
+ && tag != ARCHIVE_ENTRY_ACL_MASK))
+ *(*p)++ = ':';
+ }
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
+ /* POSIX.1e ACL perms */
+ *(*p)++ = (perm & 0444) ? 'r' : '-';
+ *(*p)++ = (perm & 0222) ? 'w' : '-';
+ *(*p)++ = (perm & 0111) ? 'x' : '-';
+ } else {
+ /* NFS4 ACL perms */
+ *(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_READ_DATA |
+ ARCHIVE_ENTRY_ACL_LIST_DIRECTORY)) ? 'r' : '-';
+ *(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_WRITE_DATA |
+ ARCHIVE_ENTRY_ACL_ADD_FILE)) ? 'w' : '-';
+ *(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_EXECUTE)) ? 'x' : '-';
+ *(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_APPEND_DATA |
+ ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY)) ? 'p' : '-';
+ *(*p)++ = (perm & ARCHIVE_ENTRY_ACL_DELETE) ? 'd' : '-';
+ *(*p)++ = (perm & ARCHIVE_ENTRY_ACL_DELETE_CHILD) ? 'D' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES) ? 'a' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES) ? 'A' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS) ? 'R' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS) ? 'W' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_READ_ACL) ? 'c' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_WRITE_ACL) ? 'C' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_WRITE_OWNER) ? 'o' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_SYNCHRONIZE) ? 's' : '-';
+ *(*p)++ = ':';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT) ? 'f' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT) ? 'd' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY) ? 'i' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT) ? 'n' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS) ? 'S' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS) ? 'F' : '-';
+ *(*p)++ = (perm &
+ ARCHIVE_ENTRY_ACL_ENTRY_INHERITED) ? 'I' : '-';
+ *(*p)++ = ':';
+ switch (type) {
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+ strcpy(*p, "allow");
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+ strcpy(*p, "deny");
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+ strcpy(*p, "audit");
+ break;
+ case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+ strcpy(*p, "alarm");
+ break;
+ }
*p += strlen(*p);
- } else if (tag == ARCHIVE_ENTRY_ACL_USER
- || tag == ARCHIVE_ENTRY_ACL_GROUP) {
- append_id(p, id);
- id = -1;
}
- *(*p)++ = ':';
- *(*p)++ = (perm & 0444) ? 'r' : '-';
- *(*p)++ = (perm & 0222) ? 'w' : '-';
- *(*p)++ = (perm & 0111) ? 'x' : '-';
if (id != -1) {
*(*p)++ = ':';
append_id(p, id);
}
- **p = '\0';
}
/*
- * Parse a textual ACL. This automatically recognizes and supports
- * extensions described above. The 'type' argument is used to
- * indicate the type that should be used for any entries not
- * explicitly marked as "default:".
+ * Parse a wide ACL text string.
+ *
+ * The want_type argument may be one of the following:
+ * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - text is a POSIX.1e ACL of type ACCESS
+ * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - text is a POSIX.1e ACL of type DEFAULT
+ * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - text is as a NFSv4 ACL
+ *
+ * POSIX.1e ACL entries prefixed with "default:" are treated as
+ * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is ARCHIVE_ENTRY_ACL_TYPE_NFS4
*/
int
-archive_acl_parse_w(struct archive_acl *acl,
- const wchar_t *text, int default_type)
+archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
+ int want_type)
{
struct {
const wchar_t *start;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable
mailing list