Update vendor/libarchive to git to 379867ecb330b3a952fb7bfa7bffb7bbd5547205
Vendor changes: PR #771: Add NFSv4 ACL support to pax and restricted pax
This commit is contained in:
parent
cda329a1ca
commit
dc8e86c53b
@ -328,6 +328,7 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_acl_nfs4.c \
|
||||
libarchive/test/test_acl_pax.c \
|
||||
libarchive/test/test_acl_posix1e.c \
|
||||
libarchive/test/test_acl_text.c \
|
||||
libarchive/test/test_archive_api_feature.c \
|
||||
libarchive/test/test_archive_clear_error.c \
|
||||
libarchive/test/test_archive_cmdline.c \
|
||||
@ -376,7 +377,7 @@ libarchive_test_SOURCES= \
|
||||
libarchive/test/test_compat_plexus_archiver_tar.c \
|
||||
libarchive/test/test_compat_solaris_tar_acl.c \
|
||||
libarchive/test/test_compat_solaris_pax_sparse.c \
|
||||
libarchive/test/test_compat_star_acl_posix1e.c \
|
||||
libarchive/test/test_compat_star_acl.c \
|
||||
libarchive/test/test_compat_tar_hardlink.c \
|
||||
libarchive/test/test_compat_uudecode.c \
|
||||
libarchive/test/test_compat_uudecode_large.c \
|
||||
@ -598,7 +599,8 @@ libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/
|
||||
|
||||
libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/list.h \
|
||||
libarchive/test/test_acl_pax.tar.uu \
|
||||
libarchive/test/test_acl_pax_posix1e.tar.uu \
|
||||
libarchive/test/test_acl_pax_nfs4.tar.uu \
|
||||
libarchive/test/test_archive_string_conversion.txt.Z.uu \
|
||||
libarchive/test/test_compat_bzip2_1.tbz.uu \
|
||||
libarchive/test/test_compat_bzip2_2.tbz.uu \
|
||||
@ -635,6 +637,7 @@ libarchive_test_EXTRA_DIST=\
|
||||
libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu \
|
||||
libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu \
|
||||
libarchive/test/test_compat_solaris_tar_acl.tar.uu \
|
||||
libarchive/test/test_compat_star_acl_nfs4.tar.uu \
|
||||
libarchive/test/test_compat_star_acl_posix1e.tar.uu \
|
||||
libarchive/test/test_compat_tar_hardlink_1.tar.uu \
|
||||
libarchive/test/test_compat_uudecode_large.tar.Z.uu \
|
||||
|
3
NEWS
3
NEWS
@ -1,3 +1,6 @@
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -66,22 +66,17 @@ int archive_acl_add_entry_w_len(struct archive_acl *,
|
||||
int archive_acl_add_entry_len(struct archive_acl *,
|
||||
int, int, int, int, const char *, size_t);
|
||||
|
||||
const wchar_t *archive_acl_text_w(struct archive *, struct archive_acl *, int);
|
||||
int archive_acl_text_l(struct archive_acl *, int, const char **, size_t *,
|
||||
wchar_t *archive_acl_to_text_w(struct archive_acl *, ssize_t *, int,
|
||||
struct archive *);
|
||||
char *archive_acl_to_text_l(struct archive_acl *, ssize_t *, int,
|
||||
struct archive_string_conv *);
|
||||
|
||||
/*
|
||||
* Private ACL parser. This is private because it handles some
|
||||
* very weird formats that clients should not be messing with.
|
||||
* Clients should only deal with their platform-native formats.
|
||||
* Because of the need to support many formats cleanly, new arguments
|
||||
* are likely to get added on a regular basis. Clients who try to use
|
||||
* this interface are likely to be surprised when it changes.
|
||||
* ACL text parser.
|
||||
*/
|
||||
int archive_acl_parse_w(struct archive_acl *,
|
||||
const wchar_t *, int /* type */);
|
||||
int archive_acl_parse_l(struct archive_acl *,
|
||||
const char *, int /* type */,
|
||||
struct archive_string_conv *);
|
||||
int archive_acl_from_text_w(struct archive_acl *, const wchar_t * /* wtext */,
|
||||
int /* type */);
|
||||
int archive_acl_from_text_l(struct archive_acl *, const char * /* text */,
|
||||
int /* type */, struct archive_string_conv *);
|
||||
|
||||
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -1486,34 +1487,121 @@ archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a text version of the ACL. The flags parameter controls
|
||||
* Generate a text version of the ACL. The flags parameter controls
|
||||
* the style of the generated ACL.
|
||||
*/
|
||||
wchar_t *
|
||||
archive_entry_acl_to_text_w(struct archive_entry *entry, ssize_t *len,
|
||||
int flags)
|
||||
{
|
||||
return (archive_acl_to_text_w(&entry->acl, len, flags,
|
||||
entry->archive));
|
||||
}
|
||||
|
||||
char *
|
||||
archive_entry_acl_to_text(struct archive_entry *entry, ssize_t *len,
|
||||
int flags)
|
||||
{
|
||||
return (archive_acl_to_text_l(&entry->acl, len, flags, NULL));
|
||||
}
|
||||
|
||||
char *
|
||||
_archive_entry_acl_to_text_l(struct archive_entry *entry, ssize_t *len,
|
||||
int flags, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_acl_to_text_l(&entry->acl, len, flags, sc));
|
||||
}
|
||||
|
||||
/*
|
||||
* ACL text parser.
|
||||
*/
|
||||
int
|
||||
archive_entry_acl_from_text_w(struct archive_entry *entry,
|
||||
const wchar_t *wtext, int type)
|
||||
{
|
||||
return (archive_acl_from_text_w(&entry->acl, wtext, type));
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_acl_from_text(struct archive_entry *entry,
|
||||
const char *text, int type)
|
||||
{
|
||||
return (archive_acl_from_text_l(&entry->acl, text, type, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
_archive_entry_acl_from_text_l(struct archive_entry *entry, const char *text,
|
||||
int type, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_acl_from_text_l(&entry->acl, text, type, sc));
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
static int
|
||||
archive_entry_acl_text_compat(int *flags)
|
||||
{
|
||||
if ((*flags & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0)
|
||||
return (1);
|
||||
|
||||
/* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID */
|
||||
if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0)
|
||||
*flags |= ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID;
|
||||
|
||||
/* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT */
|
||||
if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0)
|
||||
*flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
|
||||
|
||||
*flags |= ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
const wchar_t *
|
||||
archive_entry_acl_text_w(struct archive_entry *entry, int flags)
|
||||
{
|
||||
const wchar_t *r;
|
||||
r = archive_acl_text_w(entry->archive, &entry->acl, flags);
|
||||
if (r == NULL && errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
return (r);
|
||||
if (entry->acl.acl_text_w != NULL) {
|
||||
free(entry->acl.acl_text_w);
|
||||
entry->acl.acl_text_w = NULL;
|
||||
}
|
||||
if (archive_entry_acl_text_compat(&flags) == 0)
|
||||
entry->acl.acl_text_w = archive_acl_to_text_w(&entry->acl,
|
||||
NULL, flags, entry->archive);
|
||||
return (entry->acl.acl_text_w);
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
const char *
|
||||
archive_entry_acl_text(struct archive_entry *entry, int flags)
|
||||
{
|
||||
const char *p;
|
||||
if (archive_acl_text_l(&entry->acl, flags, &p, NULL, NULL) != 0
|
||||
&& errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
return (p);
|
||||
if (entry->acl.acl_text != NULL) {
|
||||
free(entry->acl.acl_text);
|
||||
entry->acl.acl_text = NULL;
|
||||
}
|
||||
if (archive_entry_acl_text_compat(&flags) == 0)
|
||||
entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, NULL,
|
||||
flags, NULL);
|
||||
|
||||
return (entry->acl.acl_text);
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
int
|
||||
_archive_entry_acl_text_l(struct archive_entry *entry, int flags,
|
||||
const char **acl_text, size_t *len, struct archive_string_conv *sc)
|
||||
{
|
||||
return (archive_acl_text_l(&entry->acl, flags, acl_text, len, sc));
|
||||
if (entry->acl.acl_text != NULL) {
|
||||
free(entry->acl.acl_text);
|
||||
entry->acl.acl_text = NULL;
|
||||
}
|
||||
|
||||
if (archive_entry_acl_text_compat(&flags) == 0)
|
||||
entry->acl.acl_text = archive_acl_to_text_l(&entry->acl,
|
||||
(ssize_t *)len, flags, sc);
|
||||
|
||||
*acl_text = entry->acl.acl_text;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2008 Tim Kientzle
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -420,6 +421,7 @@ __LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const voi
|
||||
/*
|
||||
* Inheritance values (NFS4 ACLs only); included in permset.
|
||||
*/
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERITED 0x01000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
|
||||
#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
|
||||
@ -433,15 +435,16 @@ __LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const voi
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS)
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS \
|
||||
| ARCHIVE_ENTRY_ACL_ENTRY_INHERITED)
|
||||
|
||||
/* We need to be able to specify combinations of these. */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256 /* POSIX.1e only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512 /* POSIX.1e only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 1024 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_DENY 2048 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 4096 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 8192 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 0x00000100 /* POSIX.1e only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 0x00000200 /* POSIX.1e only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 0x00000400 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_DENY 0x00000800 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 0x00001000 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 0x00002000 /* NFS4 only */
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
|
||||
| ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
|
||||
#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
|
||||
@ -492,21 +495,43 @@ __LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type
|
||||
* Construct a text-format ACL. The flags argument is a bitmask that
|
||||
* can include any of the following:
|
||||
*
|
||||
* Flags only for archive entries with POSIX.1e ACL:
|
||||
* ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
|
||||
* ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
|
||||
* ARCHIVE_ENTRY_ACL_TYPE_NFS4 - Include NFS4 entries.
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
|
||||
* each ACL entry. ('star' introduced this for POSIX.1e, this flag
|
||||
* also applies to NFS4.)
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
|
||||
* default ACL entry, as used in old Solaris ACLs.
|
||||
* default ACL entry.
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_SOLARIS - Output only one colon after "other" and
|
||||
* "mask" entries.
|
||||
*
|
||||
* Flags for for archive entries with POSIX.1e ACL or NFSv4 ACL:
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
|
||||
* each ACL entry.
|
||||
* ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA - Separate entries with comma
|
||||
* instead of newline.
|
||||
*/
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 0x00000001
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 0x00000002
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_SOLARIS 0x00000004
|
||||
#define ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 0x00000008
|
||||
|
||||
__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *,
|
||||
ssize_t * /* len */, int /* flags */);
|
||||
__LA_DECL char *archive_entry_acl_to_text(struct archive_entry *,
|
||||
ssize_t * /* len */, int /* flags */);
|
||||
__LA_DECL int archive_entry_acl_from_text_w(struct archive_entry *,
|
||||
const wchar_t * /* wtext */, int /* type */);
|
||||
__LA_DECL int archive_entry_acl_from_text(struct archive_entry *,
|
||||
const char * /* text */, int /* type */);
|
||||
|
||||
/* Deprecated constants */
|
||||
#define OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
|
||||
#define OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
|
||||
|
||||
/* Deprecated functions */
|
||||
__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
|
||||
int /* flags */);
|
||||
int /* flags */) __attribute__ ((deprecated));
|
||||
__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
|
||||
int /* flags */);
|
||||
int /* flags */) __attribute__ ((deprecated));
|
||||
|
||||
/* Return bitmask of ACL types in an archive entry */
|
||||
__LA_DECL int archive_entry_acl_types(struct archive_entry *);
|
||||
|
@ -1,4 +1,5 @@
|
||||
.\" Copyright (c) 2010 Joerg Sonnenberger
|
||||
.\" Copyright (c) 2016 Martin Matuska
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -22,7 +23,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 2, 2012
|
||||
.Dd December 27, 2016
|
||||
.Dt ARCHIVE_ENTRY_ACL 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -30,10 +31,13 @@
|
||||
.Nm archive_entry_acl_add_entry_w ,
|
||||
.Nm archive_entry_acl_clear ,
|
||||
.Nm archive_entry_acl_count ,
|
||||
.Nm archive_entry_acl_from_text ,
|
||||
.Nm archive_entry_acl_from_text_w,
|
||||
.Nm archive_entry_acl_next ,
|
||||
.Nm archive_entry_acl_next_w ,
|
||||
.Nm archive_entry_acl_reset ,
|
||||
.Nm archive_entry_acl_text_w ,
|
||||
.Nm archive_entry_acl_to_text ,
|
||||
.Nm archive_entry_acl_to_text_w ,
|
||||
.Nm archive_entry_acl_types
|
||||
.Nd functions for manipulating Access Control Lists in archive entry descriptions
|
||||
.Sh LIBRARY
|
||||
@ -63,6 +67,18 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Ft int
|
||||
.Fn archive_entry_acl_count "struct archive_entry *a" "int type"
|
||||
.Ft int
|
||||
.Fo archive_entry_acl_from_text
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "const char *text"
|
||||
.Fa "int type"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_entry_acl_from_text_w
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "const wchar_t *text"
|
||||
.Fa "int type"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo archive_entry_acl_next
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "int type"
|
||||
@ -84,33 +100,48 @@ Streaming Archive Library (libarchive, -larchive)
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
|
||||
.Ft const wchar_t *
|
||||
.Fn archive_entry_acl_text_w "struct archive_entry *a" "int flags"
|
||||
.Ft char *
|
||||
.Fo archive_entry_acl_to_text
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "ssize_t *len_p"
|
||||
.Fa "int flags"
|
||||
.Fc
|
||||
.Ft wchar_t *
|
||||
.Fo archive_entry_acl_to_text_w
|
||||
.Fa "struct archive_entry *a"
|
||||
.Fa "ssize_t *len_p"
|
||||
.Fa "int flags"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn archive_entry_acl_types "struct archive_entry *a"
|
||||
.\" enum?
|
||||
.Sh DESCRIPTION
|
||||
An
|
||||
.Dq Access Control List
|
||||
is a generalisation of the classic Unix permission system.
|
||||
The
|
||||
.Dq Access Control Lists (ACLs)
|
||||
extend the standard Unix perssion model.
|
||||
The ACL interface of
|
||||
.Nm libarchive
|
||||
is derived from the POSIX.1e draft, but restricted to simplify dealing
|
||||
with practical implementations in various Operating Systems and archive formats.
|
||||
.Pp
|
||||
An ACL consists of a number of independent entries.
|
||||
supports both POSIX.1e and NFSv4 style ACLs. Use of ACLs is restricted by
|
||||
various levels of ACL support in operating systems, file systems and archive
|
||||
formats.
|
||||
.Ss POSIX.1e Access Control Lists
|
||||
A POSIX.1e ACL consists of a number of independent entries.
|
||||
Each entry specifies the permission set as bitmask of basic permissions.
|
||||
Valid permissions are:
|
||||
Valid permissions in the
|
||||
.Fa permset
|
||||
are:
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_EXECUTE"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_EXECUTE
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ ( Sy r )
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE ( Sy w )
|
||||
.It Dv ARCHIVE_ENTRY_ACL_EXECUTE ( Sy x )
|
||||
.El
|
||||
The permissions correspond to the normal Unix permissions.
|
||||
.Pp
|
||||
The tag specifies the principal to which the permission applies.
|
||||
The
|
||||
.Fa tag
|
||||
specifies the principal to which the permission applies.
|
||||
Valid values are:
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ"
|
||||
.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER
|
||||
The user specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
|
||||
@ -122,8 +153,9 @@ The group who owns the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_MASK
|
||||
The maximum permissions to be obtained via group permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_OTHER
|
||||
Any principal who doesn't have a user or group entry.
|
||||
Any principal who is not file owner or a member of the owning group.
|
||||
.El
|
||||
.Pp
|
||||
The principals
|
||||
.Dv ARCHIVE_ENTRY_ACL_USER_OBJ ,
|
||||
.Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
|
||||
@ -132,19 +164,123 @@ and
|
||||
are equivalent to user, group and other in the classic Unix permission
|
||||
model and specify non-extended ACL entries.
|
||||
.Pp
|
||||
All files have an access ACL
|
||||
All files with have an access ACL
|
||||
.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS .
|
||||
This specifies the permissions required for access to the file itself.
|
||||
Directories have an additional ACL
|
||||
.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT ,
|
||||
which controls the initial access ACL for newly created directory entries.
|
||||
.Ss NFSv4 Access Control Lists
|
||||
A NFSv4 ACL consists of multiple individual entries called Access Control
|
||||
Entries (ACEs).
|
||||
.Pp
|
||||
There are four possible types of a NFSv4 ACE:
|
||||
.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYE_ALLOW"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALLOW
|
||||
Allow principal to perform actions requiring given permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DENY
|
||||
Prevent principal from performing actions requiring given permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_AUDIT
|
||||
Log access attempts by principal which require given permissions.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALARM
|
||||
Trigger a system alarm on access attempts by principal which require given
|
||||
permissions.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fa tag
|
||||
specifies the principal to which the permission applies.
|
||||
Valid values are:
|
||||
.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER
|
||||
The user specified by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
|
||||
The owner of the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP
|
||||
The group specied by the name field.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
|
||||
The group who owns the file.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_EVERYONE
|
||||
Any principal who is not file owner or a member of the owning group.
|
||||
.El
|
||||
.Pp
|
||||
Entries with the
|
||||
.Dv ARCHIVE_ENTRY_ACL_USER
|
||||
or
|
||||
.Dv ARCHIVE_ENTRY_ACL_GROUP
|
||||
tag store the user and group name in the
|
||||
.Fa name
|
||||
string and optionally the user or group ID in the
|
||||
.Fa qualifier
|
||||
integer.
|
||||
.Pp
|
||||
NFSv4 ACE permissions and flags are stored in the same
|
||||
.Fa permset
|
||||
bitfield. Some permissions share the same constant and permission character but
|
||||
have different effect on directories than on files. The following ACE
|
||||
permissions are supported:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_DATA ( Sy r )
|
||||
Read data (file).
|
||||
.It Dv ARCHIVE_ENTRY_ACL_LIST_DIRECTORY ( Sy r )
|
||||
List entries (directory).
|
||||
.It ARCHIVE_ENTRY_ACL_WRITE_DATA ( Sy w )
|
||||
Write data (file).
|
||||
.It ARCHIVE_ENTRY_ACL_ADD_FILE ( Sy w )
|
||||
Create files (directory).
|
||||
.It Dv ARCHIVE_ENTRY_ACL_EXECUTE ( Sy x )
|
||||
Execute file or change into a directory.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_APPEND_DATA ( Sy p )
|
||||
Append data (file).
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY ( Sy p )
|
||||
Create subdirectories (directory).
|
||||
.It Dv ARCHIVE_ENTRY_ACL_DELETE_CHILD ( Sy D )
|
||||
Remove files and subdirectories inside a directory.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_DELETE ( Sy d )
|
||||
Remove file or directory.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES ( Sy a )
|
||||
Read file or directory attributes.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES ( Sy A )
|
||||
Write file or directory attributes.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS ( Sy R )
|
||||
Read named file or directory attributes.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS ( Sy W )
|
||||
Write named file or directory attributes.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_READ_ACL ( Sy c )
|
||||
Read file or directory ACL.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE_ACL ( Sy C )
|
||||
Write file or directory ACL.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_WRITE_OWNER ( Sy o )
|
||||
Change owner of a file or directory.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_SYNCHRONIZE ( Sy s )
|
||||
Use synchronous I/O.
|
||||
.El
|
||||
.Pp
|
||||
The following NFSv4 ACL inheritance flags are supported:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT ( Sy f )
|
||||
Inherit parent directory ACE to files.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT ( Sy d )
|
||||
Inherit parent directory ACE to subdirectories.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY ( Sy i )
|
||||
Only inherit, do not apply the permission on the directory itself.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n )
|
||||
Do not propagate inherit flags. Only first-level entries inherit ACLs.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S )
|
||||
Trigger alarm or audit on succesful access.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F )
|
||||
Trigger alarm or audit on failed access.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERITED ( Sy I )
|
||||
Mark that ACE was inherited.
|
||||
.El
|
||||
.Ss Functions
|
||||
.Fn archive_entry_acl_add_entry
|
||||
and
|
||||
.Fn archive_entry_acl_add_entry_w
|
||||
add a single ACL entry.
|
||||
For the access ACL and non-extended principals, the classic Unix permissions
|
||||
are updated.
|
||||
are updated. An archive enry cannot contain both POSIX.1e and NFSv4 ACL
|
||||
entries.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_clear
|
||||
removes all ACL entries and resets the enumeration pointer.
|
||||
@ -153,14 +289,58 @@ removes all ACL entries and resets the enumeration pointer.
|
||||
counts the ACL entries that have the given type mask.
|
||||
.Fa type
|
||||
can be the bitwise-or of
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
and
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT .
|
||||
If
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_DEFAULT"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
.El
|
||||
for POSIX.1e ACLs and
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_ALLOW"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALLOW
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DENY
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_AUDIT
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALARM
|
||||
.El
|
||||
for NFSv4 ACLs. For POSIX.1e ACLs if
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
is included and at least one extended ACL entry is found,
|
||||
the three non-extened ACLs are added.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_from_text
|
||||
and
|
||||
.Fn archive_entry_acl_from_text_w
|
||||
add new
|
||||
.Pq or merge with existing
|
||||
ACL entries from
|
||||
.Pq wide
|
||||
text. The argument
|
||||
.Fa type
|
||||
may take one of the following values:
|
||||
.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_DEFAULT"
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_NFS4
|
||||
.El
|
||||
Supports all formats that can be created with
|
||||
.Fn archive_entry_acl_to_text
|
||||
or respective
|
||||
.Fn archive_entry_acl_to_text_w .
|
||||
Existing ACL entries are preserved. To get a clean new ACL from text
|
||||
.Fn archive_entry_acl_clear
|
||||
must be called first. Entries prefixed with
|
||||
.Dq default:
|
||||
are treated as
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
unless
|
||||
.Fa type
|
||||
is
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_NFS4 .
|
||||
Invalid entries, non-parseable ACL entries and entries beginning with
|
||||
the
|
||||
.Sq #
|
||||
character
|
||||
.Pq comments
|
||||
are skipped.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_next
|
||||
and
|
||||
.Fn archive_entry_acl_next_w
|
||||
@ -182,19 +362,50 @@ or set using
|
||||
Otherwise, the function returns the same value as
|
||||
.Fn archive_entry_acl_count .
|
||||
.Pp
|
||||
.Fn archive_entry_acl_text_w
|
||||
converts the ACL entries for the given type mask into a wide string.
|
||||
In addition to the normal type flags,
|
||||
.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
|
||||
.Fn archive_entry_acl_to_text
|
||||
and
|
||||
.Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
|
||||
can be specified to further customize the result.
|
||||
The returned long string is valid until the next call to
|
||||
.Fn archive_entry_acl_clear ,
|
||||
.Fn archive_entry_acl_add_entry ,
|
||||
.Fn archive_entry_acl_add_entry_w
|
||||
.Fn archive_entry_acl_to_text_w
|
||||
convert the ACL entries for the given type into a
|
||||
.Pq wide
|
||||
string of ACL entries separated by newline. If the the pointer
|
||||
.Fa len_p
|
||||
is not NULL, then the function shall return the length of the string
|
||||
.Pq not including the NULL terminator
|
||||
in the location pointed to by
|
||||
.Fa len_p .
|
||||
The
|
||||
.Fa flag
|
||||
argument is a bitwise-or.
|
||||
.Pp
|
||||
The following flags are effective only on POSIX.1e ACL:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
Output access ACLs.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
Output POSIX.1e default ACLs.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
|
||||
Prefix each default ACL entry with the word
|
||||
.Dq default: .
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_SOLARIS
|
||||
The mask and other ACLs don not contain a double colon.
|
||||
.El
|
||||
.Pp
|
||||
The following flags are effective on both POSIX.1e and NFSv4 ACL:
|
||||
.Bl -tag -offset indent -compact -width ARCHIV
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
|
||||
Add an additional colon-separated field containing the user or group id.
|
||||
.It Dv ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA
|
||||
Separate ACL entries with comma instead of newline.
|
||||
.El
|
||||
.Pp
|
||||
If the archive entry contains NFSv4 ACLs, all types of NFSv4 ACLs are returned.
|
||||
It the entry contains POSIX.1e ACLs and none of the flags
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
or
|
||||
.Fn archive_entry_acl_text_w .
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
|
||||
are specified, both access and default entries are returned and default entries
|
||||
are prefixed with
|
||||
.Dq default: .
|
||||
.Pp
|
||||
.Fn archive_entry_acl_types
|
||||
get ACL entry types contained in an archive entry's ACL. As POSIX.1e and NFSv4
|
||||
@ -205,11 +416,20 @@ an ACL already contains POSIX.1e or NFSv4 ACL entries.
|
||||
and
|
||||
.Fn archive_entry_acl_reset
|
||||
returns the number of ACL entries that match the given type mask.
|
||||
If the type mask includes
|
||||
For POSIX.1e ACLS if the type mask includes
|
||||
.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
and at least one extended ACL entry exists, the three classic Unix
|
||||
permissions are counted.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_from_text
|
||||
and
|
||||
.Fn archive_entry_acl_from_text_w
|
||||
return
|
||||
.Dv ARCHIVE_OK
|
||||
if all entries were successfully parsed and
|
||||
.Dv ARCHIVE_WARN
|
||||
if one or more entries were invalid or non-parseable.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_next
|
||||
and
|
||||
.Fn archive_entry_acl_next_w
|
||||
@ -224,23 +444,16 @@ if
|
||||
.Fn archive_entry_acl_reset
|
||||
has not been called first.
|
||||
.Pp
|
||||
.Fn archive_entry_text_w
|
||||
returns a wide string representation of the ACL entrise matching the
|
||||
given type mask.
|
||||
The returned long string is valid until the next call to
|
||||
.Fn archive_entry_acl_clear ,
|
||||
.Fn archive_entry_acl_add_entry ,
|
||||
.Fn archive_entry_acl_add_entry_w
|
||||
or
|
||||
.Fn archive_entry_acl_text_w .
|
||||
.Fn archive_entry_acl_to_text
|
||||
returns a string representing the ACL entries matching the given type and
|
||||
flags on success or NULL on error.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_to_text_w
|
||||
returns a wide string representing the ACL entries matching the given type
|
||||
and flags on success or NULL on error.
|
||||
.Pp
|
||||
.Fn archive_entry_acl_types
|
||||
returns a bitmask of ACL entry types or 0 if archive entry has no ACL entries.
|
||||
.Sh SEE ALSO
|
||||
.Xr archive_entry 3
|
||||
.Xr libarchive 3 ,
|
||||
.Sh BUGS
|
||||
.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
|
||||
and
|
||||
.Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
|
||||
are not documented.
|
||||
.Xr archive_entry 3 ,
|
||||
.Xr libarchive 3
|
||||
|
@ -63,9 +63,14 @@ int _archive_entry_uname_l(struct archive_entry *,
|
||||
const char **, size_t *, struct archive_string_conv *);
|
||||
#define archive_entry_acl_text_l _archive_entry_acl_text_l
|
||||
int _archive_entry_acl_text_l(struct archive_entry *, int,
|
||||
const char **, size_t *, struct archive_string_conv *);
|
||||
|
||||
|
||||
const char **, size_t *, struct archive_string_conv *)
|
||||
__attribute__ ((deprecated));
|
||||
#define archive_entry_acl_to_text_l _archive_entry_acl_to_text_l
|
||||
char *_archive_entry_acl_to_text_l(struct archive_entry *, ssize_t *, int,
|
||||
struct archive_string_conv *);
|
||||
#define archive_entry_acl_from_text_l _archive_entry_acl_from_text_l
|
||||
int _archive_entry_acl_from_text_l(struct archive_entry *, const char* text,
|
||||
int type, struct archive_string_conv *);
|
||||
#define archive_entry_copy_gname_l _archive_entry_copy_gname_l
|
||||
int _archive_entry_copy_gname_l(struct archive_entry *,
|
||||
const char *, size_t, struct archive_string_conv *);
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -440,7 +441,7 @@ setup_acls(struct archive_read_disk *a,
|
||||
acl = NULL;
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
/* Try NFS4 ACL first. */
|
||||
/* Try NFSv4 ACL first. */
|
||||
if (*fd >= 0)
|
||||
#if HAVE_ACL_GET_FD_NP
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -204,6 +205,10 @@ 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);
|
||||
@ -1016,7 +1021,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
archive_strncpy(&(tar->localname), acl, p - acl);
|
||||
err = archive_acl_parse_l(archive_entry_acl(entry),
|
||||
err = archive_acl_from_text_l(archive_entry_acl(entry),
|
||||
tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, tar->sconv_acl);
|
||||
if (err != ARCHIVE_OK) {
|
||||
if (errno == ENOMEM) {
|
||||
@ -1758,6 +1763,52 @@ 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_from_text_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.
|
||||
@ -1874,53 +1925,20 @@ 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) {
|
||||
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");
|
||||
}
|
||||
r = pax_attribute_acl(a, tar, entry, value,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
if (r == ARCHIVE_FATAL)
|
||||
return (r);
|
||||
} else if (strcmp(key, "SCHILY.acl.default") == 0) {
|
||||
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");
|
||||
}
|
||||
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);
|
||||
} else if (strcmp(key, "SCHILY.devmajor") == 0) {
|
||||
archive_entry_set_rdevmajor(entry,
|
||||
(dev_t)tar_atol10(value, strlen(value)));
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -70,6 +71,8 @@ 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 *);
|
||||
@ -449,6 +452,45 @@ 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)
|
||||
{
|
||||
char *p;
|
||||
const char *attr;
|
||||
int acl_types;
|
||||
|
||||
acl_types = archive_entry_acl_types(entry);
|
||||
|
||||
if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0)
|
||||
attr = "SCHILY.acl.ace";
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
|
||||
attr = "SCHILY.acl.access";
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
||||
attr = "SCHILY.acl.default";
|
||||
else
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
p = archive_entry_acl_to_text_l(entry, NULL, flags, pax->sconv_utf8);
|
||||
if (p == NULL) {
|
||||
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 != '\0') {
|
||||
add_pax_attr(&(pax->pax_header),
|
||||
attr, p);
|
||||
free(p);
|
||||
}
|
||||
return(ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Consider adding 'comment' and 'charset' fields to
|
||||
* archive_entry so that clients can specify them. Also, consider
|
||||
@ -465,6 +507,7 @@ archive_write_pax_header(struct archive_write *a,
|
||||
const char *p;
|
||||
const char *suffix;
|
||||
int need_extension, r, ret;
|
||||
int acl_types;
|
||||
int sparse_count;
|
||||
uint64_t sparse_total, real_size;
|
||||
struct pax *pax;
|
||||
@ -1016,16 +1059,6 @@ 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;
|
||||
@ -1034,6 +1067,12 @@ archive_write_pax_header(struct archive_write *a,
|
||||
if (!need_extension && sparse_count > 0)
|
||||
need_extension = 1;
|
||||
|
||||
acl_types = archive_entry_acl_types(entry_original);
|
||||
|
||||
/* If there are any ACL entries, we need an extension */
|
||||
if (!need_extension && acl_types != 0)
|
||||
need_extension = 1;
|
||||
|
||||
/*
|
||||
* Libarchive used to include these in extended headers for
|
||||
* restricted pax format, but that confused people who
|
||||
@ -1085,43 +1124,28 @@ archive_write_pax_header(struct archive_write *a,
|
||||
add_pax_attr(&(pax->pax_header), "SCHILY.fflags", p);
|
||||
|
||||
/* I use star-compatible ACL attributes. */
|
||||
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");
|
||||
if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = add_pax_acl(a, entry_original, pax,
|
||||
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
|
||||
if (ret == ARCHIVE_FATAL)
|
||||
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);
|
||||
}
|
||||
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");
|
||||
if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
||||
ret = add_pax_acl(a, entry_original, pax,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
|
||||
if (ret == ARCHIVE_FATAL)
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) {
|
||||
ret = add_pax_acl(a, entry_original, pax,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
|
||||
if (ret == ARCHIVE_FATAL)
|
||||
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. */
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 18, 2012
|
||||
.Dd December 27, 2016
|
||||
.Dt LIBARCHIVE-FORMATS 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -191,8 +191,6 @@ and device numbers.
|
||||
.It Solaris extensions
|
||||
Libarchive recognizes ACL and extended attribute records written
|
||||
by Solaris tar.
|
||||
Currently, libarchive only has support for old-style ACLs; the
|
||||
newer NFSv4 ACLs are recognized but discarded.
|
||||
.El
|
||||
.Pp
|
||||
The first tar program appeared in Seventh Edition Unix in 1979.
|
||||
|
@ -1,4 +1,5 @@
|
||||
.\" Copyright (c) 2003-2009 Tim Kientzle
|
||||
.\" Copyright (c) 2016 Martin Matuska
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -24,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 23, 2011
|
||||
.Dd December 27, 2016
|
||||
.Dt TAR 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -440,11 +441,11 @@ archives to store files much larger than the historic 8GB limit.
|
||||
Vendor-specific attributes used by Joerg Schilling's
|
||||
.Nm star
|
||||
implementation.
|
||||
.It Cm SCHILY.acl.access , Cm SCHILY.acl.default
|
||||
Stores the access and default ACLs as textual strings in a format
|
||||
.It Cm SCHILY.acl.access , Cm SCHILY.acl.default, .Cm SCHILY.acl.ace
|
||||
Stores the access, default and NFSv4 ACLs as textual strings in a format
|
||||
that is an extension of the format specified by POSIX.1e draft 17.
|
||||
In particular, each user or group access specification can include a fourth
|
||||
colon-separated field with the numeric UID or GID.
|
||||
In particular, each user or group access specification can include
|
||||
an additional colon-separated field with the numeric UID or GID.
|
||||
This allows ACLs to be restored on systems that may not have complete
|
||||
user or group information available (such as when NIS/YP or LDAP services
|
||||
are temporarily unavailable).
|
||||
|
@ -14,6 +14,7 @@ IF(ENABLE_TEST)
|
||||
test_acl_nfs4.c
|
||||
test_acl_pax.c
|
||||
test_acl_posix1e.c
|
||||
test_acl_text.c
|
||||
test_archive_api_feature.c
|
||||
test_archive_clear_error.c
|
||||
test_archive_cmdline.c
|
||||
@ -62,7 +63,7 @@ IF(ENABLE_TEST)
|
||||
test_compat_plexus_archiver_tar.c
|
||||
test_compat_solaris_pax_sparse.c
|
||||
test_compat_solaris_tar_acl.c
|
||||
test_compat_star_acl_posix1e.c
|
||||
test_compat_star_acl.c
|
||||
test_compat_tar_hardlink.c
|
||||
test_compat_uudecode.c
|
||||
test_compat_uudecode_large.c
|
||||
|
@ -2421,6 +2421,132 @@ extract_reference_files(const char **names)
|
||||
extract_reference_file(*names++);
|
||||
}
|
||||
|
||||
/* Set ACLs */
|
||||
void
|
||||
archive_test_set_acls(struct archive_entry *ae,
|
||||
struct archive_test_acl_t *acls, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
archive_entry_acl_clear(ae);
|
||||
for (i = 0; i < n; i++) {
|
||||
failure("type=%#010x, permset=%#010x, tag=%d, qual=%d name=%s",
|
||||
acls[i].type, acls[i].permset, acls[i].tag,
|
||||
acls[i].qual, acls[i].name);
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_add_entry(ae,
|
||||
acls[i].type, acls[i].permset, acls[i].tag,
|
||||
acls[i].qual, acls[i].name));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
archive_test_acl_match(struct archive_test_acl_t *acl, int type, int permset,
|
||||
int tag, int qual, const char *name)
|
||||
{
|
||||
if (type != acl->type)
|
||||
return (0);
|
||||
if (permset != acl->permset)
|
||||
return (0);
|
||||
if (tag != acl->tag)
|
||||
return (0);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_OTHER)
|
||||
return (1);
|
||||
if (qual != acl->qual)
|
||||
return (0);
|
||||
if (name == NULL) {
|
||||
if (acl->name == NULL || acl->name[0] == '\0')
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
if (acl->name == NULL) {
|
||||
if (name[0] == '\0')
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
return (0 == strcmp(name, acl->name));
|
||||
}
|
||||
|
||||
/* Compare ACLs */
|
||||
void
|
||||
archive_test_compare_acls(struct archive_entry *ae,
|
||||
struct archive_test_acl_t *acls, int cnt, int want_type, int mode)
|
||||
{
|
||||
int *marker;
|
||||
int i, r, n;
|
||||
int type, permset, tag, qual;
|
||||
int matched;
|
||||
const char *name;
|
||||
|
||||
n = 0;
|
||||
marker = malloc(sizeof(marker[0]) * cnt);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
if ((acls[i].type & want_type) != 0) {
|
||||
marker[n] = i;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
failure("No ACL's to compare, type mask: %d", want_type);
|
||||
assert(n > 0);
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
while (0 == (r = archive_entry_acl_next(ae, want_type,
|
||||
&type, &permset, &tag, &qual, &name))) {
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
if (archive_test_acl_match(&acls[marker[i]], type,
|
||||
permset, tag, qual, name)) {
|
||||
/* We found a match; remove it. */
|
||||
marker[i] = marker[n - 1];
|
||||
n--;
|
||||
matched = 1;
|
||||
}
|
||||
}
|
||||
if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
&& tag == ARCHIVE_ENTRY_ACL_USER_OBJ) {
|
||||
if (!matched) printf("No match for user_obj perm\n");
|
||||
failure("USER_OBJ permset (%02o) != user mode (%02o)",
|
||||
permset, 07 & (mode >> 6));
|
||||
assert((permset << 6) == (mode & 0700));
|
||||
} else if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
&& tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ) {
|
||||
if (!matched) printf("No match for group_obj perm\n");
|
||||
failure("GROUP_OBJ permset %02o != group mode %02o",
|
||||
permset, 07 & (mode >> 3));
|
||||
assert((permset << 3) == (mode & 0070));
|
||||
} else if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
|
||||
&& tag == ARCHIVE_ENTRY_ACL_OTHER) {
|
||||
if (!matched) printf("No match for other perm\n");
|
||||
failure("OTHER permset (%02o) != other mode (%02o)",
|
||||
permset, mode & 07);
|
||||
assert((permset << 0) == (mode & 0007));
|
||||
} else {
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%#010x,permset=%#010x,tag=%d,qual=%d,"
|
||||
"name=``%s'')", type, permset, tag, qual, name);
|
||||
assert(matched == 1);
|
||||
}
|
||||
}
|
||||
assertEqualInt(ARCHIVE_EOF, r);
|
||||
if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
|
||||
assert((mode_t)(mode & 0777) == (archive_entry_mode(ae)
|
||||
& 0777));
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s'')",
|
||||
acls[marker[0]].type, acls[marker[0]].permset,
|
||||
acls[marker[0]].tag, acls[marker[0]].qual, acls[marker[0]].name);
|
||||
assert(n == 0); /* Number of ACLs not matched should == 0 */
|
||||
free(marker);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* TEST management
|
||||
|
@ -346,6 +346,23 @@ extern const char *testworkdir;
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
|
||||
/* ACL structure */
|
||||
struct archive_test_acl_t {
|
||||
int type; /* Type of ACL */
|
||||
int permset; /* Permissions for this class of users. */
|
||||
int tag; /* Owner, User, Owning group, group, other, etc. */
|
||||
int qual; /* GID or UID of user/group, depending on tag. */
|
||||
const char *name; /* Name of user/group, depending on tag. */
|
||||
};
|
||||
|
||||
/* Set ACLs */
|
||||
void archive_test_set_acls(struct archive_entry *, struct archive_test_acl_t *,
|
||||
int);
|
||||
|
||||
/* Compare ACLs */
|
||||
void archive_test_compare_acls(struct archive_entry *,
|
||||
struct archive_test_acl_t *, int, int, int);
|
||||
|
||||
/* Special customized read-from-memory interface. */
|
||||
int read_open_memory(struct archive *, const void *, size_t, size_t);
|
||||
/* _minimal version exercises a slightly different set of libarchive APIs. */
|
||||
|
@ -334,7 +334,7 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
|
||||
/* Dump entries in the myacls array that weren't in the system acl. */
|
||||
for (i = 0; i < n; ++i) {
|
||||
failure(" ACL entry %d missing from %s: "
|
||||
"type=%d,permset=%x,tag=%d,qual=%d,name=``%s''\n",
|
||||
"type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n",
|
||||
marker[i], filename,
|
||||
myacls[marker[i]].type, myacls[marker[i]].permset,
|
||||
myacls[marker[i]].tag, myacls[marker[i]].qual,
|
||||
@ -386,7 +386,7 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
|
||||
}
|
||||
|
||||
failure("ACL entry on file that shouldn't be there: "
|
||||
"type=%d,permset=%x,tag=%d,qual=%d",
|
||||
"type=%#010x,permset=%#010x,tag=%d,qual=%d",
|
||||
type,permset,tag,qual);
|
||||
assert(matched == 1);
|
||||
}
|
||||
@ -394,7 +394,7 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
|
||||
/* Dump entries in the myacls array that weren't in the system acl. */
|
||||
for (i = 0; i < n; ++i) {
|
||||
failure(" ACL entry %d missing from %s: "
|
||||
"type=%d,permset=%x,tag=%d,qual=%d,name=``%s''\n",
|
||||
"type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n",
|
||||
marker[i], filename,
|
||||
myacls[marker[i]].type, myacls[marker[i]].permset,
|
||||
myacls[marker[i]].tag, myacls[marker[i]].qual,
|
||||
|
@ -28,15 +28,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-0
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ > 4
|
||||
#include <sys/acl.h>
|
||||
|
||||
struct myacl_t {
|
||||
int type; /* Type of ACL: "access" or "default" */
|
||||
int permset; /* Permissions for this class of users. */
|
||||
int tag; /* Owner, User, Owning group, group, other, etc. */
|
||||
int qual; /* GID or UID of user/group, depending on tag. */
|
||||
const char *name; /* Name of user/group, depending on tag. */
|
||||
};
|
||||
|
||||
static struct myacl_t acls2[] = {
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -53,22 +45,8 @@ static struct myacl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, "" },
|
||||
{ 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
set_acls(struct archive_entry *ae, struct myacl_t *acls)
|
||||
{
|
||||
int i;
|
||||
|
||||
archive_entry_acl_clear(ae);
|
||||
for (i = 0; acls[i].name != NULL; i++) {
|
||||
archive_entry_acl_add_entry(ae,
|
||||
acls[i].type, acls[i].permset, acls[i].tag, acls[i].qual,
|
||||
acls[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
acl_entry_get_perm(acl_entry_t aclent) {
|
||||
int permset = 0;
|
||||
@ -127,7 +105,7 @@ acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_ta
|
||||
#endif
|
||||
|
||||
static int
|
||||
acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
|
||||
{
|
||||
gid_t g, *gp;
|
||||
uid_t u, *up;
|
||||
@ -173,25 +151,20 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
}
|
||||
|
||||
static void
|
||||
compare_acls(acl_t acl, struct myacl_t *myacls)
|
||||
compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
{
|
||||
int *marker;
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
int matched;
|
||||
int i, n;
|
||||
int i;
|
||||
acl_entry_t acl_entry;
|
||||
|
||||
/* Count ACL entries in myacls array and allocate an indirect array. */
|
||||
for (n = 0; myacls[n].name != NULL; ++n)
|
||||
continue;
|
||||
if (n) {
|
||||
marker = malloc(sizeof(marker[0]) * n);
|
||||
if (marker == NULL)
|
||||
return;
|
||||
for (i = 0; i < n; i++)
|
||||
marker[i] = i;
|
||||
} else
|
||||
marker = NULL;
|
||||
marker = malloc(sizeof(marker[0]) * n);
|
||||
if (marker == NULL)
|
||||
return;
|
||||
for (i = 0; i < n; i++)
|
||||
marker[i] = i;
|
||||
|
||||
/*
|
||||
* Iterate over acls in system acl object, try to match each
|
||||
@ -219,7 +192,7 @@ compare_acls(acl_t acl, struct myacl_t *myacls)
|
||||
/* Dump entries in the myacls array that weren't in the system acl. */
|
||||
for (i = 0; i < n; ++i) {
|
||||
failure(" ACL entry missing from file: "
|
||||
"type=%d,permset=%d,tag=%d,qual=%d,name=``%s''\n",
|
||||
"type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n",
|
||||
myacls[marker[i]].type, myacls[marker[i]].permset,
|
||||
myacls[marker[i]].tag, myacls[marker[i]].qual,
|
||||
myacls[marker[i]].name);
|
||||
@ -291,7 +264,7 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
|
||||
archive_entry_set_pathname(ae, "test0");
|
||||
archive_entry_set_mtime(ae, 123456, 7890);
|
||||
archive_entry_set_size(ae, 0);
|
||||
set_acls(ae, acls2);
|
||||
archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
||||
archive_entry_free(ae);
|
||||
|
||||
@ -304,7 +277,7 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
acl = acl_get_file("test0", ACL_TYPE_ACCESS);
|
||||
assert(acl != (acl_t)NULL);
|
||||
compare_acls(acl, acls2);
|
||||
compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
acl_free(acl);
|
||||
#endif
|
||||
}
|
||||
@ -332,7 +305,12 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
*/
|
||||
|
||||
/* Create a test file f1 with acl1 */
|
||||
acl1_text = "user::rwx,group::rwx,other::rwx,user:1:rw-,group:15:r-x,mask::rwx";
|
||||
acl1_text = "user::rwx\n"
|
||||
"group::rwx\n"
|
||||
"other::rwx\n"
|
||||
"user:1:rw-\n"
|
||||
"group:15:r-x\n"
|
||||
"mask::rwx";
|
||||
acl1 = acl_from_text(acl1_text);
|
||||
assert((void *)acl1 != NULL);
|
||||
fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
@ -371,7 +349,12 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
* to read ACLs, resulting in reading the ACL from a like-named
|
||||
* file in the wrong directory.
|
||||
*/
|
||||
acl2_text = "user::rwx,group::rwx,other::---,user:1:r--,group:15:r--,mask::rwx";
|
||||
acl2_text = "user::rwx\n"
|
||||
"group::rwx\n"
|
||||
"other::---\n"
|
||||
"user:1:r--\n"
|
||||
"group:15:r--\n"
|
||||
"mask::rwx";
|
||||
acl2 = acl_from_text(acl2_text);
|
||||
assert((void *)acl2 != NULL);
|
||||
fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
@ -406,10 +389,10 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
while (ARCHIVE_OK == archive_read_next_header2(a, ae)) {
|
||||
archive_read_disk_descend(a);
|
||||
if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
|
||||
assertEqualString(archive_entry_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl1_text);
|
||||
assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl1_text);
|
||||
|
||||
} else if (strcmp(archive_entry_pathname(ae), "./d/f1") == 0) {
|
||||
assertEqualString(archive_entry_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl2_text);
|
||||
assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl2_text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,15 +33,7 @@ __FBSDID("$FreeBSD$");
|
||||
* filesystems support ACLs or not.
|
||||
*/
|
||||
|
||||
struct acl_t {
|
||||
int type; /* Type of entry: "allow" or "deny" */
|
||||
int permset; /* Permissions for this class of users. */
|
||||
int tag; /* Owner, User, Owning group, group, everyone, etc. */
|
||||
int qual; /* GID or UID of user/group, depending on tag. */
|
||||
const char *name; /* Name of user/group, depending on tag. */
|
||||
};
|
||||
|
||||
static struct acl_t acls1[] = {
|
||||
static struct archive_test_acl_t acls1[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_READ_DATA,
|
||||
@ -52,7 +44,7 @@ static struct acl_t acls1[] = {
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
|
||||
};
|
||||
|
||||
static struct acl_t acls2[] = {
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
/* An entry for each type. */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0,
|
||||
ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
|
||||
@ -136,7 +128,7 @@ static struct acl_t acls2[] = {
|
||||
* Entries that should be rejected when we attempt to set them
|
||||
* on an ACL that already has NFS4 entries.
|
||||
*/
|
||||
static struct acl_t acls_bad[] = {
|
||||
static struct archive_test_acl_t acls_bad[] = {
|
||||
/* POSIX.1e ACL types */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 78, "" },
|
||||
@ -156,95 +148,6 @@ static struct acl_t acls_bad[] = {
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" },
|
||||
};
|
||||
|
||||
static void
|
||||
set_acls(struct archive_entry *ae, struct acl_t *acls, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
archive_entry_acl_clear(ae);
|
||||
for (i = 0; i < n; i++) {
|
||||
failure("type=%d, permset=%d, tag=%d, qual=%d name=%s",
|
||||
acls[i].type, acls[i].permset, acls[i].tag,
|
||||
acls[i].qual, acls[i].name);
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_add_entry(ae,
|
||||
acls[i].type, acls[i].permset, acls[i].tag,
|
||||
acls[i].qual, acls[i].name));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
acl_match(struct acl_t *acl, int type, int permset, int tag, int qual,
|
||||
const char *name)
|
||||
{
|
||||
if (acl == NULL)
|
||||
return (0);
|
||||
if (type != acl->type)
|
||||
return (0);
|
||||
if (permset != acl->permset)
|
||||
return (0);
|
||||
if (tag != acl->tag)
|
||||
return (0);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
return (1);
|
||||
if (qual != acl->qual)
|
||||
return (0);
|
||||
if (name == NULL) {
|
||||
if (acl->name == NULL || acl->name[0] == '\0')
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
if (acl->name == NULL) {
|
||||
if (name[0] == '\0')
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
return (0 == strcmp(name, acl->name));
|
||||
}
|
||||
|
||||
static void
|
||||
compare_acls(struct archive_entry *ae, struct acl_t *acls, int n)
|
||||
{
|
||||
int *marker = malloc(sizeof(marker[0]) * n);
|
||||
int i;
|
||||
int r;
|
||||
int type, permset, tag, qual;
|
||||
int matched;
|
||||
const char *name;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
marker[i] = i;
|
||||
|
||||
while (0 == (r = archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4,
|
||||
&type, &permset, &tag, &qual, &name))) {
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
if (acl_match(&acls[marker[i]], type, permset,
|
||||
tag, qual, name)) {
|
||||
/* We found a match; remove it. */
|
||||
marker[i] = marker[n - 1];
|
||||
n--;
|
||||
matched = 1;
|
||||
}
|
||||
}
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
|
||||
type, permset, tag, qual, name);
|
||||
assertEqualInt(1, matched);
|
||||
}
|
||||
assertEqualInt(ARCHIVE_EOF, r);
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
|
||||
acls[marker[0]].type, acls[marker[0]].permset,
|
||||
acls[marker[0]].tag, acls[marker[0]].qual, acls[marker[0]].name);
|
||||
assertEqualInt(0, n); /* Number of ACLs not matched should == 0 */
|
||||
free(marker);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_nfs4)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
@ -256,22 +159,31 @@ DEFINE_TEST(test_acl_nfs4)
|
||||
archive_entry_set_mode(ae, S_IFREG | 0777);
|
||||
|
||||
/* Store and read back some basic ACL entries. */
|
||||
set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
|
||||
/* Check that entry contains only NFSv4 types */
|
||||
assert((archive_entry_acl_types(ae) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0);
|
||||
assert((archive_entry_acl_types(ae) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0);
|
||||
|
||||
assertEqualInt(4,
|
||||
archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
/* A more extensive set of ACLs. */
|
||||
set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
assertEqualInt(32,
|
||||
archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
/*
|
||||
* Check that clearing ACLs gets rid of them all by repeating
|
||||
* the first test.
|
||||
*/
|
||||
set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
failure("Basic ACLs shouldn't be stored as extended ACLs");
|
||||
assertEqualInt(4,
|
||||
archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
@ -280,9 +192,9 @@ DEFINE_TEST(test_acl_nfs4)
|
||||
* Different types of malformed ACL entries that should
|
||||
* fail when added to existing NFS4 ACLs.
|
||||
*/
|
||||
set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
for (i = 0; i < (int)(sizeof(acls_bad)/sizeof(acls_bad[0])); ++i) {
|
||||
struct acl_t *p = &acls_bad[i];
|
||||
struct archive_test_acl_t *p = &acls_bad[i];
|
||||
failure("Malformed ACL test #%d", i);
|
||||
assertEqualInt(ARCHIVE_FAILED,
|
||||
archive_entry_acl_add_entry(ae,
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -23,11 +24,11 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_pax.c 201247 2009-12-30 05:59:21Z kientzle $");
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Exercise the system-independent portion of the ACL support.
|
||||
* Check that pax archive can save and restore ACL data.
|
||||
* Check that pax archive can save and restore POSIX.1e ACL data.
|
||||
*
|
||||
* This should work on all systems, regardless of whether local
|
||||
* filesystems support ACLs or not.
|
||||
@ -35,15 +36,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_pax.c 201247 2009-12-30 05
|
||||
|
||||
static unsigned char buff[16384];
|
||||
|
||||
struct acl_t {
|
||||
int type; /* Type of ACL: "access" or "default" */
|
||||
int permset; /* Permissions for this class of users. */
|
||||
int tag; /* Owner, User, Owning group, group, other, etc. */
|
||||
int qual; /* GID or UID of user/group, depending on tag. */
|
||||
const char *name; /* Name of user/group, depending on tag. */
|
||||
};
|
||||
|
||||
static struct acl_t acls0[] = {
|
||||
static struct archive_test_acl_t acls0[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -52,7 +45,7 @@ static struct acl_t acls0[] = {
|
||||
ARCHIVE_ENTRY_ACL_OTHER, 0, "" },
|
||||
};
|
||||
|
||||
static struct acl_t acls1[] = {
|
||||
static struct archive_test_acl_t acls1[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -63,7 +56,7 @@ static struct acl_t acls1[] = {
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct acl_t acls2[] = {
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -78,101 +71,149 @@ static struct acl_t acls2[] = {
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static void
|
||||
set_acls(struct archive_entry *ae, struct acl_t *acls, int n)
|
||||
{
|
||||
int i;
|
||||
static struct archive_test_acl_t acls3[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
archive_entry_acl_clear(ae);
|
||||
for (i = 0; i < n; i++) {
|
||||
archive_entry_acl_add_entry(ae,
|
||||
acls[i].type, acls[i].permset, acls[i].tag, acls[i].qual,
|
||||
acls[i].name);
|
||||
}
|
||||
}
|
||||
static struct archive_test_acl_t acls4[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
|
||||
ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 78, "user78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
static int
|
||||
acl_match(struct acl_t *acl, int type, int permset, int tag, int qual, const char *name)
|
||||
{
|
||||
if (type != acl->type)
|
||||
return (0);
|
||||
if (permset != acl->permset)
|
||||
return (0);
|
||||
if (tag != acl->tag)
|
||||
return (0);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_OTHER)
|
||||
return (1);
|
||||
if (qual != acl->qual)
|
||||
return (0);
|
||||
if (name == NULL)
|
||||
return (acl->name == NULL || acl->name[0] == '\0');
|
||||
if (acl->name == NULL)
|
||||
return (name == NULL || name[0] == '\0');
|
||||
return (0 == strcmp(name, acl->name));
|
||||
}
|
||||
static struct archive_test_acl_t acls5[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALARM,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
static void
|
||||
compare_acls(struct archive_entry *ae, struct acl_t *acls, int n, int mode)
|
||||
{
|
||||
int *marker = malloc(sizeof(marker[0]) * n);
|
||||
int i;
|
||||
int r;
|
||||
int type, permset, tag, qual;
|
||||
int matched;
|
||||
const char *name;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
marker[i] = i;
|
||||
|
||||
while (0 == (r = archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name))) {
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
if (acl_match(&acls[marker[i]], type, permset,
|
||||
tag, qual, name)) {
|
||||
/* We found a match; remove it. */
|
||||
marker[i] = marker[n - 1];
|
||||
n--;
|
||||
matched = 1;
|
||||
}
|
||||
}
|
||||
if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ) {
|
||||
if (!matched) printf("No match for user_obj perm\n");
|
||||
failure("USER_OBJ permset (%02o) != user mode (%02o)",
|
||||
permset, 07 & (mode >> 6));
|
||||
assert((permset << 6) == (mode & 0700));
|
||||
} else if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ) {
|
||||
if (!matched) printf("No match for group_obj perm\n");
|
||||
failure("GROUP_OBJ permset %02o != group mode %02o",
|
||||
permset, 07 & (mode >> 3));
|
||||
assert((permset << 3) == (mode & 0070));
|
||||
} else if (tag == ARCHIVE_ENTRY_ACL_OTHER) {
|
||||
if (!matched) printf("No match for other perm\n");
|
||||
failure("OTHER permset (%02o) != other mode (%02o)",
|
||||
permset, mode & 07);
|
||||
assert((permset << 0) == (mode & 0007));
|
||||
} else {
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
|
||||
type, permset, tag, qual, name);
|
||||
assert(matched == 1);
|
||||
}
|
||||
}
|
||||
assertEqualInt(ARCHIVE_EOF, r);
|
||||
assert((mode_t)(mode & 0777) == (archive_entry_mode(ae) & 0777));
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
|
||||
acls[marker[0]].type, acls[marker[0]].permset,
|
||||
acls[marker[0]].tag, acls[marker[0]].qual, acls[marker[0]].name);
|
||||
assert(n == 0); /* Number of ACLs not matched should == 0 */
|
||||
free(marker);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_pax)
|
||||
DEFINE_TEST(test_acl_pax_posix1e)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
@ -197,23 +238,23 @@ DEFINE_TEST(test_acl_pax)
|
||||
archive_entry_set_mode(ae, S_IFREG | 0777);
|
||||
|
||||
/* Basic owner/owning group should just update mode bits. */
|
||||
set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
assertA(0 == archive_write_header(a, ae));
|
||||
|
||||
/* With any extended ACL entry, we should read back a full set. */
|
||||
set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
assertA(0 == archive_write_header(a, ae));
|
||||
|
||||
|
||||
/* A more extensive set of ACLs. */
|
||||
set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
assertA(0 == archive_write_header(a, ae));
|
||||
|
||||
/*
|
||||
* Check that clearing ACLs gets rid of them all by repeating
|
||||
* the first test.
|
||||
*/
|
||||
set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
assertA(0 == archive_write_header(a, ae));
|
||||
archive_entry_free(ae);
|
||||
|
||||
@ -227,13 +268,13 @@ DEFINE_TEST(test_acl_pax)
|
||||
fclose(f);
|
||||
|
||||
/* Write out the reference data to a file for manual inspection. */
|
||||
extract_reference_file("test_acl_pax.tar");
|
||||
reference = slurpfile(&reference_size, "test_acl_pax.tar");
|
||||
extract_reference_file("test_acl_pax_posix1e.tar");
|
||||
reference = slurpfile(&reference_size, "test_acl_pax_posix1e.tar");
|
||||
|
||||
/* Assert that the generated data matches the built-in reference data.*/
|
||||
failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax.tar' reference file.");
|
||||
failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax_posix1e.tar' reference file.");
|
||||
assertEqualMem(buff, reference, reference_size);
|
||||
failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax.tar' reference file.");
|
||||
failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax_posix1e.tar' reference file.");
|
||||
assertEqualInt((int)used, reference_size);
|
||||
free(reference);
|
||||
|
||||
@ -255,15 +296,18 @@ DEFINE_TEST(test_acl_pax)
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
failure("One extended ACL should flag all ACLs to be returned.");
|
||||
assert(4 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), 0142);
|
||||
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142);
|
||||
failure("Basic ACLs should set mode to 0142, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0142);
|
||||
|
||||
/* Third item has pretty extensive ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), 0543);
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543);
|
||||
failure("Basic ACLs should set mode to 0543, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0543);
|
||||
@ -280,3 +324,93 @@ DEFINE_TEST(test_acl_pax)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_pax_nfs4)
|
||||
{
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
size_t used;
|
||||
FILE *f;
|
||||
void *reference;
|
||||
size_t reference_size;
|
||||
|
||||
/* Write an archive to memory. */
|
||||
assert(NULL != (a = archive_write_new()));
|
||||
assertA(0 == archive_write_set_format_pax(a));
|
||||
assertA(0 == archive_write_add_filter_none(a));
|
||||
assertA(0 == archive_write_set_bytes_per_block(a, 1));
|
||||
assertA(0 == archive_write_set_bytes_in_last_block(a, 1));
|
||||
assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
|
||||
|
||||
/* Write a series of files to the archive with different ACL info. */
|
||||
|
||||
/* Create a simple archive_entry. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
archive_entry_set_pathname(ae, "file");
|
||||
archive_entry_set_mode(ae, S_IFREG | 0777);
|
||||
|
||||
/* NFS4 ACLs mirroring 0754 file mode */
|
||||
archive_test_set_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]));
|
||||
assertA(0 == archive_write_header(a, ae));
|
||||
|
||||
/* A more extensive set of NFS4 ACLs. */
|
||||
archive_test_set_acls(ae, acls4, sizeof(acls4)/sizeof(acls4[0]));
|
||||
assertA(0 == archive_write_header(a, ae));
|
||||
|
||||
/* Set with special (audit, alarm) NFS4 ACLs. */
|
||||
archive_test_set_acls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]));
|
||||
assertA(0 == archive_write_header(a, ae));
|
||||
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Close out the archive. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
/* Write out the data we generated to a file for manual inspection. */
|
||||
assert(NULL != (f = fopen("testout", "wb")));
|
||||
assertEqualInt(used, (size_t)fwrite(buff, 1, (unsigned int)used, f));
|
||||
fclose(f);
|
||||
|
||||
/* Write out the reference data to a file for manual inspection. */
|
||||
extract_reference_file("test_acl_pax_nfs4.tar");
|
||||
reference = slurpfile(&reference_size, "test_acl_pax_nfs4.tar");
|
||||
|
||||
/* Assert that the generated data matches the built-in reference data.*/
|
||||
failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax_nfs4.tar' reference file.");
|
||||
assertEqualMem(buff, reference, reference_size);
|
||||
failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax_nfs4.tar' reference file.");
|
||||
assertEqualInt((int)used, reference_size);
|
||||
free(reference);
|
||||
|
||||
/* Read back each entry and check that the ACL data is right. */
|
||||
assert(NULL != (a = archive_read_new()));
|
||||
assertA(0 == archive_read_support_format_all(a));
|
||||
assertA(0 == archive_read_support_filter_all(a));
|
||||
assertA(0 == archive_read_open_memory(a, buff, used));
|
||||
|
||||
/* First item has NFS4 ACLs mirroring file mode */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(3, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ALLOW));
|
||||
archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0);
|
||||
|
||||
/* Second item has has more fine-grained NFS4 ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls4[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
/* Third item has has audit and alarm NFS4 ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
/* Close the archive. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
129
libarchive/test/test_acl_pax_nfs4.tar.uu
Normal file
129
libarchive/test/test_acl_pax_nfs4.tar.uu
Normal file
@ -0,0 +1,129 @@
|
||||
begin 644 test_acl_pax_nfs4.tar
|
||||
M4&%X2&5A9&5R+V9I;&4`````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````#`P,#<W-R``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,C`R
|
||||
M(#`P,#`P,#`P,#`P(#`Q,C`P,0`@>```````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````!U<W1A<@`P,```````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````P,#`P,#`@`#`P,#`P,"``````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````Q,S`@4T-(24Q9+F%C;"YA8V4];W=N97)`.G)W
|
||||
M>'`M+6%!4E=C0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7!`.G)W+7`M+6$M4BUC
|
||||
M+2US.BTM+2TM+2TZ86QL;W<L979E<GEO;F5`.G(M+2TM+6$M4BUC+2US.BTM
|
||||
M+2TM+2TZ86QL;W<*````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````````````````````````````&9I;&4`````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````````````````````````````````````````P
|
||||
M,#`W-S<@`#`P,#`P,"``,#`P,#`P(``P,#`P,#`P,#`P,"`P,#`P,#`P,#`P
|
||||
M,"`P,3`P,C0`(#``````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````=7-T87(`,#``````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````,#`P,#`P(``P,#`P,#`@````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````4&%X2&5A9&5R+V9I;&4`````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````#`P,#<W-R``,#`P,#`P(``P,#`P,#`@`#`P,#`P
|
||||
M,#`P-#`V(#`P,#`P,#`P,#`P(#`Q,C`P-P`@>```````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````````````!U<W1A<@`P
|
||||
M,```````````````````````````````````````````````````````````
|
||||
M```````````````````````````P,#`P,#`@`#`P,#`P,"``````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````````````R-C(@4T-(24Q9+F%C;"YA8V4];W=N
|
||||
M97)`.G)W+7`M+6%!4E=C0V]S.BTM+2TM+2TZ86QL;W<L=7-E<CIU<V5R-S<Z
|
||||
M<BTM+2TM82U2+6,M+7,Z+2TM+2TM23IA;&QO=SHW-RQU<V5R.G5S97(W.#IR
|
||||
M=W@M+2TM+2TM+2TM+3HM+2TM+2TM.F1E;GDZ-S@L9W)O=7!`.G)W+7`M+6$M
|
||||
M4BUC+2US.BTM+2TM+2TZ86QL;W<L9W)O=7`Z9W)O=7`W.#HM=RUP+2TM02U7
|
||||
M+4-O+3HM+2TM+2TM.F1E;GDZ-S@L979E<GEO;F5`.G(M+2TM+6$M4BUC+2US
|
||||
M.BTM+2TM+2TZ86QL;W<*````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````````````````````````````````````&9I;&4`
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````P,#`W-S<@`#`P,#`P,"``,#`P,#`P(``P,#`P,#`P,#`P,"`P,#`P
|
||||
M,#`P,#`P,"`P,3`P,C0`(#``````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````=7-T87(`,#``````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````,#`P,#`P(``P,#`P,#`@````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````4&%X2&5A9&5R+V9I;&4`````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````````````#`P,#<W-R``,#`P,#`P(``P,#`P,#`@
|
||||
M`#`P,#`P,#`P-#$P(#`P,#`P,#`P,#`P(#`Q,C`P,@`@>```````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````````````````````!U
|
||||
M<W1A<@`P,```````````````````````````````````````````````````
|
||||
M```````````````````````````````````P,#`P,#`@`#`P,#`P,"``````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````````````````````R-C0@4T-(24Q9+F%C;"YA
|
||||
M8V4];W=N97)`.G)W>'`M+6%!4E=C0V]S.BTM+2TM+2TZ86QL;W<L=7-E<CIU
|
||||
M<V5R-S<Z<G<M<"TM82U2+6,M;W,Z+2TM+2TM+3IA;&QO=SHW-RQU<V5R.G5S
|
||||
M97(W-SHM=RUP+2TM+2TM+2TM+3HM+2TM4RTM.F%U9&ET.C<W+&=R;W5P0#IR
|
||||
M=RUP+2UA+5(M8RTM<SHM+2TM+2TM.F%L;&]W+&=R;W5P.F=R;W5P-S@Z<BTM
|
||||
M+2TM82U2+6,M+2TZ+2TM+2U&+3IA;&%R;3HW."QE=F5R>6]N94`Z<BTM+2TM
|
||||
M82U2+6,M+7,Z+2TM+2TM+3IA;&QO=PH`````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`&9I;&4`````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````P,#`W-S<@`#`P,#`P,"``,#`P,#`P(``P,#`P,#`P,#`P
|
||||
M,"`P,#`P,#`P,#`P,"`P,3`P,C0`(#``````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````=7-T87(`,#``````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````,#`P,#`P(``P,#`P,#`@````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
'````````````
|
||||
`
|
||||
end
|
@ -1,4 +1,4 @@
|
||||
begin 644 test_acl_pax.tar
|
||||
begin 644 test_acl_pax_posix1e.tar
|
||||
M9FEL90``````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````#`P,#$T,B``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,#`P
|
@ -27,21 +27,14 @@ __FBSDID("$FreeBSD: src/lib/libarchive/test/test_acl_basic.c,v 1.6 2008/10/19 00
|
||||
|
||||
/*
|
||||
* Exercise the system-independent portion of the ACL support.
|
||||
* Check that archive_entry objects can save and restore POSIX.1e-style ACL data.
|
||||
* Check that archive_entry objects can save and restore POSIX.1e-style
|
||||
* ACL data.
|
||||
*
|
||||
* This should work on all systems, regardless of whether local
|
||||
* filesystems support ACLs or not.
|
||||
*/
|
||||
|
||||
struct acl_t {
|
||||
int type; /* Type of ACL: "access" or "default" */
|
||||
int permset; /* Permissions for this class of users. */
|
||||
int tag; /* Owner, User, Owning group, group, other, etc. */
|
||||
int qual; /* GID or UID of user/group, depending on tag. */
|
||||
const char *name; /* Name of user/group, depending on tag. */
|
||||
};
|
||||
|
||||
static struct acl_t acls0[] = {
|
||||
static struct archive_test_acl_t acls0[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -50,7 +43,7 @@ static struct acl_t acls0[] = {
|
||||
ARCHIVE_ENTRY_ACL_OTHER, 0, "" },
|
||||
};
|
||||
|
||||
static struct acl_t acls1[] = {
|
||||
static struct archive_test_acl_t acls1[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -61,7 +54,7 @@ static struct acl_t acls1[] = {
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct acl_t acls2[] = {
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -80,7 +73,7 @@ static struct acl_t acls2[] = {
|
||||
* NFS4 entry types; attempts to set these on top of POSIX.1e
|
||||
* attributes should fail.
|
||||
*/
|
||||
static struct acl_t acls_nfs4[] = {
|
||||
static struct archive_test_acl_t acls_nfs4[] = {
|
||||
/* NFS4 types */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 78, "" },
|
||||
@ -104,106 +97,6 @@ static struct acl_t acls_nfs4[] = {
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
};
|
||||
|
||||
static void
|
||||
set_acls(struct archive_entry *ae, struct acl_t *acls, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
archive_entry_acl_clear(ae);
|
||||
for (i = 0; i < n; i++) {
|
||||
archive_entry_acl_add_entry(ae,
|
||||
acls[i].type, acls[i].permset, acls[i].tag, acls[i].qual,
|
||||
acls[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
acl_match(struct acl_t *acl, int type, int permset, int tag, int qual, const char *name)
|
||||
{
|
||||
if (type != acl->type)
|
||||
return (0);
|
||||
if (permset != acl->permset)
|
||||
return (0);
|
||||
if (tag != acl->tag)
|
||||
return (0);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_OTHER)
|
||||
return (1);
|
||||
if (qual != acl->qual)
|
||||
return (0);
|
||||
if (name == NULL) {
|
||||
if (acl->name == NULL || acl->name[0] == '\0')
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
if (acl->name == NULL) {
|
||||
if (name[0] == '\0')
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
return (0 == strcmp(name, acl->name));
|
||||
}
|
||||
|
||||
static void
|
||||
compare_acls(struct archive_entry *ae, struct acl_t *acls, int n, int mode)
|
||||
{
|
||||
int *marker = malloc(sizeof(marker[0]) * n);
|
||||
int i;
|
||||
int r;
|
||||
int type, permset, tag, qual;
|
||||
int matched;
|
||||
const char *name;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
marker[i] = i;
|
||||
|
||||
while (0 == (r = archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name))) {
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
if (acl_match(&acls[marker[i]], type, permset,
|
||||
tag, qual, name)) {
|
||||
/* We found a match; remove it. */
|
||||
marker[i] = marker[n - 1];
|
||||
n--;
|
||||
matched = 1;
|
||||
}
|
||||
}
|
||||
if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ) {
|
||||
if (!matched) printf("No match for user_obj perm\n");
|
||||
failure("USER_OBJ permset (%02o) != user mode (%02o)",
|
||||
permset, 07 & (mode >> 6));
|
||||
assert((permset << 6) == (mode & 0700));
|
||||
} else if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ) {
|
||||
if (!matched) printf("No match for group_obj perm\n");
|
||||
failure("GROUP_OBJ permset %02o != group mode %02o",
|
||||
permset, 07 & (mode >> 3));
|
||||
assert((permset << 3) == (mode & 0070));
|
||||
} else if (tag == ARCHIVE_ENTRY_ACL_OTHER) {
|
||||
if (!matched) printf("No match for other perm\n");
|
||||
failure("OTHER permset (%02o) != other mode (%02o)",
|
||||
permset, mode & 07);
|
||||
assert((permset << 0) == (mode & 0007));
|
||||
} else {
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
|
||||
type, permset, tag, qual, name);
|
||||
assert(matched == 1);
|
||||
}
|
||||
}
|
||||
assertEqualInt(ARCHIVE_EOF, r);
|
||||
assert((mode_t)(mode & 0777) == (archive_entry_mode(ae) & 0777));
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%d,permset=%d,tag=%d,qual=%d,name=``%s'')",
|
||||
acls[marker[0]].type, acls[marker[0]].permset,
|
||||
acls[marker[0]].tag, acls[marker[0]].qual, acls[marker[0]].name);
|
||||
assert(n == 0); /* Number of ACLs not matched should == 0 */
|
||||
free(marker);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_posix1e)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
@ -223,7 +116,7 @@ DEFINE_TEST(test_acl_posix1e)
|
||||
* triggering unnecessary extensions. It's better to identify
|
||||
* trivial ACLs at the point they are being read from disk.
|
||||
*/
|
||||
set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
failure("Basic ACLs shouldn't be stored as extended ACLs");
|
||||
assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
failure("Basic ACLs should set mode to 0142, not %04o",
|
||||
@ -232,19 +125,28 @@ DEFINE_TEST(test_acl_posix1e)
|
||||
|
||||
|
||||
/* With any extended ACL entry, we should read back a full set. */
|
||||
set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
failure("One extended ACL should flag all ACLs to be returned.");
|
||||
|
||||
/* Check that entry contains only POSIX.1e types */
|
||||
assert((archive_entry_acl_types(ae) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0);
|
||||
assert((archive_entry_acl_types(ae) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0);
|
||||
|
||||
assert(4 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), 0142);
|
||||
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142);
|
||||
failure("Basic ACLs should set mode to 0142, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0142);
|
||||
|
||||
|
||||
/* A more extensive set of ACLs. */
|
||||
set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), 0543);
|
||||
archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543);
|
||||
failure("Basic ACLs should set mode to 0543, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0543);
|
||||
@ -253,7 +155,7 @@ DEFINE_TEST(test_acl_posix1e)
|
||||
* Check that clearing ACLs gets rid of them all by repeating
|
||||
* the first test.
|
||||
*/
|
||||
set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
failure("Basic ACLs shouldn't be stored as extended ACLs");
|
||||
assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
failure("Basic ACLs should set mode to 0142, not %04o",
|
||||
@ -264,9 +166,9 @@ DEFINE_TEST(test_acl_posix1e)
|
||||
* Different types of malformed ACL entries that should
|
||||
* fail when added to existing POSIX.1e ACLs.
|
||||
*/
|
||||
set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
for (i = 0; i < (int)(sizeof(acls_nfs4)/sizeof(acls_nfs4[0])); ++i) {
|
||||
struct acl_t *p = &acls_nfs4[i];
|
||||
struct archive_test_acl_t *p = &acls_nfs4[i];
|
||||
failure("Malformed ACL test #%d", i);
|
||||
assertEqualInt(ARCHIVE_FAILED,
|
||||
archive_entry_acl_add_entry(ae,
|
||||
|
456
libarchive/test/test_acl_text.c
Normal file
456
libarchive/test/test_acl_text.c
Normal file
@ -0,0 +1,456 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Test converting ACLs to text, both wide and non-wide
|
||||
*
|
||||
* This should work on all systems, regardless of whether local
|
||||
* filesystems support ACLs or not.
|
||||
*/
|
||||
|
||||
static struct archive_test_acl_t acls0[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ |
|
||||
ARCHIVE_ENTRY_ACL_WRITE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 100, "user100" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
|
||||
ARCHIVE_ENTRY_ACL_USER, 1000, "user1000" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ |
|
||||
ARCHIVE_ENTRY_ACL_WRITE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_READ |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 101, "user101"},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 79, "group79" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls1[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER,
|
||||
ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_DELETE_CHILD |
|
||||
ARCHIVE_ENTRY_ACL_DELETE |
|
||||
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_USER, 101, "user101" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
const char* acltext[] = {
|
||||
"user::rwx\n"
|
||||
"group::r-x\n"
|
||||
"other::r-x\n"
|
||||
"user:user100:r-x\n"
|
||||
"user:user1000:---\n"
|
||||
"group:group78:rwx\n"
|
||||
"default:user::r-x\n"
|
||||
"default:group::r-x\n"
|
||||
"default:other::---\n"
|
||||
"default:user:user101:r-x\n"
|
||||
"default:group:group79:--x",
|
||||
|
||||
"user::rwx\n"
|
||||
"group::r-x\n"
|
||||
"other::r-x\n"
|
||||
"user:user100:r-x:100\n"
|
||||
"user:user1000:---:1000\n"
|
||||
"group:group78:rwx:78\n"
|
||||
"default:user::r-x\n"
|
||||
"default:group::r-x\n"
|
||||
"default:other::---\n"
|
||||
"default:user:user101:r-x:101\n"
|
||||
"default:group:group79:--x:79",
|
||||
|
||||
"u::rwx\n"
|
||||
"g::r-x\n"
|
||||
"o::r-x\n"
|
||||
"u:user100:r-x:100\n"
|
||||
"u:user1000:---:1000\n"
|
||||
"g:group78:rwx:78\n"
|
||||
"d:user::r-x\n"
|
||||
"d:group::r-x\n"
|
||||
"d:other::---\n"
|
||||
"d:user:user101:r-x:101\n"
|
||||
"d:group:group79:--x:79",
|
||||
|
||||
"user::rwx\n"
|
||||
"group::r-x\n"
|
||||
"other::r-x\n"
|
||||
"user:user100:r-x\n"
|
||||
"user:user1000:---\n"
|
||||
"group:group78:rwx",
|
||||
|
||||
"user::rwx,"
|
||||
"group::r-x,"
|
||||
"other::r-x,"
|
||||
"user:user100:r-x,"
|
||||
"user:user1000:---,"
|
||||
"group:group78:rwx",
|
||||
|
||||
"user::rwx\n"
|
||||
"group::r-x\n"
|
||||
"other::r-x\n"
|
||||
"user:user100:r-x:100\n"
|
||||
"user:user1000:---:1000\n"
|
||||
"group:group78:rwx:78",
|
||||
|
||||
"user::r-x\n"
|
||||
"group::r-x\n"
|
||||
"other::---\n"
|
||||
"user:user101:r-x\n"
|
||||
"group:group79:--x",
|
||||
|
||||
"user::r-x\n"
|
||||
"group::r-x\n"
|
||||
"other::---\n"
|
||||
"user:user101:r-x:101\n"
|
||||
"group:group79:--x:79",
|
||||
|
||||
"default:user::r-x\n"
|
||||
"default:group::r-x\n"
|
||||
"default:other::---\n"
|
||||
"default:user:user101:r-x\n"
|
||||
"default:group:group79:--x",
|
||||
|
||||
"user:user77:rw-p--a-R-c-o-:-------:allow\n"
|
||||
"user:user101:-w-pdD--------:fdin---:deny\n"
|
||||
"group:group78:r-----a-R-c---:------I:allow\n"
|
||||
"owner@:rwxp--aARWcCo-:-------:allow\n"
|
||||
"group@:rw-p--a-R-c---:-------:allow\n"
|
||||
"everyone@:r-----a-R-c--s:-------:allow",
|
||||
|
||||
"user:user77:rw-p--a-R-c-o-:-------:allow:77\n"
|
||||
"user:user101:-w-pdD--------:fdin---:deny:101\n"
|
||||
"group:group78:r-----a-R-c---:------I:allow:78\n"
|
||||
"owner@:rwxp--aARWcCo-:-------:allow\n"
|
||||
"group@:rw-p--a-R-c---:-------:allow\n"
|
||||
"everyone@:r-----a-R-c--s:-------:allow"
|
||||
};
|
||||
|
||||
static wchar_t *
|
||||
convert_s_to_ws(const char *s)
|
||||
{
|
||||
size_t len;
|
||||
wchar_t *ws = NULL;
|
||||
|
||||
if (s != NULL) {
|
||||
len = strlen(s) + 1;
|
||||
ws = malloc(len * sizeof(wchar_t));
|
||||
assert(mbstowcs(ws, s, len) != (size_t)-1);
|
||||
}
|
||||
|
||||
return (ws);
|
||||
}
|
||||
|
||||
static void
|
||||
compare_acl_text(struct archive_entry *ae, int flags, const char *s)
|
||||
{
|
||||
const char *text;
|
||||
const wchar_t *wtext;
|
||||
wchar_t *ws;
|
||||
ssize_t slen;
|
||||
|
||||
ws = convert_s_to_ws(s);
|
||||
|
||||
text = archive_entry_acl_to_text(ae, &slen, flags);
|
||||
assertEqualString(text, s);
|
||||
if (text != NULL)
|
||||
assertEqualInt(strlen(text), slen);
|
||||
wtext = archive_entry_acl_to_text_w(ae, &slen, flags);
|
||||
assertEqualWString(wtext, ws);
|
||||
if (wtext != NULL) {
|
||||
assertEqualInt(wcslen(wtext), slen);
|
||||
free(ws);
|
||||
ws = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_from_text)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
wchar_t *ws = NULL;
|
||||
|
||||
/* Create an empty archive_entry. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
|
||||
/* 1a. Read POSIX.1e access ACLs from text */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text(ae, acltext[5],
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0755);
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
|
||||
/* 1b. Now read POSIX.1e default ACLs and append them */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text(ae, acltext[7],
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
|
||||
assertEqualInt(11, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
/* 1a and 1b with wide strings */
|
||||
ws = convert_s_to_ws(acltext[5]);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text_w(ae, ws,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0755);
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
|
||||
free(ws);
|
||||
ws = convert_s_to_ws(acltext[7]);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text_w(ae, ws,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
|
||||
assertEqualInt(11, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
/* 2. Read POSIX.1e default ACLs from text */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text(ae, acltext[7],
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0);
|
||||
assertEqualInt(5, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
/* ws is still acltext[7] */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text_w(ae, ws,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0);
|
||||
assertEqualInt(5, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
/* 3. Read POSIX.1e access and default ACLs from text */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text(ae, acltext[1],
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
|
||||
assertEqualInt(11, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
free(ws);
|
||||
ws = convert_s_to_ws(acltext[1]);
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text_w(ae, ws,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
|
||||
assertEqualInt(11, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
/* 4. Read POSIX.1e access and default ACLs from text (short form) */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text(ae, acltext[2],
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
|
||||
assertEqualInt(11, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
free(ws);
|
||||
ws = convert_s_to_ws(acltext[2]);
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text_w(ae, ws,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
|
||||
assertEqualInt(11, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
/* 5. Read NFSv4 ACLs from text */
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text(ae, acltext[10],
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
free(ws);
|
||||
ws = convert_s_to_ws(acltext[10]);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_entry_acl_from_text_w(ae, ws,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_entry_acl_clear(ae);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_to_text)
|
||||
{
|
||||
struct archive_entry *ae;
|
||||
|
||||
/* Create an empty archive_entry. */
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
|
||||
/* Write POSIX.1e ACLs */
|
||||
archive_test_set_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
|
||||
|
||||
/* No flags should give output like getfacl(1) on linux */
|
||||
compare_acl_text(ae, 0, acltext[0]);
|
||||
|
||||
/* This should give the same output as previous test */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, acltext[0]);
|
||||
|
||||
/* This should give the same output as previous two tests */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT, acltext[0]);
|
||||
|
||||
/* POSIX.1e access and default ACLs with appended ID */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[1]);
|
||||
|
||||
/* POSIX.1e access acls only, like getfacl(1) on FreeBSD */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, acltext[3]);
|
||||
|
||||
/* POSIX.1e access acls separated with comma */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA,
|
||||
acltext[4]);
|
||||
|
||||
/* POSIX.1e access acls with appended user or group ID */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[5]);
|
||||
|
||||
/* POSIX.1e default acls */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, acltext[6]);
|
||||
|
||||
/* POSIX.1e default acls with appended user or group ID */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[7]);
|
||||
|
||||
/* POSIX.1e default acls prefixed with default: */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
|
||||
ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT, acltext[8]);
|
||||
|
||||
/* Write NFSv4 ACLs */
|
||||
archive_test_set_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
|
||||
|
||||
/* NFSv4 ACLs like getfacl(1) on FreeBSD */
|
||||
compare_acl_text(ae, 0, acltext[9]);
|
||||
|
||||
/* NFSv4 ACLs like "getfacl -i" on FreeBSD */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[10]);
|
||||
}
|
321
libarchive/test/test_compat_star_acl.c
Normal file
321
libarchive/test/test_compat_star_acl.c
Normal file
@ -0,0 +1,321 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created
|
||||
* by star.
|
||||
*
|
||||
* This should work on all systems, regardless of whether local filesystems
|
||||
* support ACLs or not.
|
||||
*/
|
||||
|
||||
static struct archive_test_acl_t acls0[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls1[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
|
||||
ARCHIVE_ENTRY_ACL_USER, -1, "user78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, -1, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, -1, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_WRITE,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls3[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls4[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
|
||||
ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 78, "user78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls5[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
|
||||
ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
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 |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
DEFINE_TEST(test_compat_star_acl_posix1e)
|
||||
{
|
||||
char name[] = "test_compat_star_acl_posix1e.tar";
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
/* Read archive file */
|
||||
assert(NULL != (a = archive_read_new()));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name,
|
||||
10240));
|
||||
|
||||
/* First item has a few ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
failure("One extended ACL should flag all ACLs to be returned.");
|
||||
assertEqualInt(5, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142);
|
||||
failure("Basic ACLs should set mode to 0142, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0142);
|
||||
|
||||
/* Second item has pretty extensive ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(7, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543);
|
||||
failure("Basic ACLs should set mode to 0543, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0543);
|
||||
|
||||
/* Third item has default ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0142);
|
||||
failure("Basic ACLs should set mode to 0142, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0142);
|
||||
|
||||
/* Close the archive. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_compat_star_acl_nfs4)
|
||||
{
|
||||
char name[] = "test_compat_star_acl_nfs4.tar";
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
/* Read archive file */
|
||||
assert(NULL != (a = archive_read_new()));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240
|
||||
));
|
||||
|
||||
/* First item has NFS4 ACLs mirroring file mode */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(3, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ALLOW));
|
||||
archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0);
|
||||
|
||||
/* Second item has has fine-grained NFS4 ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
/* Third item has file and directory inheritance NFS4 ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(5, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
/* Close the archive. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
231
libarchive/test/test_compat_star_acl_nfs4.tar.uu
Normal file
231
libarchive/test/test_compat_star_acl_nfs4.tar.uu
Normal file
@ -0,0 +1,231 @@
|
||||
begin 644 test_compat_star_acl_nfs4.tar
|
||||
M+B\N+T!087A(96%D97(`````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````#`P,#`V,#`@,#`P,#`P,"`P,#`P,#`P(#`P,#`P,#`P,C<R
|
||||
M(#`P,#`P,#`P,#`P(#`P,38P-S0@9P``````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````!U<W1A<@`P,')O;W0`
|
||||
M````````````````````````````````````=VAE96P`````````````````
|
||||
M```````````````````P,#`P,#`P(#`P,#`P,#`@````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````````````````P,#`P,#`P,#`P,"`P,#`P,#`P
|
||||
M,#`P,"`````````````````U-R!30TA)3%DN<F5L96%S93US=&%R(#$N-2XS
|
||||
M("AA;60V-"UU;FMN;W=N+69R965B<V0Q,2XP*0HR-R!30TA)3%DN87)C:'1Y
|
||||
M<&4]97AU<W1A<@HT-R!30TA)3%DN=F]L:&1R+F1U;7!D871E/3$T-SDQ-C<W
|
||||
M,C<N,38W,C(U,C@Q"C(U(%-#2$E,62YV;VQH9'(N=F]L;F\],0HS,"!30TA)
|
||||
M3%DN=F]L:&1R+F)L;V-K<VEZ93TR,`H`````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````````````````````````````"XO+B]`4&%X2&5A
|
||||
M9&5R````````````````````````````````````````````````````````
|
||||
M```````````````````````````````````````````````````````````P
|
||||
M,#`P-C`P(#`P,#`P,#`@,#`P,#`P,"`P,#`P,#`P,#,S-"`P,#`P,#`P,#`P
|
||||
M,"`P,#$V,3$T('@`````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````=7-T87(`,#!R;V]T````````````````
|
||||
M`````````````````````'=H965L````````````````````````````````
|
||||
M````,#`P,#`P,"`P,#`P,#`P(```````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````,#`P,#`P,#`P,#`@,#`P,#`P,#`P,#`@````````
|
||||
M````````,S`@871I;64],30W.3$Q.34U-"XP-#,U-#DP,#`*,S`@8W1I;64]
|
||||
M,30W.3$Q.3DQ,BXY,SDQ-C@P,#`*,S`@;71I;64],30W.3$Q.34U-"XP-#,U
|
||||
M-#DP,#`*,3,P(%-#2$E,62YA8VPN86-E/6]W;F5R0#IR=WAP+2UA05)78T-O
|
||||
M<SHM+2TM+2TM.F%L;&]W+&=R;W5P0#IR=RUP+2UA+5(M8RTM<SHM+2TM+2TM
|
||||
M.F%L;&]W+&5V97)Y;VYE0#IR+2TM+2UA+5(M8RTM<SHM+2TM+2TM.F%L;&]W
|
||||
M"@``````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````!F:6QE,0``````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````,#`P,#<V-"`P,#`P
|
||||
M,#`P(#`P,#`P,#`@,#`P,#`P,#`P,#`@,3,P,3(S,3$S,#(@,#`Q-#8S-B`P
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````'5S=&%R`#`P<F]O=```````````````````````````````
|
||||
M``````!W:&5E;````````````````````````````````````#`P,#`P,#`@
|
||||
M,#`P,#`P,"``````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````#$S,#$R,S$Q,S`R(#$S,#$R,S$R,#4P(````````````````"XO+B]`
|
||||
M4&%X2&5A9&5R````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````P,#`P-C`P(#`P,#`P,#`@,#`P,#`P,"`P,#`P,#`P,#4T,"`P,#`P
|
||||
M,#`P,#`P,"`P,#$V,3$S('@`````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````=7-T87(`,#!R;V]T````````
|
||||
M`````````````````````````````'=H965L````````````````````````
|
||||
M````````````,#`P,#`P,"`P,#`P,#`P(```````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````,#`P,#`P,#`P,#`@,#`P,#`P,#`P,#`@
|
||||
M````````````````,S`@871I;64],30W.3$Q.34U-2XR-C<P,3@P,#`*,S`@
|
||||
M8W1I;64],30W.3$V,34Y."XY,SDV-#8P,#`*,S`@;71I;64],30W.3$Q.34U
|
||||
M-2XR-C<P,3@P,#`*,C8R(%-#2$E,62YA8VPN86-E/75S97(Z=7-E<C<X.G)W
|
||||
M>"TM+2TM+2TM+2TM.BTM+2TM+2TZ9&5N>3HW."QG<F]U<#IG<F]U<#<X.BUW
|
||||
M+7`M+2U!+5<M0V\M.BTM+2TM+2TZ9&5N>3HW."QU<V5R.G5S97(W-SIR+2TM
|
||||
M+2UA+5(M8RTM<SHM+2TM+2U).F%L;&]W.C<W+&]W;F5R0#IR=RUP+2UA05)7
|
||||
M8T-O<SHM+2TM+2TM.F%L;&]W+&=R;W5P0#IR=RUP+2UA+5(M8RTM<SHM+2TM
|
||||
M+2TM.F%L;&]W+&5V97)Y;VYE0#IR+2TM+2UA+5(M8RTM<SHM+2TM+2TM.F%L
|
||||
M;&]W"@``````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````!F:6QE,@``````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````,#`P,#8V
|
||||
M-"`P,#`P,#`P(#`P,#`P,#`@,#`P,#`P,#`P,#`@,3,P,3(S,3$S,#,@,#`Q
|
||||
M-#8U-R`P````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````'5S=&%R`#`P<F]O=```````````````````````
|
||||
M``````````````!W:&5E;````````````````````````````````````#`P
|
||||
M,#`P,#`@,#`P,#`P,"``````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````#$S,#$R,S$Q,S`S(#$S,#$R-#,S,S<V(```````````````
|
||||
M`"XO+B]`4&%X2&5A9&5R````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````P,#`P-C`P(#`P,#`P,#`@,#`P,#`P,"`P,#`P,#`P,#0V
|
||||
M-2`P,#`P,#`P,#`P,"`P,#$V,3(Q('@`````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````=7-T87(`,#!R;V]T
|
||||
M`````````````````````````````````````'=H965L````````````````
|
||||
M````````````````````,#`P,#`P,"`P,#`P,#`P(```````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````,#`P,#`P,#`P,#`@,#`P,#`P
|
||||
M,#`P,#`@````````````````,S`@871I;64],30W.3$V-S0Y-2XV.#<X-C8P
|
||||
M,#`*,S`@8W1I;64],30W.3$V-S<R,RXT-#`X-C<P,#`*,S`@;71I;64],30W
|
||||
M.3$R,#8W."XT-#$U.#`P,#`*,C$Y(%-#2$E,62YA8VPN86-E/6=R;W5P.F=R
|
||||
M;W5P-S@Z<G=X<$1D84%25V-#;W,Z9F0M+2TM+3ID96YY.C<X+'5S97(Z=7-E
|
||||
M<C<W.G(M+2TM+6$M4BUC+2US.F9D+2TM+2TZ86QL;W<Z-S<L;W=N97)`.G)W
|
||||
M>'`M+6%!4E=C0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7!`.G)W>'`M+6%!4E=C
|
||||
M+2US.BTM+2TM+2TZ86QL;W<L979E<GEO;F5`.G(M>"TM+6$M4BUC+2US.BTM
|
||||
M+2TM+2TZ86QL;W<*````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````````!D:7(Q+P``````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M,#`P,#<W-2`P,#`P,#`P(#`P,#`P,#`@,#`P,#`P,#`P,#`@,3,P,3(S,3,T
|
||||
M-#8@,#`Q-#8S,2`U````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````````````'5S=&%R`#`P<F]O=```````````````
|
||||
M``````````````````````!W:&5E;```````````````````````````````
|
||||
M`````#`P,#`P,#`@,#`P,#`P,"``````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````````````#$S,#$R-#0W,#`W(#$S,#$R-#0W,S4S(```````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
9````````````````````````````````````
|
||||
`
|
||||
end
|
@ -1,215 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Verify reading entries with POSIX.1e ACLs from archives created by star
|
||||
*
|
||||
* This should work on all systems, regardless of whether local filesystems
|
||||
* support ACLs or not.
|
||||
*/
|
||||
|
||||
struct acl_t {
|
||||
int type; /* Type of ACL: "access" or "default" */
|
||||
int permset; /* Permissions for this class of users. */
|
||||
int tag; /* Owner, User, Owning group, group, other, etc. */
|
||||
const char *name; /* Name of user/group, depending on tag. */
|
||||
};
|
||||
|
||||
static struct acl_t acls0[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_MASK, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, "" },
|
||||
};
|
||||
|
||||
static struct acl_t acls1[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
|
||||
ARCHIVE_ENTRY_ACL_USER, "user78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
|
||||
ARCHIVE_ENTRY_ACL_MASK, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, "" },
|
||||
};
|
||||
|
||||
static struct acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, "user77" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, "group78" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_MASK, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_WRITE,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, "" },
|
||||
};
|
||||
|
||||
static int
|
||||
acl_match(struct acl_t *acl, int type, int permset, int tag, const char *name)
|
||||
{
|
||||
if (type != acl->type)
|
||||
return (0);
|
||||
if (permset != acl->permset)
|
||||
return (0);
|
||||
if (tag != acl->tag)
|
||||
return (0);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_OTHER)
|
||||
return (1);
|
||||
if (tag == ARCHIVE_ENTRY_ACL_MASK)
|
||||
return (1);
|
||||
if (name == NULL)
|
||||
return (acl->name == NULL || acl->name[0] == '\0');
|
||||
if (acl->name == NULL)
|
||||
return (name == NULL || name[0] == '\0');
|
||||
return (0 == strcmp(name, acl->name));
|
||||
}
|
||||
|
||||
static void
|
||||
compare_acls(struct archive_entry *ae, struct acl_t *acls, int n, int mode,
|
||||
int want_type)
|
||||
{
|
||||
int *marker = malloc(sizeof(marker[0]) * n);
|
||||
int i;
|
||||
int r;
|
||||
int type, permset, tag, qual;
|
||||
int matched;
|
||||
const char *name;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
marker[i] = i;
|
||||
|
||||
while (0 == (r = archive_entry_acl_next(ae, want_type,
|
||||
&type, &permset, &tag, &qual, &name))) {
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
if (acl_match(&acls[marker[i]], type, permset,
|
||||
tag, name)) {
|
||||
/* We found a match; remove it. */
|
||||
marker[i] = marker[n - 1];
|
||||
n--;
|
||||
matched = 1;
|
||||
}
|
||||
}
|
||||
if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ) {
|
||||
if (!matched) printf("No match for user_obj perm\n");
|
||||
if (want_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
||||
failure("USER_OBJ permset (%02o) != user mode (%02o)",
|
||||
permset, 07 & (mode >> 6));
|
||||
assert((permset << 6) == (mode & 0700));
|
||||
}
|
||||
} else if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ) {
|
||||
if (!matched) printf("No match for group_obj perm\n");
|
||||
if (want_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
||||
failure("GROUP_OBJ permset %02o != group mode %02o",
|
||||
permset, 07 & (mode >> 3));
|
||||
assert((permset << 3) == (mode & 0070));
|
||||
}
|
||||
} else if (tag == ARCHIVE_ENTRY_ACL_OTHER) {
|
||||
if (!matched) printf("No match for other perm\n");
|
||||
if (want_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
|
||||
failure("OTHER permset (%02o) != other mode (%02o)",
|
||||
permset, mode & 07);
|
||||
assert((permset << 0) == (mode & 0007));
|
||||
}
|
||||
} else if (tag != ARCHIVE_ENTRY_ACL_MASK) {
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%d,permset=%d,tag=%d,name=``%s'')",
|
||||
type, permset, tag, name);
|
||||
assert(matched == 1);
|
||||
}
|
||||
}
|
||||
assertEqualInt(ARCHIVE_EOF, r);
|
||||
assert((mode_t)(mode & 0777) == (archive_entry_mode(ae) & 0777));
|
||||
failure("Could not find match for ACL "
|
||||
"(type=%d,permset=%d,tag=%d,name=``%s'')",
|
||||
acls[marker[0]].type, acls[marker[0]].permset,
|
||||
acls[marker[0]].tag, acls[marker[0]].name);
|
||||
assert(n == 0); /* Number of ACLs not matched should == 0 */
|
||||
free(marker);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_compat_star_acl_posix1e)
|
||||
{
|
||||
char name[] = "test_compat_star_acl_posix1e.tar";
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
|
||||
/* Read archive file */
|
||||
assert(NULL != (a = archive_read_new()));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));
|
||||
|
||||
/* First item has a few ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
failure("One extended ACL should flag all ACLs to be returned.");
|
||||
assertEqualInt(5, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), 0142, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
failure("Basic ACLs should set mode to 0142, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0142);
|
||||
|
||||
/* Second item has pretty extensive ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(7, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), 0543, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
failure("Basic ACLs should set mode to 0543, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0543);
|
||||
|
||||
/* Third item has default ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), 0142, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
|
||||
failure("Basic ACLs should set mode to 0142, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0142);
|
||||
|
||||
/* Close the archive. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
Loading…
Reference in New Issue
Block a user