1/*-
2 * Copyright (c) 2003-2007 Tim Kientzle
3 * Copyright (c) 2016 Martin Matuska
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26#include "test.h"
27
28/*
29 * Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created
30 * by star.
31 *
32 * This should work on all systems, regardless of whether local filesystems
33 * support ACLs or not.
34 */
35
36static struct archive_test_acl_t acls0[] = {
37	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
38	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
39	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
40	  ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
41	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
42	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
43	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
44	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
45	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE,
46	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
47};
48
49static struct archive_test_acl_t acls1[] = {
50	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
51	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
52	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
53	  ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
54	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
55	  ARCHIVE_ENTRY_ACL_USER, -1, "user78" },
56	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
57	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
58	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
59	  ARCHIVE_ENTRY_ACL_GROUP, -1, "group78" },
60	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
61	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
62	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE,
63	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
64};
65
66static struct archive_test_acl_t acls2[] = {
67	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
68	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" },
69	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ,
70	  ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
71	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ,
72	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
73	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
74	  ARCHIVE_ENTRY_ACL_GROUP, -1, "group78" },
75	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EXECUTE,
76	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
77	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_WRITE,
78	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
79};
80
81static struct archive_test_acl_t acls3[] = {
82	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
83	    ARCHIVE_ENTRY_ACL_READ_DATA |
84	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
85	    ARCHIVE_ENTRY_ACL_EXECUTE |
86	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
87	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
88	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
89	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
90	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
91	    ARCHIVE_ENTRY_ACL_READ_ACL |
92	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
93	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
94	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
95	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
96	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
97	    ARCHIVE_ENTRY_ACL_READ_DATA |
98	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
99	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
100	    ARCHIVE_ENTRY_ACL_READ_ACL |
101	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
102	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
103	    ARCHIVE_ENTRY_ACL_READ_ACL |
104	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
105	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
106	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
107	    ARCHIVE_ENTRY_ACL_READ_DATA |
108	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
109	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
110	    ARCHIVE_ENTRY_ACL_READ_ACL |
111	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
112	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
113};
114
115static struct archive_test_acl_t acls4[] = {
116	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
117	    ARCHIVE_ENTRY_ACL_READ_DATA |
118	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
119	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
120	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
121	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
122	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
123	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
124	    ARCHIVE_ENTRY_ACL_READ_ACL |
125	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
126	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
127	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
128	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
129	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
130	    ARCHIVE_ENTRY_ACL_READ_DATA |
131	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
132	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
133	    ARCHIVE_ENTRY_ACL_READ_ACL |
134	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
135	    ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
136	  ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
137	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
138	    ARCHIVE_ENTRY_ACL_READ_DATA |
139	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
140	    ARCHIVE_ENTRY_ACL_EXECUTE,
141	  ARCHIVE_ENTRY_ACL_USER, 78, "user78" },
142	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
143	    ARCHIVE_ENTRY_ACL_READ_DATA |
144	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
145	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
146	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
147	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
148	    ARCHIVE_ENTRY_ACL_READ_ACL |
149	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
150	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
151	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
152	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
153	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
154	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
155	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
156	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
157	    ARCHIVE_ENTRY_ACL_WRITE_OWNER,
158	  ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
159	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
160	    ARCHIVE_ENTRY_ACL_READ_DATA |
161	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
162	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
163	    ARCHIVE_ENTRY_ACL_READ_ACL |
164	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
165	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
166};
167
168static struct archive_test_acl_t acls5[] = {
169	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
170	    ARCHIVE_ENTRY_ACL_READ_DATA |
171	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
172	    ARCHIVE_ENTRY_ACL_EXECUTE |
173	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
174	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
175	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
176	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
177	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
178	    ARCHIVE_ENTRY_ACL_READ_ACL |
179	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
180	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
181	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
182	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
183	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
184	    ARCHIVE_ENTRY_ACL_READ_DATA |
185	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
186	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
187	    ARCHIVE_ENTRY_ACL_READ_ACL |
188	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
189	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
190	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
191	  ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
192	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
193	    ARCHIVE_ENTRY_ACL_READ_DATA |
194	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
195	    ARCHIVE_ENTRY_ACL_EXECUTE |
196	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
197	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
198	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
199	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
200	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
201	    ARCHIVE_ENTRY_ACL_READ_ACL |
202	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
203	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
204	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
205	    ARCHIVE_ENTRY_ACL_READ_DATA |
206	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
207	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
208	    ARCHIVE_ENTRY_ACL_EXECUTE |
209	    ARCHIVE_ENTRY_ACL_DELETE |
210	    ARCHIVE_ENTRY_ACL_DELETE_CHILD |
211	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
212	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
213	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
214	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
215	    ARCHIVE_ENTRY_ACL_READ_ACL |
216	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
217	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
218	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
219	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
220	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
221	  ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
222	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
223	    ARCHIVE_ENTRY_ACL_READ_DATA |
224	    ARCHIVE_ENTRY_ACL_EXECUTE |
225	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
226	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
227	    ARCHIVE_ENTRY_ACL_READ_ACL |
228	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
229	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
230};
231
232DEFINE_TEST(test_compat_star_acl_posix1e)
233{
234	char name[] = "test_compat_star_acl_posix1e.tar";
235	struct archive *a;
236	struct archive_entry *ae;
237
238	/* Read archive file */
239	assert(NULL != (a = archive_read_new()));
240        assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
241        assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
242        extract_reference_file(name);
243	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name,
244	    10240));
245
246	/* First item has a few ACLs */
247	assertA(0 == archive_read_next_header(a, &ae));
248	failure("One extended ACL should flag all ACLs to be returned.");
249	assertEqualInt(5, archive_entry_acl_reset(ae,
250	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
251	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
252	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142);
253	failure("Basic ACLs should set mode to 0142, not %04o",
254	    archive_entry_mode(ae)&0777);
255	assert((archive_entry_mode(ae) & 0777) == 0142);
256
257	/* Second item has pretty extensive ACLs */
258	assertA(0 == archive_read_next_header(a, &ae));
259	assertEqualInt(7, archive_entry_acl_reset(ae,
260	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
261	assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
262	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543);
263	failure("Basic ACLs should set mode to 0543, not %04o",
264	    archive_entry_mode(ae)&0777);
265	assert((archive_entry_mode(ae) & 0777) == 0543);
266
267	/* Third item has default ACLs */
268	assertA(0 == archive_read_next_header(a, &ae));
269	assertEqualInt(6, archive_entry_acl_reset(ae,
270	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
271	assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
272	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0142);
273	failure("Basic ACLs should set mode to 0142, not %04o",
274	    archive_entry_mode(ae)&0777);
275	assert((archive_entry_mode(ae) & 0777) == 0142);
276
277	/* Close the archive. */
278	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
279	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
280}
281
282DEFINE_TEST(test_compat_star_acl_nfs4)
283{
284	char name[] = "test_compat_star_acl_nfs4.tar";
285	struct archive *a;
286	struct archive_entry *ae;
287
288	/* Read archive file */
289	assert(NULL != (a = archive_read_new()));
290	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
291	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
292	extract_reference_file(name);
293	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240
294));
295
296	/* First item has NFS4 ACLs mirroring file mode */
297	assertA(0 == archive_read_next_header(a, &ae));
298	assertEqualInt(3, archive_entry_acl_reset(ae,
299	    ARCHIVE_ENTRY_ACL_TYPE_ALLOW));
300	assertEntryCompareAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
301	    ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0);
302
303	/* Second item has has fine-grained NFS4 ACLs */
304	assertA(0 == archive_read_next_header(a, &ae));
305	assertEqualInt(6, archive_entry_acl_reset(ae,
306	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
307	assertEntryCompareAcls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
308	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
309
310	/* Third item has file and directory inheritance NFS4 ACLs */
311	assertA(0 == archive_read_next_header(a, &ae));
312	assertEqualInt(5, archive_entry_acl_reset(ae,
313	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
314	assertEntryCompareAcls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]),
315	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
316
317	/* Close the archive. */
318	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
319	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
320}
321