From c438d3849218111797309c4e3c5cc0da13026f9e Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Mon, 29 Aug 2016 06:50:45 +0000 Subject: [PATCH] Revert r304869 This commit was incorrect and will be re-committed asap. --- contrib/libarchive/libarchive/archive_acl.c | 906 ++++-------------- contrib/libarchive/libarchive/archive_entry.h | 5 +- .../archive_read_disk_entry_from_file.c | 201 ++-- .../archive_read_support_format_tar.c | 120 +-- .../archive_read_support_format_zip.c | 42 +- .../libarchive/archive_write_disk_acl.c | 85 +- .../libarchive/archive_write_disk_posix.c | 12 +- .../libarchive/archive_write_set_format_pax.c | 112 +-- contrib/libarchive/tar/util.c | 2 +- 9 files changed, 382 insertions(+), 1103 deletions(-) diff --git a/contrib/libarchive/libarchive/archive_acl.c b/contrib/libarchive/libarchive/archive_acl.c index 4dbded19cf11..bf4b61040ef6 100644 --- a/contrib/libarchive/libarchive/archive_acl.c +++ b/contrib/libarchive/libarchive/archive_acl.c @@ -57,27 +57,21 @@ static int archive_acl_add_entry_len_l(struct archive_acl *acl, size_t len, 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 parse_nfs4_flags_w(const wchar_t *start, const wchar_t *end, - int *result); -static int parse_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 type, - int tag, const wchar_t *wname, int perm, int id); +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_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 parse_nfs4_flags(const char *start, const char *end, int *result); -static int parse_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 type, - int tag, const char *name, int perm, int id); +static void append_entry(char **p, const char *prefix, int tag, + const char *name, int perm, int id); static void append_id(char **p, int id); void @@ -453,16 +447,6 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags) int id, r; wchar_t *wp; - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) && - (flags & (ARCHIVE_ENTRY_ACL_TYPE_ACCESS | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))) { - /* cannot convert NFSv4 ACLs and POSIX1e ACLs at the same time */ - return (NULL); - } - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) && (flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)) { - /* cannot have access and default at the same time */ - return (NULL); - } - if (acl->acl_text_w != NULL) { free (acl->acl_text_w); acl->acl_text_w = NULL; @@ -478,57 +462,17 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags) if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) && (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)) length += 8; /* "default:" */ - switch (ap->tag) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - length += 6; /* "owner@" */ - break; - } - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_USER: - length += 4; /* "user" */ - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - 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 += 5; /* tag name */ length += 1; /* colon */ - if (((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0) || - ap->tag == ARCHIVE_ENTRY_ACL_USER || - ap->tag == ARCHIVE_ENTRY_ACL_GROUP) { - 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 += 1; /* colon */ - } - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) - length += 14; /* rwxpdDaARWcCos */ + 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 += 3; /* rwx */ - length += 1; /* colon */ - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - length += 7; /* fdinSFI */ - length += 1; /* colon */ - if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DENY) != 0) - length += 4; /* deny */ - else - length += 5; /* allow, alarm, audit */ - length += 1; /* colon */ - } + 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 */ @@ -536,39 +480,34 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags) ap = ap->next; } - if (count == 0) - return (NULL); - - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { + 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 (count == 0) + return (NULL); + /* Now, allocate the string and actually populate it. */ wp = acl->acl_text_w = (wchar_t *)malloc(length * sizeof(wchar_t)); if (wp == NULL) return (NULL); count = 0; - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_USER_OBJ, NULL, acl->mode & 0700, -1); + append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL, + acl->mode & 0700, -1); *wp++ = ','; - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL, acl->mode & 0070, -1); + append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL, + acl->mode & 0070, -1); *wp++ = ','; - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_OTHER, NULL, acl->mode & 0007, -1); + append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL, + acl->mode & 0007, -1); count += 3; - } - if ((flags & (ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_TYPE_NFS4)) != 0) { ap = acl->acl_head; while (ap != NULL) { - if ((ap->type & (ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_TYPE_NFS4)) != 0) { + if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { r = archive_mstring_get_wcs(a, &ap->name, &wname); if (r == 0) { *wp++ = separator; @@ -576,8 +515,8 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags) id = ap->id; else id = -1; - append_entry_w(&wp, NULL, ap->type, ap->tag, - wname, ap->permset, id); + append_entry_w(&wp, NULL, ap->tag, wname, + ap->permset, id); count++; } else if (r < 0 && errno == ENOMEM) return (NULL); @@ -586,6 +525,7 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags) } } + if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) { if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) prefix = L"default:"; @@ -603,8 +543,8 @@ archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags) id = ap->id; else id = -1; - append_entry_w(&wp, prefix, ap->type, - ap->tag, wname, ap->permset, id); + append_entry_w(&wp, prefix, ap->tag, + wname, ap->permset, id); count ++; } else if (r < 0 && errno == ENOMEM) return (NULL); @@ -628,8 +568,8 @@ append_id_w(wchar_t **wp, int id) } static void -append_entry_w(wchar_t **wp, const wchar_t *prefix, int type, - int tag, const wchar_t *wname, int perm, int id) +append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag, + const wchar_t *wname, int perm, int id) { if (prefix != NULL) { wcscpy(*wp, prefix); @@ -639,11 +579,6 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type, case ARCHIVE_ENTRY_ACL_USER_OBJ: wname = NULL; id = -1; - if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - wcscpy(*wp, L"owner@"); - break; - } - /* FALLTHROUGH */ /* FALLTHROUGH */ case ARCHIVE_ENTRY_ACL_USER: wcscpy(*wp, L"user"); @@ -668,57 +603,18 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type, } *wp += wcslen(*wp); *(*wp)++ = L':'; - if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 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); - id = -1; - } - *(*wp)++ = L':'; - } - *(*wp)++ = (perm & (ARCHIVE_ENTRY_ACL_READ | - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_LIST_DIRECTORY)) ? L'r' : L'-'; - *(*wp)++ = (perm & (ARCHIVE_ENTRY_ACL_WRITE | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_ADD_FILE)) ? L'w' : L'-'; - *(*wp)++ = (perm & ARCHIVE_ENTRY_ACL_EXECUTE) ? L'x' : L'-'; - if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - *(*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':'; - if (type & ARCHIVE_ENTRY_ACL_TYPE_ALLOW) - wcscpy(*wp, L"allow"); - else if (type & ARCHIVE_ENTRY_ACL_TYPE_DENY) - wcscpy(*wp, L"deny"); - else if (type & ARCHIVE_ENTRY_ACL_TYPE_AUDIT) - wcscpy(*wp, L"audit"); - else if (type & ARCHIVE_ENTRY_ACL_TYPE_ALARM) - wcscpy(*wp, L"alarm"); + 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); + 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); @@ -741,16 +637,6 @@ archive_acl_text_l(struct archive_acl *acl, int flags, int id, r; char *p; - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) && - (flags & (ARCHIVE_ENTRY_ACL_TYPE_ACCESS | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))) { - /* cannot convert NFSv4 ACLs and POSIX1e ACLs at the same time */ - return (-1); - } - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) && (flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)) { - /* cannot have access and default at the same time */ - return (-1); - } - if (acl->acl_text != NULL) { free (acl->acl_text); acl->acl_text = NULL; @@ -769,109 +655,63 @@ archive_acl_text_l(struct archive_acl *acl, int flags, if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) && (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)) length += 8; /* "default:" */ - switch (ap->tag) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - length += 6; /* "owner@" */ - break; - } - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_USER: - length += 4; /* "user" */ - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - 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 += 5; /* tag name */ length += 1; /* colon */ - if (((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0) || - ap->tag == ARCHIVE_ENTRY_ACL_USER || - ap->tag == ARCHIVE_ENTRY_ACL_GROUP) { - 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 += 1; /* colon */ - } - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) - length += 14; /* rwxpdDaARWcCos */ + 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 += 3; /* rwx */ + length += sizeof(uid_t) * 3 + 1; + length ++; /* colon */ + length += 3; /* rwx */ length += 1; /* colon */ - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - length += 7; /* fdinSFI */ - length += 1; /* colon */ - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DENY) != 0) - length += 4; /* deny */ - else - length += 5; /* allow, alarm, audit */ - length += 1; /* colon */ - } - length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1; length ++; /* newline */ } ap = ap->next; } - if (count == 0) - return (0); - - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { + 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 (count == 0) + return (0); + /* Now, allocate the string and actually populate it. */ p = acl->acl_text = (char *)malloc(length); if (p == NULL) return (-1); count = 0; if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_USER_OBJ, NULL, acl->mode & 0700, -1); + append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL, + acl->mode & 0700, -1); *p++ = ','; - append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL, acl->mode & 0070, -1); + append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL, + acl->mode & 0070, -1); *p++ = ','; - append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_OTHER, NULL, acl->mode & 0007, -1); + append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL, + acl->mode & 0007, -1); count += 3; - } - if ((flags & (ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_TYPE_NFS4)) != 0) { for (ap = acl->acl_head; ap != NULL; ap = ap->next) { - if ((ap->type & (ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_TYPE_NFS4)) == 0) + 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); - if (count > 0) - *p++ = separator; + *p++ = separator; if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) id = ap->id; else id = -1; - append_entry(&p, NULL, ap->type, ap->tag, name, + append_entry(&p, NULL, ap->tag, name, ap->permset, id); count++; } @@ -897,7 +737,7 @@ archive_acl_text_l(struct archive_acl *acl, int flags, id = ap->id; else id = -1; - append_entry(&p, prefix, ap->type, ap->tag, + append_entry(&p, prefix, ap->tag, name, ap->permset, id); count ++; } @@ -920,8 +760,8 @@ append_id(char **p, int id) } static void -append_entry(char **p, const char *prefix, int type, - int tag, const char *name, int perm, int id) +append_entry(char **p, const char *prefix, int tag, + const char *name, int perm, int id) { if (prefix != NULL) { strcpy(*p, prefix); @@ -931,10 +771,6 @@ append_entry(char **p, const char *prefix, int type, case ARCHIVE_ENTRY_ACL_USER_OBJ: name = NULL; id = -1; - if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - strcpy(*p, "owner@"); - break; - } /* FALLTHROUGH */ case ARCHIVE_ENTRY_ACL_USER: strcpy(*p, "user"); @@ -942,10 +778,6 @@ append_entry(char **p, const char *prefix, int type, case ARCHIVE_ENTRY_ACL_GROUP_OBJ: name = NULL; id = -1; - if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - strcpy(*p, "group@"); - break; - } /* FALLTHROUGH */ case ARCHIVE_ENTRY_ACL_GROUP: strcpy(*p, "group"); @@ -960,65 +792,21 @@ append_entry(char **p, const char *prefix, int type, name = NULL; id = -1; break; - case ARCHIVE_ENTRY_ACL_EVERYONE: - strcpy(*p, "everyone@"); - name = NULL; - id = -1; - break; } *p += strlen(*p); *(*p)++ = ':'; - if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 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); - id = -1; - } - *(*p)++ = ':'; - } - *(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_READ | - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_LIST_DIRECTORY)) ? 'r' : '-'; - *(*p)++ = (perm & (ARCHIVE_ENTRY_ACL_WRITE | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_ADD_FILE)) ? 'w' : '-'; - *(*p)++ = (perm & ARCHIVE_ENTRY_ACL_EXECUTE) ? 'x' : '-'; - if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - *(*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)++ = ':'; - if (type & ARCHIVE_ENTRY_ACL_TYPE_ALLOW) - strcpy(*p, "allow"); - else if (type & ARCHIVE_ENTRY_ACL_TYPE_DENY) - strcpy(*p, "deny"); - else if (type & ARCHIVE_ENTRY_ACL_TYPE_AUDIT) - strcpy(*p, "audit"); - else if (type & ARCHIVE_ENTRY_ACL_TYPE_ALARM) - strcpy(*p, "alarm"); + 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); + id = -1; } + *(*p)++ = ':'; + *(*p)++ = (perm & 0444) ? 'r' : '-'; + *(*p)++ = (perm & 0222) ? 'w' : '-'; + *(*p)++ = (perm & 0111) ? 'x' : '-'; if (id != -1) { *(*p)++ = ':'; append_id(p, id); @@ -1039,19 +827,12 @@ archive_acl_parse_w(struct archive_acl *acl, struct { const wchar_t *start; const wchar_t *end; - } field[6], name; + } field[4], name; - int numfields, fields, n; + int fields, n; int type, tag, permset, id; - int offset; wchar_t sep; - if (default_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) - numfields = 6; - else - numfields = 4; - - while (text != NULL && *text != L'\0') { /* * Parse the fields out of the next entry, @@ -1061,7 +842,7 @@ archive_acl_parse_w(struct archive_acl *acl, do { const wchar_t *start, *end; next_field_w(&text, &start, &end, &sep); - if (fields < numfields) { + if (fields < 4) { field[fields].start = start; field[fields].end = end; } @@ -1069,148 +850,72 @@ archive_acl_parse_w(struct archive_acl *acl, } while (sep == L':'); /* Set remaining fields to blank. */ - for (n = fields; n < numfields; ++n) + for (n = fields; n < 4; ++n) field[n].start = field[n].end = NULL; - if (default_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - /* POSIX.1e ACLs */ - /* Check for a numeric ID in field 1 or 3. */ - id = -1; - isint_w(field[1].start, field[1].end, &id); - /* Field 3 is optional. */ - if (id == -1 && fields > 3) - isint_w(field[3].start, field[3].end, &id); + /* Check for a numeric ID in field 1 or 3. */ + id = -1; + isint_w(field[1].start, field[1].end, &id); + /* Field 3 is optional. */ + if (id == -1 && fields > 3) + isint_w(field[3].start, field[3].end, &id); - /* - * Solaris extension: "defaultuser::rwx" is the - * default ACL corresponding to "user::rwx", etc. - */ - if (field[0].end - field[0].start > 7 - && wmemcmp(field[0].start, L"default", 7) == 0) { - type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; - field[0].start += 7; - } else - type = default_type; + /* + * Solaris extension: "defaultuser::rwx" is the + * default ACL corresponding to "user::rwx", etc. + */ + if (field[0].end - field[0].start > 7 + && wmemcmp(field[0].start, L"default", 7) == 0) { + type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; + field[0].start += 7; + } else + type = default_type; - name.start = name.end = NULL; - if (prefix_w(field[0].start, field[0].end, L"user")) { - if (!ismode_w(field[2].start, field[2].end, - &permset)) + name.start = name.end = NULL; + if (prefix_w(field[0].start, field[0].end, L"user")) { + if (!ismode_w(field[2].start, field[2].end, &permset)) return (ARCHIVE_WARN); - if (id != -1 || field[1].start < field[1].end) { - tag = ARCHIVE_ENTRY_ACL_USER; - name = field[1]; - } else - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - } else if (prefix_w(field[0].start, field[0].end, - L"group")) { - if (!ismode_w(field[2].start, field[2].end, - &permset)) - return (ARCHIVE_WARN); - if (id != -1 || field[1].start < field[1].end) { - tag = ARCHIVE_ENTRY_ACL_GROUP; - name = field[1]; - } else - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - } else if (prefix_w(field[0].start, field[0].end, - L"other")) { - if (fields == 2 - && field[1].start < field[1].end - && ismode_w(field[1].start, field[1].end, - &permset)) { - /* This is Solaris-style "other:rwx" */ - } else if (fields == 3 - && field[1].start == field[1].end - && field[2].start < field[2].end - && ismode_w(field[2].start, field[2].end, - &permset)) { - /* This is FreeBSD-style "other::rwx" */ - } else - return (ARCHIVE_WARN); - tag = ARCHIVE_ENTRY_ACL_OTHER; - } else if (prefix_w(field[0].start, field[0].end, - L"mask")) { - if (fields == 2 - && field[1].start < field[1].end - && ismode_w(field[1].start, field[1].end, - &permset)) { - /* This is Solaris-style "mask:rwx" */ - } else if (fields == 3 - && field[1].start == field[1].end - && field[2].start < field[2].end - && ismode_w(field[2].start, field[2].end, - &permset)) { - /* This is FreeBSD-style "mask::rwx" */ - } else - return (ARCHIVE_WARN); - tag = ARCHIVE_ENTRY_ACL_MASK; - } else - return (ARCHIVE_WARN); - } else { - /* NFSv4 ACLs */ - if (wcsncmp(field[0].start, L"user", - field[0].end - field[0].start) == 0) + if (id != -1 || field[1].start < field[1].end) { tag = ARCHIVE_ENTRY_ACL_USER; - else if (wcsncmp(field[0].start, L"group", - field[0].end - field[0].start) == 0) - tag = ARCHIVE_ENTRY_ACL_GROUP; - else if (wcsncmp(field[0].start, L"owner@", - field[0].end - field[0].start) == 0) - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - else if (wcsncmp(field[0].start, L"group@", - field[0].end - field[0].start) == 0) - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - else if (wcsncmp(field[0].start, L"everyone@", - field[0].end - field[0].start) == 0) - tag = ARCHIVE_ENTRY_ACL_EVERYONE; - else { - /* Unknown entry */ - return (ARCHIVE_WARN); - } - - permset = 0; - name.start = name.end = NULL; - - if (tag == ARCHIVE_ENTRY_ACL_USER || - tag == ARCHIVE_ENTRY_ACL_GROUP) { - offset = 1; name = field[1]; } else - offset = 0; - - if (parse_nfs4_perms_w(field[1 + offset].start, - field[1 + offset].end, &permset) != 0) { - /* NFS4 perms are invalid */ + tag = ARCHIVE_ENTRY_ACL_USER_OBJ; + } else if (prefix_w(field[0].start, field[0].end, L"group")) { + if (!ismode_w(field[2].start, field[2].end, &permset)) return (ARCHIVE_WARN); - } - if (parse_nfs4_flags_w(field[2 + offset].start, - field[2 + offset].end, &permset) != 0) { - /* NFS4 flags are invalid */ + if (id != -1 || field[1].start < field[1].end) { + tag = ARCHIVE_ENTRY_ACL_GROUP; + name = field[1]; + } else + tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; + } else if (prefix_w(field[0].start, field[0].end, L"other")) { + if (fields == 2 + && field[1].start < field[1].end + && ismode_w(field[1].start, field[1].end, &permset)) { + /* This is Solaris-style "other:rwx" */ + } else if (fields == 3 + && field[1].start == field[1].end + && field[2].start < field[2].end + && ismode_w(field[2].start, field[2].end, &permset)) { + /* This is FreeBSD-style "other::rwx" */ + } else return (ARCHIVE_WARN); - } - if (wcsncmp(field[3 + offset].start, L"allow", - field[3 + offset].end - field[3 + offset].start) - == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - else if (wcsncmp(field[3 + offset].start, L"deny", - field[3 + offset].end - field[3 + offset].start) - == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - else if (wcsncmp(field[3 + offset].start, L"audit", - field[3 + offset].end - field[3 + offset].start) - == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT; - else if (wcsncmp(field[3 + offset].start, L"alarm", - field[3 + offset].end - field[3 + offset].start) - == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; - else { - /* Unknown type */ + tag = ARCHIVE_ENTRY_ACL_OTHER; + } else if (prefix_w(field[0].start, field[0].end, L"mask")) { + if (fields == 2 + && field[1].start < field[1].end + && ismode_w(field[1].start, field[1].end, &permset)) { + /* This is Solaris-style "mask:rwx" */ + } else if (fields == 3 + && field[1].start == field[1].end + && field[2].start < field[2].end + && ismode_w(field[2].start, field[2].end, &permset)) { + /* This is FreeBSD-style "mask::rwx" */ + } else return (ARCHIVE_WARN); - } - isint_w(field[4 + offset].start, field[4 + offset].end, - &id); - } + tag = ARCHIVE_ENTRY_ACL_MASK; + } else + return (ARCHIVE_WARN); /* Add entry to the internal list. */ archive_acl_add_entry_w_len(acl, type, permset, @@ -1280,78 +985,6 @@ ismode_w(const wchar_t *start, const wchar_t *end, int *permset) return (1); } -/* Parse a wstring as a strict NFSv4 ACL permission field. */ -static int -parse_nfs4_perms_w(const wchar_t *start, const wchar_t *end, int *permset) -{ - const wchar_t *p; - int pos; - const wchar_t *letter = L"rwxpdDaARWcCos"; - const int perms[14] = { - ARCHIVE_ENTRY_ACL_READ_DATA, - ARCHIVE_ENTRY_ACL_WRITE_DATA, - ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_APPEND_DATA, - ARCHIVE_ENTRY_ACL_DELETE, - 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 - }; - - if (start >= end) - return (0); - p = start; - pos = 0; - while (p < end && pos < 14) { - if (*p == letter[pos]) - *permset |= perms[pos]; - else if (*p != '-') - return (-1); - p = p + sizeof(wchar_t); - pos++; - } - return (0); -} - -/* Parse a string as a strict NFSv4 ACL flags field. */ -static int -parse_nfs4_flags_w(const wchar_t *start, const wchar_t *end, int *permset) -{ - const wchar_t *p; - int pos; - const wchar_t *letter = L"fdinSFI"; - const int perms[7] = { - ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, - ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, - ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, - ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, - ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, - ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, - ARCHIVE_ENTRY_ACL_ENTRY_INHERITED - }; - - if (start >= end) - return (0); - p = start; - pos = 0; - while (p < end && pos < 7) { - if (*p == letter[pos]) - *permset |= perms[pos]; - else if (*p != '-') - return (-1); - p = p + sizeof(wchar_t); - pos++; - } - return (0); -} - - /* * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated * to point to just after the separator. *start points to the first @@ -1424,18 +1057,12 @@ archive_acl_parse_l(struct archive_acl *acl, struct { const char *start; const char *end; - } field[6], name; + } field[4], name; - int numfields, fields, n, r, ret = ARCHIVE_OK; + int fields, n, r, ret = ARCHIVE_OK; int type, tag, permset, id; - int offset; char sep; - if (default_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) - numfields = 6; - else - numfields = 4; - while (text != NULL && *text != '\0') { /* * Parse the fields out of the next entry, @@ -1445,7 +1072,7 @@ archive_acl_parse_l(struct archive_acl *acl, do { const char *start, *end; next_field(&text, &start, &end, &sep); - if (fields < numfields) { + if (fields < 4) { field[fields].start = start; field[fields].end = end; } @@ -1453,148 +1080,72 @@ archive_acl_parse_l(struct archive_acl *acl, } while (sep == ':'); /* Set remaining fields to blank. */ - for (n = fields; n < numfields; ++n) + for (n = fields; n < 4; ++n) field[n].start = field[n].end = NULL; - if (default_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - /* POSIX.1e ACLs */ - /* Check for a numeric ID in field 1 or 3. */ - id = -1; - isint(field[1].start, field[1].end, &id); - /* Field 3 is optional. */ - if (id == -1 && fields > 3) - isint(field[3].start, field[3].end, &id); + /* Check for a numeric ID in field 1 or 3. */ + id = -1; + isint(field[1].start, field[1].end, &id); + /* Field 3 is optional. */ + if (id == -1 && fields > 3) + isint(field[3].start, field[3].end, &id); - /* - * Solaris extension: "defaultuser::rwx" is the - * default ACL corresponding to "user::rwx", etc. - */ - if (field[0].end - field[0].start > 7 - && memcmp(field[0].start, "default", 7) == 0) { - type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; - field[0].start += 7; - } else - type = default_type; + /* + * Solaris extension: "defaultuser::rwx" is the + * default ACL corresponding to "user::rwx", etc. + */ + if (field[0].end - field[0].start > 7 + && memcmp(field[0].start, "default", 7) == 0) { + type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; + field[0].start += 7; + } else + type = default_type; - name.start = name.end = NULL; - if (prefix_c(field[0].start, field[0].end, "user")) { - if (!ismode(field[2].start, field[2].end, - &permset)) - return (ARCHIVE_WARN); - if (id != -1 || field[1].start < field[1].end) { - tag = ARCHIVE_ENTRY_ACL_USER; - name = field[1]; - } else - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - } else if (prefix_c(field[0].start, field[0].end, - "group")) { - if (!ismode(field[2].start, field[2].end, - &permset)) - return (ARCHIVE_WARN); - if (id != -1 || field[1].start < field[1].end) { - tag = ARCHIVE_ENTRY_ACL_GROUP; - name = field[1]; - } else - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - } else if (prefix_c(field[0].start, field[0].end, - "other")) { - if (fields == 2 - && field[1].start < field[1].end - && ismode(field[1].start, field[1].end, - &permset)) { - /* This is Solaris-style "other:rwx" */ - } else if (fields == 3 - && field[1].start == field[1].end - && field[2].start < field[2].end - && ismode(field[2].start, field[2].end, - &permset)) { - /* This is FreeBSD-style "other::rwx" */ - } else - return (ARCHIVE_WARN); - tag = ARCHIVE_ENTRY_ACL_OTHER; - } else if (prefix_c(field[0].start, field[0].end, - "mask")) { - if (fields == 2 - && field[1].start < field[1].end - && ismode(field[1].start, field[1].end, - &permset)) { - /* This is Solaris-style "mask:rwx" */ - } else if (fields == 3 - && field[1].start == field[1].end - && field[2].start < field[2].end - && ismode(field[2].start, field[2].end, - &permset)) { - /* This is FreeBSD-style "mask::rwx" */ - } else - return (ARCHIVE_WARN); - tag = ARCHIVE_ENTRY_ACL_MASK; - } else + name.start = name.end = NULL; + if (prefix_c(field[0].start, field[0].end, "user")) { + if (!ismode(field[2].start, field[2].end, &permset)) return (ARCHIVE_WARN); - } else { - /* NFSv4 ACLs */ - if (strncmp(field[0].start, "user", - field[0].end - field[0].start) == 0) + if (id != -1 || field[1].start < field[1].end) { tag = ARCHIVE_ENTRY_ACL_USER; - else if (strncmp(field[0].start, "group", - field[0].end - field[0].start) == 0) - tag = ARCHIVE_ENTRY_ACL_GROUP; - else if (strncmp(field[0].start, "owner@", - field[0].end - field[0].start) == 0) - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - else if (strncmp(field[0].start, "group@", - field[0].end - field[0].start) == 0) - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - else if (strncmp(field[0].start, "everyone@", - field[0].end - field[0].start) == 0) - tag = ARCHIVE_ENTRY_ACL_EVERYONE; - else { - /* Unknown entry */ - return (ARCHIVE_WARN); - } - - permset = 0; - name.start = name.end = NULL; - - if (tag == ARCHIVE_ENTRY_ACL_USER || - tag == ARCHIVE_ENTRY_ACL_GROUP) { - offset = 1; name = field[1]; } else - offset = 0; - - if (parse_nfs4_perms(field[1 + offset].start, - field[1 + offset].end, &permset) != 0) { - /* NFS4 perms are invalid */ + tag = ARCHIVE_ENTRY_ACL_USER_OBJ; + } else if (prefix_c(field[0].start, field[0].end, "group")) { + if (!ismode(field[2].start, field[2].end, &permset)) return (ARCHIVE_WARN); - } - if (parse_nfs4_flags(field[2 + offset].start, - field[2 + offset].end, &permset) != 0) { - /* NFS4 flags are invalid */ + if (id != -1 || field[1].start < field[1].end) { + tag = ARCHIVE_ENTRY_ACL_GROUP; + name = field[1]; + } else + tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; + } else if (prefix_c(field[0].start, field[0].end, "other")) { + if (fields == 2 + && field[1].start < field[1].end + && ismode(field[1].start, field[1].end, &permset)) { + /* This is Solaris-style "other:rwx" */ + } else if (fields == 3 + && field[1].start == field[1].end + && field[2].start < field[2].end + && ismode(field[2].start, field[2].end, &permset)) { + /* This is FreeBSD-style "other::rwx" */ + } else return (ARCHIVE_WARN); - } - if (strncmp(field[3 + offset].start, "allow", - field[3 + offset].end - field[3 + offset].start) - == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - else if (strncmp(field[3 + offset].start, "deny", - field[3 + offset].end - field[3 + offset].start) - == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - else if (strncmp(field[3 + offset].start, "audit", - field[3 + offset].end - field[3 + offset].start) - == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT; - else if (strncmp(field[3 + offset].start, "alarm", - field[3 + offset].end - field[3 + offset].start) - == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; - else { - /* Unknown type */ + tag = ARCHIVE_ENTRY_ACL_OTHER; + } else if (prefix_c(field[0].start, field[0].end, "mask")) { + if (fields == 2 + && field[1].start < field[1].end + && ismode(field[1].start, field[1].end, &permset)) { + /* This is Solaris-style "mask:rwx" */ + } else if (fields == 3 + && field[1].start == field[1].end + && field[2].start < field[2].end + && ismode(field[2].start, field[2].end, &permset)) { + /* This is FreeBSD-style "mask::rwx" */ + } else return (ARCHIVE_WARN); - } - isint(field[4 + offset].start, field[4 + offset].end, - &id); - } + tag = ARCHIVE_ENTRY_ACL_MASK; + } else + return (ARCHIVE_WARN); /* Add entry to the internal list. */ r = archive_acl_add_entry_len_l(acl, type, permset, @@ -1668,77 +1219,6 @@ ismode(const char *start, const char *end, int *permset) return (1); } -/* Parse a string as a strict NFSv4 ACL permission field. */ -static int -parse_nfs4_perms(const char *start, const char *end, int *permset) -{ - const char *p; - int pos; - const char *letter = "rwxpdDaARWcCos"; - const int perms[14] = { - ARCHIVE_ENTRY_ACL_READ_DATA, - ARCHIVE_ENTRY_ACL_WRITE_DATA, - ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_APPEND_DATA, - ARCHIVE_ENTRY_ACL_DELETE, - 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 - }; - - if (start >= end) - return (0); - p = start; - pos = 0; - while (p < end && pos < 14) { - if (*p == letter[pos]) - *permset |= perms[pos]; - else if (*p != '-') - return (-1); - p = p + sizeof(char); - pos++; - } - return (0); -} - -/* Parse a string as a strict NFSv4 ACL flags field. */ -static int -parse_nfs4_flags(const char *start, const char *end, int *permset) -{ - const char *p; - int pos; - const char *letter = "fdinSFI"; - const int perms[7] = { - ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, - ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, - ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, - ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, - ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, - ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, - ARCHIVE_ENTRY_ACL_ENTRY_INHERITED - }; - - if (start >= end) - return (0); - p = start; - pos = 0; - while (p < end && pos < 7) { - if (*p == letter[pos]) - *permset |= perms[pos]; - else if (*p != '-') - return (-1); - p = p + sizeof(char); - pos++; - } - return (0); -} - /* * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated * to point to just after the separator. *start points to the first diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h index 5ea5369555c3..3a90ac72fec6 100644 --- a/contrib/libarchive/libarchive/archive_entry.h +++ b/contrib/libarchive/libarchive/archive_entry.h @@ -426,7 +426,6 @@ __LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const voi #define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000 #define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000 #define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000 -#define ARCHIVE_ENTRY_ACL_ENTRY_INHERITED 0x80000000 #define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \ (ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \ @@ -502,8 +501,8 @@ __LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type * ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each * default ACL entry, as used in old Solaris ACLs. */ -#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 16384 -#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 32768 +#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024 +#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048 __LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *, int /* flags */); __LA_DECL const char *archive_entry_acl_text(struct archive_entry *, 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 5b630d7521af..29b4b6cb0869 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c @@ -411,116 +411,75 @@ setup_acls(struct archive_read_disk *a, { const char *accpath; acl_t acl; +#if HAVE_ACL_IS_TRIVIAL_NP int r; +#endif accpath = archive_entry_sourcepath(entry); if (accpath == NULL) accpath = archive_entry_pathname(entry); - if (*fd < 0 && a->tree != NULL) { - if (a->follow_symlinks || - archive_entry_filetype(entry) != AE_IFLNK) - *fd = a->open_on_current_dir(a->tree, - accpath, O_RDONLY | O_NONBLOCK); - if (*fd < 0) { - if (a->tree_enter_working_dir(a->tree) != 0) { - archive_set_error(&a->archive, errno, - "Couldn't access %s", accpath); - return (ARCHIVE_FAILED); - } - } - } - archive_entry_acl_clear(entry); - acl = NULL; - #ifdef ACL_TYPE_NFS4 /* Try NFS4 ACL first. */ -#if HAVE_ACL_GET_FD_NP if (*fd >= 0) - acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4); -#endif - if (acl == NULL) { + acl = acl_get_fd(*fd); #if HAVE_ACL_GET_LINK_NP - if (!a->follow_symlinks) - acl = acl_get_link_np(accpath, ACL_TYPE_NFS4); + else if (!a->follow_symlinks) + acl = acl_get_link_np(accpath, ACL_TYPE_NFS4); #else - if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) } - /* We can't get the ACL of a symlink, so we assume - it can't have one. */ - acl = NULL; - } + else if ((!a->follow_symlinks) + && (archive_entry_filetype(entry) == AE_IFLNK)) + /* We can't get the ACL of a symlink, so we assume it can't + have one. */ + acl = NULL; #endif - } - if (acl == NULL) + else acl = acl_get_file(accpath, ACL_TYPE_NFS4); - - if (acl != NULL) { #if HAVE_ACL_IS_TRIVIAL_NP - /* Ignore "trivial" ACLs that just mirror the file mode. */ - if (acl_is_trivial_np(acl, &r) == 0) { - if (r) { - acl_free(acl); - acl = NULL; - return (ARCHIVE_OK); - } - } -#endif - r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4); + /* Ignore "trivial" ACLs that just mirror the file mode. */ + acl_is_trivial_np(acl, &r); + if (r) { acl_free(acl); - return (r); + acl = NULL; + } +#endif + if (acl != NULL) { + translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4); + acl_free(acl); + return (ARCHIVE_OK); } #endif /* Retrieve access ACL from file. */ if (*fd >= 0) acl = acl_get_fd(*fd); - if (acl == NULL) { #if HAVE_ACL_GET_LINK_NP - if (!a->follow_symlinks) - acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); + else if (!a->follow_symlinks) + acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); #else - if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) { - /* We can't get the ACL of a symlink, so we assume it - can't have one. */ - acl = NULL; - } + else if ((!a->follow_symlinks) + && (archive_entry_filetype(entry) == AE_IFLNK)) + /* We can't get the ACL of a symlink, so we assume it can't + have one. */ + acl = NULL; #endif - } - if (acl == NULL) + else acl = acl_get_file(accpath, ACL_TYPE_ACCESS); - if (acl != NULL) { -#if HAVE_ACL_IS_TRIVIAL_NP - /* Ignore "trivial" ACLs that just mirror the file mode. */ - if (acl_is_trivial_np(acl, &r) == 0) { - if (r) { - acl_free(acl); - acl = NULL; - return (ARCHIVE_OK); - } - } -#endif - r = translate_acl(a, entry, acl, + translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); acl_free(acl); - acl = NULL; - if (r != 0) - return (r); } /* Only directories can have default ACLs. */ if (S_ISDIR(archive_entry_mode(entry))) { acl = acl_get_file(accpath, ACL_TYPE_DEFAULT); if (acl != NULL) { - r = translate_acl(a, entry, acl, + translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); acl_free(acl); - if (r != 0) - return (r); } } return (ARCHIVE_OK); @@ -576,23 +535,19 @@ translate_acl(struct archive_read_disk *a, #ifdef ACL_TYPE_NFS4 acl_entry_type_t acl_type; acl_flagset_t acl_flagset; - int brand; + int brand, r; #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; + int s, ae_id, ae_tag, ae_perm; const char *ae_name; #ifdef 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. - if (acl_get_brand_np(acl, &brand) != 0) { - archive_set_error(&a->archive, errno, - "Failed to read ACL brand"); - return (ARCHIVE_FAILED); - } + acl_get_brand_np(acl, &brand); switch (brand) { case ACL_BRAND_POSIX: switch (default_entry_acl_type) { @@ -600,43 +555,31 @@ translate_acl(struct archive_read_disk *a, case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: break; default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid ACL entry type for POSIX.1e ACL"); - return (ARCHIVE_FAILED); + // XXX set warning message? + return ARCHIVE_FAILED; } break; case ACL_BRAND_NFS4: if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "ACL brand mismatch"); - return (ARCHIVE_FAILED); + // XXX set warning message? + return ARCHIVE_FAILED; } break; default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid ACL brand"); - return (ARCHIVE_FAILED); + // XXX set warning message? + return ARCHIVE_FAILED; break; } #endif s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get ACL entry"); - return (ARCHIVE_FAILED); - } while (s == 1) { ae_id = -1; ae_name = NULL; ae_perm = 0; - if (acl_get_tag_type(acl_entry, &acl_tag) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL tag type"); - return (ARCHIVE_FAILED); - } + acl_get_tag_type(acl_entry, &acl_tag); switch (acl_tag) { case ACL_USER: ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry); @@ -676,12 +619,8 @@ translate_acl(struct archive_read_disk *a, // non-NFSv4 ACLs entry_acl_type = default_entry_acl_type; #ifdef ACL_TYPE_NFS4 - if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL type from an NFSv4 ACL entry"); - return (ARCHIVE_FAILED); - } + r = acl_get_entry_type_np(acl_entry, &acl_type); + if (r == 0) { switch (acl_type) { case ACL_ENTRY_TYPE_ALLOW: entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; @@ -695,64 +634,40 @@ translate_acl(struct archive_read_disk *a, case ACL_ENTRY_TYPE_ALARM: entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; break; - default: - archive_set_error(&a->archive, errno, - "Unknown NFSv4 ACL entry type: %d", acl_type); - return (ARCHIVE_FAILED); } + } - /* - * Libarchive stores "flag" (NFSv4 inheritance bits) - * in the ae_perm bitmap. - */ - if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get flagset from an NFSv4 ACL entry"); - return (ARCHIVE_FAILED); - } - 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) { - archive_set_error(&a->archive, errno, - "Failed to check flag in a NFSv4 ACL flagset"); - return (ARCHIVE_FAILED); - } else if (r) + /* + * Libarchive stores "flag" (NFSv4 inheritance bits) + * in the ae_perm bitmap. + */ + // XXX acl_get_flagset_np on FreeBSD returns EINVAL for + // non-NFSv4 ACLs + r = acl_get_flagset_np(acl_entry, &acl_flagset); + if (r == 0) { + for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) { + if (acl_get_flag_np(acl_flagset, + acl_inherit_map[i].platform_inherit)) ae_perm |= acl_inherit_map[i].archive_inherit; } } #endif - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL permission set"); - return (ARCHIVE_FAILED); - } + acl_get_permset(acl_entry, &acl_permset); for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) { /* * acl_get_perm() is spelled differently on different * platforms; see above. */ - r = ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to check permission in an ACL permission set"); - return (ARCHIVE_FAILED); - } else if (r) + if (ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm)) ae_perm |= acl_perm_map[i].archive_perm; } - r = archive_entry_acl_add_entry(entry, entry_acl_type, + archive_entry_acl_add_entry(entry, entry_acl_type, ae_perm, ae_tag, ae_id, ae_name); - if (r != 0) - return (r); s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get ACL entry"); - return (ARCHIVE_FAILED); - } } return (ARCHIVE_OK); } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_tar.c b/contrib/libarchive/libarchive/archive_read_support_format_tar.c index cde169715edc..9a44078b771a 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_tar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_tar.c @@ -203,10 +203,6 @@ static int archive_read_format_tar_read_header(struct archive_read *, static int checksum(struct archive_read *, const void *); static int pax_attribute(struct archive_read *, struct tar *, struct archive_entry *, const char *key, const char *value); -static int pax_attribute_acl(struct archive_read *, struct tar *, - struct archive_entry *, const char *, int); -static int pax_attribute_xattr(struct archive_entry *, const char *, - const char *); static int pax_header(struct archive_read *, struct tar *, struct archive_entry *, char *attr); static void pax_time(const char *, int64_t *sec, long *nanos); @@ -1132,15 +1128,8 @@ header_common(struct archive_read *a, struct tar *tar, if (tar->entry_bytes_remaining < 0) { tar->entry_bytes_remaining = 0; archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Tar entry has negative size"); - return (ARCHIVE_FATAL); - } - if (tar->entry_bytes_remaining == INT64_MAX) { - /* Note: tar_atol returns INT64_MAX on overflow */ - tar->entry_bytes_remaining = 0; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Tar entry size overflow"); - return (ARCHIVE_FATAL); + "Tar entry has negative size?"); + err = ARCHIVE_WARN; } tar->realsize = tar->entry_bytes_remaining; archive_entry_set_size(entry, tar->entry_bytes_remaining); @@ -1706,52 +1695,6 @@ pax_attribute_xattr(struct archive_entry *entry, return 0; } -static int -pax_attribute_acl(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const char *value, int type) -{ - int r; - const char* errstr; - - switch (type) { - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - errstr = "SCHILY.acl.access"; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - errstr = "SCHILY.acl.default"; - break; - case ARCHIVE_ENTRY_ACL_TYPE_NFS4: - errstr = "SCHILY.acl.ace"; - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Unknown ACL type: %d", type); - return(ARCHIVE_FATAL); - } - - if (tar->sconv_acl == NULL) { - tar->sconv_acl = - archive_string_conversion_from_charset( - &(a->archive), "UTF-8", 1); - if (tar->sconv_acl == NULL) - return (ARCHIVE_FATAL); - } - - r = archive_acl_parse_l(archive_entry_acl(entry), value, type, - tar->sconv_acl); - if (r != ARCHIVE_OK) { - if (r == ARCHIVE_FATAL) { - archive_set_error(&a->archive, ENOMEM, - "%s %s", "Can't allocate memory for ", - errstr); - return (r); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, "%s %s", "Parse error: ", errstr); - } - return (r); -} - /* * Parse a single key=value attribute. key/value pointers are * assumed to point into reasonably long-lived storage. @@ -1862,20 +1805,53 @@ pax_attribute(struct archive_read *a, struct tar *tar, case 'S': /* We support some keys used by the "star" archiver */ if (strcmp(key, "SCHILY.acl.access") == 0) { - r = pax_attribute_acl(a, tar, entry, value, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - if (r == ARCHIVE_FATAL) - return (r); + if (tar->sconv_acl == NULL) { + tar->sconv_acl = + archive_string_conversion_from_charset( + &(a->archive), "UTF-8", 1); + if (tar->sconv_acl == NULL) + return (ARCHIVE_FATAL); + } + + r = archive_acl_parse_l(archive_entry_acl(entry), + value, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, + tar->sconv_acl); + if (r != ARCHIVE_OK) { + err = r; + if (err == ARCHIVE_FATAL) { + archive_set_error(&a->archive, ENOMEM, + "Can't allocate memory for " + "SCHILY.acl.access"); + return (err); + } + archive_set_error(&a->archive, + ARCHIVE_ERRNO_MISC, + "Parse error: SCHILY.acl.access"); + } } else if (strcmp(key, "SCHILY.acl.default") == 0) { - r = pax_attribute_acl(a, tar, entry, value, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); - if (r == ARCHIVE_FATAL) - return (r); - } else if (strcmp(key, "SCHILY.acl.ace") == 0) { - r = pax_attribute_acl(a, tar, entry, value, - ARCHIVE_ENTRY_ACL_TYPE_NFS4); - if (r == ARCHIVE_FATAL) - return (r); + if (tar->sconv_acl == NULL) { + tar->sconv_acl = + archive_string_conversion_from_charset( + &(a->archive), "UTF-8", 1); + if (tar->sconv_acl == NULL) + return (ARCHIVE_FATAL); + } + + r = archive_acl_parse_l(archive_entry_acl(entry), + value, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, + tar->sconv_acl); + if (r != ARCHIVE_OK) { + err = r; + if (err == ARCHIVE_FATAL) { + archive_set_error(&a->archive, ENOMEM, + "Can't allocate memory for " + "SCHILY.acl.default"); + return (err); + } + archive_set_error(&a->archive, + ARCHIVE_ERRNO_MISC, + "Parse error: SCHILY.acl.default"); + } } else if (strcmp(key, "SCHILY.devmajor") == 0) { archive_entry_set_rdevmajor(entry, (dev_t)tar_atol10(value, strlen(value))); diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c index 2e5579f1fe73..2b025cbd12ad 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c @@ -418,30 +418,18 @@ zip_time(const char *p) * id1+size1+data1 + id2+size2+data2 ... * triplets. id and size are 2 bytes each. */ -static int -process_extra(struct archive_read *a, const char *p, size_t extra_length, struct zip_entry* zip_entry) +static void +process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry) { unsigned offset = 0; - if (extra_length == 0) { - return ARCHIVE_OK; - } - - if (extra_length < 4) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Too-small extra data: Need at least 4 bytes, but only found %d bytes", (int)extra_length); - return ARCHIVE_FAILED; - } - while (offset <= extra_length - 4) { + while (offset < extra_length - 4) { unsigned short headerid = archive_le16dec(p + offset); unsigned short datasize = archive_le16dec(p + offset + 2); offset += 4; if (offset + datasize > extra_length) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Extra data overflow: Need %d bytes but only found %d bytes", - (int)datasize, (int)(extra_length - offset)); - return ARCHIVE_FAILED; + break; } #ifdef DEBUG fprintf(stderr, "Header id 0x%04x, length %d\n", @@ -727,13 +715,13 @@ process_extra(struct archive_read *a, const char *p, size_t extra_length, struct } offset += datasize; } - if (offset != extra_length) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Malformed extra data: Consumed %d bytes of %d bytes", - (int)offset, (int)extra_length); - return ARCHIVE_FAILED; +#ifdef DEBUG + if (offset != extra_length) + { + fprintf(stderr, + "Extra data field contents do not match reported size!\n"); } - return ARCHIVE_OK; +#endif } /* @@ -852,9 +840,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry, return (ARCHIVE_FATAL); } - if (ARCHIVE_OK != process_extra(a, h, extra_length, zip_entry)) { - return ARCHIVE_FATAL; - } + process_extra(h, extra_length, zip_entry); __archive_read_consume(a, extra_length); /* Work around a bug in Info-Zip: When reading from a pipe, it @@ -1307,7 +1293,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff, && bytes_avail > zip->entry_bytes_remaining) { bytes_avail = (ssize_t)zip->entry_bytes_remaining; } - if (bytes_avail < 0) { + if (bytes_avail <= 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP file body"); return (ARCHIVE_FATAL); @@ -2705,9 +2691,7 @@ slurp_central_directory(struct archive_read *a, struct zip *zip) "Truncated ZIP file header"); return ARCHIVE_FATAL; } - if (ARCHIVE_OK != process_extra(a, p + filename_length, extra_length, zip_entry)) { - return ARCHIVE_FATAL; - } + process_extra(p + filename_length, extra_length, zip_entry); /* * Mac resource fork files are stored under the diff --git a/contrib/libarchive/libarchive/archive_write_disk_acl.c b/contrib/libarchive/libarchive/archive_write_disk_acl.c index a7b94ff7f403..54a96696f285 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_acl.c +++ b/contrib/libarchive/libarchive/archive_write_disk_acl.c @@ -138,7 +138,6 @@ set_acl(struct archive *a, int fd, const char *name, acl_permset_t acl_permset; #ifdef ACL_TYPE_NFS4 acl_flagset_t acl_flagset; - int r; #endif int ret; int ae_type, ae_permset, ae_tag, ae_id; @@ -146,25 +145,16 @@ set_acl(struct archive *a, int fd, const char *name, gid_t ae_gid; const char *ae_name; int entries; - int i; + int i, r; ret = ARCHIVE_OK; entries = archive_acl_reset(abstract_acl, ae_requested_type); if (entries == 0) return (ARCHIVE_OK); acl = acl_init(entries); - if (acl == (acl_t)NULL) { - archive_set_error(a, errno, - "Failed to initialize ACL working storage"); - return (ARCHIVE_FAILED); - } while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { - if (acl_create_entry(&acl, &acl_entry) != 0) { - archive_set_error(a, errno, - "Failed to create a new ACL entry"); - return (ARCHIVE_FAILED); - } + acl_create_entry(&acl, &acl_entry); switch (ae_tag) { case ARCHIVE_ENTRY_ACL_USER: @@ -195,84 +185,53 @@ set_acl(struct archive *a, int fd, const char *name, break; #endif default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unknown ACL tag: %d", ae_tag); - return (ARCHIVE_FAILED); + /* XXX */ + break; } #ifdef ACL_TYPE_NFS4 - r = 0; switch (ae_type) { case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW); + acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW); break; case ARCHIVE_ENTRY_ACL_TYPE_DENY: - r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY); + acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY); break; case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: - r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT); + acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT); break; case ARCHIVE_ENTRY_ACL_TYPE_ALARM: - r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM); + acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM); break; case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: // These don't translate directly into the system ACL. break; default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unknown ACL entry type: %d", ae_type); - return (ARCHIVE_FAILED); - } - if (r != 0) { - archive_set_error(a, errno, - "Failed to set ACL entry type"); - return (ARCHIVE_FAILED); + // XXX error handling here. + break; } #endif - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to get ACL permission set"); - return (ARCHIVE_FAILED); - } - if (acl_clear_perms(acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to clear ACL permissions"); - return (ARCHIVE_FAILED); - } + acl_get_permset(acl_entry, &acl_permset); + acl_clear_perms(acl_permset); 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 (acl_add_perm(acl_permset, - acl_perm_map[i].platform_perm) != 0) { - archive_set_error(a, errno, - "Failed to add ACL permission"); - return (ARCHIVE_FAILED); - } + acl_add_perm(acl_permset, + acl_perm_map[i].platform_perm); } #ifdef ACL_TYPE_NFS4 - if (acl_type == ACL_TYPE_NFS4) { - if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { - archive_set_error(a, errno, - "Failed to get flagset from an NFSv4 ACL entry"); - return (ARCHIVE_FAILED); - } - if (acl_clear_flags_np(acl_flagset) != 0) { - archive_set_error(a, errno, - "Failed to clear flags from an NFSv4 ACL flagset"); - return (ARCHIVE_FAILED); - } + // XXX acl_get_flagset_np on FreeBSD returns EINVAL for + // non-NFSv4 ACLs + r = acl_get_flagset_np(acl_entry, &acl_flagset); + if (r == 0) { + acl_clear_flags_np(acl_flagset); 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 (acl_add_flag_np(acl_flagset, - acl_inherit_map[i].platform_inherit) != 0) { - archive_set_error(a, errno, - "Failed to add flag to NFSv4 ACL flagset"); - return (ARCHIVE_FAILED); - } - } + if (ae_permset & acl_inherit_map[i].archive_inherit) + acl_add_flag_np(acl_flagset, + acl_inherit_map[i].platform_inherit); } } #endif diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c index 14acc2cd210d..a60d225f5c0e 100644 --- a/contrib/libarchive/libarchive/archive_write_disk_posix.c +++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c @@ -2401,18 +2401,8 @@ check_symlinks(struct archive_write_disk *a) r = lstat(a->name, &st); if (r != 0) { /* We've hit a dir that doesn't exist; stop now. */ - if (errno == ENOENT) { + if (errno == ENOENT) break; - } else { - /* Note: This effectively disables deep directory - * support when security checks are enabled. - * Otherwise, very long pathnames that trigger - * an error here could evade the sandbox. - * TODO: We could do better, but it would probably - * require merging the symlink checks with the - * deep-directory editing. */ - return (ARCHIVE_FAILED); - } } else if (S_ISLNK(st.st_mode)) { if (c == '\0') { /* diff --git a/contrib/libarchive/libarchive/archive_write_set_format_pax.c b/contrib/libarchive/libarchive/archive_write_set_format_pax.c index a06ff6c83014..1f3e5ad22d11 100644 --- a/contrib/libarchive/libarchive/archive_write_set_format_pax.c +++ b/contrib/libarchive/libarchive/archive_write_set_format_pax.c @@ -70,8 +70,6 @@ static void add_pax_attr_int(struct archive_string *, static void add_pax_attr_time(struct archive_string *, const char *key, int64_t sec, unsigned long nanos); -static int add_pax_acl(struct archive_write *, - struct archive_entry *, struct pax *, int); static ssize_t archive_write_pax_data(struct archive_write *, const void *, size_t); static int archive_write_pax_close(struct archive_write *); @@ -452,43 +450,6 @@ get_entry_symlink(struct archive_write *a, struct archive_entry *entry, return (ARCHIVE_OK); } -/* Add ACL to pax header */ -static int -add_pax_acl(struct archive_write *a, - struct archive_entry *entry, struct pax *pax, int flags) -{ - const char *p; - const char *attr; - int r; - - if (flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) - attr = "SCHILY.acl.access"; - else if (flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) - attr = "SCHILY.acl.default"; - else if (flags & ARCHIVE_ENTRY_ACL_TYPE_NFS4) - attr = "SCHILY.acl.ace"; - else - return(ARCHIVE_FATAL); - - r = archive_entry_acl_text_l(entry, flags, &p, NULL, - pax->sconv_utf8); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, "%s %s", - "Can't allocate memory for ", attr); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "%s %s %s", - "Can't translate ", attr, " to UTF-8"); - return(ARCHIVE_WARN); - } else if (p != NULL && *p != '\0') { - add_pax_attr(&(pax->pax_header), - attr, p); - } - return(ARCHIVE_OK); -} - /* * TODO: Consider adding 'comment' and 'charset' fields to * archive_entry so that clients can specify them. Also, consider @@ -505,7 +466,6 @@ archive_write_pax_header(struct archive_write *a, const char *p; const char *suffix; int need_extension, r, ret; - int acl_access, acl_default, acl_nfs4; int sparse_count; uint64_t sparse_total, real_size; struct pax *pax; @@ -1057,6 +1017,16 @@ archive_write_pax_header(struct archive_write *a, if (!need_extension && p != NULL && *p != '\0') need_extension = 1; + /* If there are non-trivial ACL entries, we need an extension. */ + if (!need_extension && archive_entry_acl_count(entry_original, + ARCHIVE_ENTRY_ACL_TYPE_ACCESS) > 0) + need_extension = 1; + + /* If there are non-trivial ACL entries, we need an extension. */ + if (!need_extension && archive_entry_acl_count(entry_original, + ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) > 0) + need_extension = 1; + /* If there are extended attributes, we need an extension */ if (!need_extension && archive_entry_xattr_count(entry_original) > 0) need_extension = 1; @@ -1065,17 +1035,6 @@ archive_write_pax_header(struct archive_write *a, if (!need_extension && sparse_count > 0) need_extension = 1; - acl_access = archive_entry_acl_count(entry_original, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - acl_default = archive_entry_acl_count(entry_original, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); - acl_nfs4 = archive_entry_acl_count(entry_original, - ARCHIVE_ENTRY_ACL_TYPE_NFS4); - - /* If there are any ACL entries, we need an extension */ - if (!need_extension && (acl_access + acl_default + acl_nfs4) > 0) - need_extension = 1; - /* * Libarchive used to include these in extended headers for * restricted pax format, but that confused people who @@ -1127,26 +1086,43 @@ archive_write_pax_header(struct archive_write *a, add_pax_attr(&(pax->pax_header), "SCHILY.fflags", p); /* I use star-compatible ACL attributes. */ - if (acl_access > 0) { - ret = add_pax_acl(a, entry_original, pax, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID); - if (ret == ARCHIVE_FATAL) + r = archive_entry_acl_text_l(entry_original, + ARCHIVE_ENTRY_ACL_TYPE_ACCESS | + ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, + &p, NULL, pax->sconv_utf8); + if (r != 0) { + if (errno == ENOMEM) { + archive_set_error(&a->archive, ENOMEM, + "Can't allocate memory for " + "ACL.access"); return (ARCHIVE_FATAL); + } + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, + "Can't translate ACL.access to UTF-8"); + ret = ARCHIVE_WARN; + } else if (p != NULL && *p != '\0') { + add_pax_attr(&(pax->pax_header), + "SCHILY.acl.access", p); } - if (acl_default > 0) { - ret = add_pax_acl(a, entry_original, pax, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT | - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID); - if (ret == ARCHIVE_FATAL) - return (ARCHIVE_FATAL); - } - if (acl_nfs4 > 0) { - ret = add_pax_acl(a, entry_original, pax, - ARCHIVE_ENTRY_ACL_TYPE_NFS4 | - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID); - if (ret == ARCHIVE_FATAL) + r = archive_entry_acl_text_l(entry_original, + ARCHIVE_ENTRY_ACL_TYPE_DEFAULT | + ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, + &p, NULL, pax->sconv_utf8); + if (r != 0) { + if (errno == ENOMEM) { + archive_set_error(&a->archive, ENOMEM, + "Can't allocate memory for " + "ACL.default"); return (ARCHIVE_FATAL); + } + archive_set_error(&a->archive, + ARCHIVE_ERRNO_FILE_FORMAT, + "Can't translate ACL.default to UTF-8"); + ret = ARCHIVE_WARN; + } else if (p != NULL && *p != '\0') { + add_pax_attr(&(pax->pax_header), + "SCHILY.acl.default", p); } /* We use GNU-tar-compatible sparse attributes. */ diff --git a/contrib/libarchive/tar/util.c b/contrib/libarchive/tar/util.c index f845600193a0..9d2aced7bd14 100644 --- a/contrib/libarchive/tar/util.c +++ b/contrib/libarchive/tar/util.c @@ -182,7 +182,7 @@ safe_fprintf(FILE *f, const char *fmt, ...) } /* If our output buffer is full, dump it and keep going. */ - if (i > (sizeof(outbuff) - 128)) { + if (i > (sizeof(outbuff) - 20)) { outbuff[i] = '\0'; fprintf(f, "%s", outbuff); i = 0;