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 __FBSDID("$FreeBSD$");
28 
29 /*
30  * Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created
31  * by star.
32  *
33  * This should work on all systems, regardless of whether local filesystems
34  * support ACLs or not.
35  */
36 
37 static struct archive_test_acl_t acls0[] = {
38 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
39 	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
40 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
41 	  ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
42 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
43 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
44 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
45 	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
46 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE,
47 	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
48 };
49 
50 static struct archive_test_acl_t acls1[] = {
51 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
52 	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
53 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
54 	  ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
55 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
56 	  ARCHIVE_ENTRY_ACL_USER, -1, "user78" },
57 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
58 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
59 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
60 	  ARCHIVE_ENTRY_ACL_GROUP, -1, "group78" },
61 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007,
62 	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
63 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE,
64 	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
65 };
66 
67 static struct archive_test_acl_t acls2[] = {
68 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
69 	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" },
70 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ,
71 	  ARCHIVE_ENTRY_ACL_USER, -1, "user77" },
72 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ,
73 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
74 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE,
75 	  ARCHIVE_ENTRY_ACL_GROUP, -1, "group78" },
76 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EXECUTE,
77 	  ARCHIVE_ENTRY_ACL_MASK, -1, ""},
78 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_WRITE,
79 	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
80 };
81 
82 static struct archive_test_acl_t acls3[] = {
83 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
84 	    ARCHIVE_ENTRY_ACL_READ_DATA |
85 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
86 	    ARCHIVE_ENTRY_ACL_EXECUTE |
87 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
88 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
89 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
90 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
91 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
92 	    ARCHIVE_ENTRY_ACL_READ_ACL |
93 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
94 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
95 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
96 	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
97 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
98 	    ARCHIVE_ENTRY_ACL_READ_DATA |
99 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
100 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
101 	    ARCHIVE_ENTRY_ACL_READ_ACL |
102 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
103 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
104 	    ARCHIVE_ENTRY_ACL_READ_ACL |
105 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
106 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
107 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
108 	    ARCHIVE_ENTRY_ACL_READ_DATA |
109 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
110 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
111 	    ARCHIVE_ENTRY_ACL_READ_ACL |
112 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
113 	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
114 };
115 
116 static struct archive_test_acl_t acls4[] = {
117 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
118 	    ARCHIVE_ENTRY_ACL_READ_DATA |
119 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
120 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
121 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
122 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
123 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
124 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
125 	    ARCHIVE_ENTRY_ACL_READ_ACL |
126 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
127 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
128 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
129 	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
130 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
131 	    ARCHIVE_ENTRY_ACL_READ_DATA |
132 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
133 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
134 	    ARCHIVE_ENTRY_ACL_READ_ACL |
135 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
136 	    ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
137 	  ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
138 	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
139 	    ARCHIVE_ENTRY_ACL_READ_DATA |
140 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
141 	    ARCHIVE_ENTRY_ACL_EXECUTE,
142 	  ARCHIVE_ENTRY_ACL_USER, 78, "user78" },
143 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
144 	    ARCHIVE_ENTRY_ACL_READ_DATA |
145 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
146 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
147 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
148 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
149 	    ARCHIVE_ENTRY_ACL_READ_ACL |
150 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
151 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
152 	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
153 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
154 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
155 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
156 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
157 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
158 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER,
159 	  ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
160 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
161 	    ARCHIVE_ENTRY_ACL_READ_DATA |
162 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
163 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
164 	    ARCHIVE_ENTRY_ACL_READ_ACL |
165 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
166 	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
167 };
168 
169 static struct archive_test_acl_t acls5[] = {
170 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
171 	    ARCHIVE_ENTRY_ACL_READ_DATA |
172 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
173 	    ARCHIVE_ENTRY_ACL_EXECUTE |
174 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
175 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
176 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
177 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
178 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
179 	    ARCHIVE_ENTRY_ACL_READ_ACL |
180 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
181 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
182 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
183 	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
184 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
185 	    ARCHIVE_ENTRY_ACL_READ_DATA |
186 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
187 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
188 	    ARCHIVE_ENTRY_ACL_READ_ACL |
189 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
190 	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
191 	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
192 	  ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
193 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
194 	    ARCHIVE_ENTRY_ACL_READ_DATA |
195 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
196 	    ARCHIVE_ENTRY_ACL_EXECUTE |
197 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
198 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
199 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
200 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
201 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
202 	    ARCHIVE_ENTRY_ACL_READ_ACL |
203 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
204 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
205 	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
206 	    ARCHIVE_ENTRY_ACL_READ_DATA |
207 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
208 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
209 	    ARCHIVE_ENTRY_ACL_EXECUTE |
210 	    ARCHIVE_ENTRY_ACL_DELETE |
211 	    ARCHIVE_ENTRY_ACL_DELETE_CHILD |
212 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
213 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
214 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
215 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
216 	    ARCHIVE_ENTRY_ACL_READ_ACL |
217 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
218 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER |
219 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
220 	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
221 	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
222 	  ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
223 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
224 	    ARCHIVE_ENTRY_ACL_READ_DATA |
225 	    ARCHIVE_ENTRY_ACL_EXECUTE |
226 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
227 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
228 	    ARCHIVE_ENTRY_ACL_READ_ACL |
229 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
230 	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
231 };
232 
233 DEFINE_TEST(test_compat_star_acl_posix1e)
234 {
235 	char name[] = "test_compat_star_acl_posix1e.tar";
236 	struct archive *a;
237 	struct archive_entry *ae;
238 
239 	/* Read archive file */
240 	assert(NULL != (a = archive_read_new()));
241         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
242         assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
243         extract_reference_file(name);
244 	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name,
245 	    10240));
246 
247 	/* First item has a few ACLs */
248 	assertA(0 == archive_read_next_header(a, &ae));
249 	failure("One extended ACL should flag all ACLs to be returned.");
250 	assertEqualInt(5, archive_entry_acl_reset(ae,
251 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
252 	archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
253 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142);
254 	failure("Basic ACLs should set mode to 0142, not %04o",
255 	    archive_entry_mode(ae)&0777);
256 	assert((archive_entry_mode(ae) & 0777) == 0142);
257 
258 	/* Second item has pretty extensive ACLs */
259 	assertA(0 == archive_read_next_header(a, &ae));
260 	assertEqualInt(7, archive_entry_acl_reset(ae,
261 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
262 	archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
263 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543);
264 	failure("Basic ACLs should set mode to 0543, not %04o",
265 	    archive_entry_mode(ae)&0777);
266 	assert((archive_entry_mode(ae) & 0777) == 0543);
267 
268 	/* Third item has default ACLs */
269 	assertA(0 == archive_read_next_header(a, &ae));
270 	assertEqualInt(6, archive_entry_acl_reset(ae,
271 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
272 	archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
273 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0142);
274 	failure("Basic ACLs should set mode to 0142, not %04o",
275 	    archive_entry_mode(ae)&0777);
276 	assert((archive_entry_mode(ae) & 0777) == 0142);
277 
278 	/* Close the archive. */
279 	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
280 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
281 }
282 
283 DEFINE_TEST(test_compat_star_acl_nfs4)
284 {
285 	char name[] = "test_compat_star_acl_nfs4.tar";
286 	struct archive *a;
287 	struct archive_entry *ae;
288 
289 	/* Read archive file */
290 	assert(NULL != (a = archive_read_new()));
291 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
292 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
293 	extract_reference_file(name);
294 	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240
295 ));
296 
297 	/* First item has NFS4 ACLs mirroring file mode */
298 	assertA(0 == archive_read_next_header(a, &ae));
299 	assertEqualInt(3, archive_entry_acl_reset(ae,
300 	    ARCHIVE_ENTRY_ACL_TYPE_ALLOW));
301 	archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
302 	    ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0);
303 
304 	/* Second item has has fine-grained NFS4 ACLs */
305 	assertA(0 == archive_read_next_header(a, &ae));
306 	assertEqualInt(6, archive_entry_acl_reset(ae,
307 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
308 	archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
309 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
310 
311 	/* Third item has file and directory inheritance NFS4 ACLs */
312 	assertA(0 == archive_read_next_header(a, &ae));
313 	assertEqualInt(5, archive_entry_acl_reset(ae,
314 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
315 	archive_test_compare_acls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]),
316 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
317 
318 	/* Close the archive. */
319 	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
320 	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
321 }
322