1 /*-
2  * Copyright (c) 2016 Martin Matuska
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include "test.h"
26 __FBSDID("$FreeBSD$");
27 
28 /*
29  * Test converting ACLs to text, both wide and non-wide
30  *
31  * This should work on all systems, regardless of whether local
32  * filesystems support ACLs or not.
33  */
34 
35 static struct archive_test_acl_t acls0[] = {
36 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
37 	    ARCHIVE_ENTRY_ACL_EXECUTE |
38 	    ARCHIVE_ENTRY_ACL_READ |
39 	    ARCHIVE_ENTRY_ACL_WRITE,
40 	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
41 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
42 	    ARCHIVE_ENTRY_ACL_EXECUTE |
43 	    ARCHIVE_ENTRY_ACL_READ,
44 	  ARCHIVE_ENTRY_ACL_USER, 100, "user100" },
45 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
46 	  ARCHIVE_ENTRY_ACL_USER, 1000, "user1000" },
47 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
48 	    ARCHIVE_ENTRY_ACL_EXECUTE |
49 	    ARCHIVE_ENTRY_ACL_READ,
50 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
51 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
52 	    ARCHIVE_ENTRY_ACL_EXECUTE |
53 	    ARCHIVE_ENTRY_ACL_READ |
54 	    ARCHIVE_ENTRY_ACL_WRITE,
55 	  ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
56 	{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
57 	    ARCHIVE_ENTRY_ACL_READ |
58 	    ARCHIVE_ENTRY_ACL_EXECUTE,
59 	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
60 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
61 	    ARCHIVE_ENTRY_ACL_EXECUTE |
62 	    ARCHIVE_ENTRY_ACL_READ,
63 	  ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
64 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
65 	    ARCHIVE_ENTRY_ACL_EXECUTE |
66 	    ARCHIVE_ENTRY_ACL_READ,
67 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
68 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0,
69 	  ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
70 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
71 	    ARCHIVE_ENTRY_ACL_EXECUTE |
72 	    ARCHIVE_ENTRY_ACL_READ,
73 	  ARCHIVE_ENTRY_ACL_USER, 101, "user101"},
74 	{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
75 	    ARCHIVE_ENTRY_ACL_EXECUTE,
76 	  ARCHIVE_ENTRY_ACL_GROUP, 79, "group79" },
77 };
78 
79 static struct archive_test_acl_t acls1[] = {
80 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
81 	    ARCHIVE_ENTRY_ACL_READ_DATA |
82 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
83 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
84 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
85 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
86 	    ARCHIVE_ENTRY_ACL_READ_ACL |
87 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER,
88 	  ARCHIVE_ENTRY_ACL_USER, 77, "user77" },
89 	{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
90 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
91 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
92 	    ARCHIVE_ENTRY_ACL_DELETE_CHILD |
93 	    ARCHIVE_ENTRY_ACL_DELETE |
94 	    ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
95 	    ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT |
96 	    ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY |
97 	    ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
98 	  ARCHIVE_ENTRY_ACL_USER, 101, "user101" },
99 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
100 	    ARCHIVE_ENTRY_ACL_READ_DATA |
101 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
102 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
103 	    ARCHIVE_ENTRY_ACL_READ_ACL |
104 	    ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
105 	  ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" },
106 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
107 	    ARCHIVE_ENTRY_ACL_READ_DATA |
108 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
109 	    ARCHIVE_ENTRY_ACL_EXECUTE |
110 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
111 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
112 	    ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
113 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
114 	    ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
115 	    ARCHIVE_ENTRY_ACL_READ_ACL |
116 	    ARCHIVE_ENTRY_ACL_WRITE_ACL |
117 	    ARCHIVE_ENTRY_ACL_WRITE_OWNER,
118 	  ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
119 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
120 	    ARCHIVE_ENTRY_ACL_READ_DATA |
121 	    ARCHIVE_ENTRY_ACL_WRITE_DATA |
122 	    ARCHIVE_ENTRY_ACL_APPEND_DATA |
123 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
124 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
125 	    ARCHIVE_ENTRY_ACL_READ_ACL,
126 	  ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
127 	{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
128 	    ARCHIVE_ENTRY_ACL_READ_DATA |
129 	    ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
130 	    ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
131 	    ARCHIVE_ENTRY_ACL_READ_ACL |
132 	    ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
133 	  ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
134 };
135 
136 const char* acltext[] = {
137 	"user::rwx\n"
138 	"group::r-x\n"
139 	"other::r-x\n"
140 	"user:user100:r-x\n"
141 	"user:user1000:---\n"
142 	"group:group78:rwx\n"
143 	"default:user::r-x\n"
144 	"default:group::r-x\n"
145 	"default:other::---\n"
146 	"default:user:user101:r-x\n"
147 	"default:group:group79:--x",
148 
149 	"user::rwx\n"
150 	"group::r-x\n"
151 	"other::r-x\n"
152 	"user:user100:r-x:100\n"
153 	"user:user1000:---:1000\n"
154 	"group:group78:rwx:78\n"
155 	"default:user::r-x\n"
156 	"default:group::r-x\n"
157 	"default:other::---\n"
158 	"default:user:user101:r-x:101\n"
159 	"default:group:group79:--x:79",
160 
161 	"u::rwx\n"
162 	"g::r-x\n"
163 	"o::r-x\n"
164 	"u:user100:r-x:100\n"
165 	"u:user1000:---:1000\n"
166 	"g:group78:rwx:78\n"
167 	"d:user::r-x\n"
168 	"d:group::r-x\n"
169 	"d:other::---\n"
170 	"d:user:user101:r-x:101\n"
171 	"d:group:group79:--x:79",
172 
173 	"user::rwx\n"
174 	"group::r-x\n"
175 	"other::r-x\n"
176 	"user:user100:r-x\n"
177 	"user:user1000:---\n"
178 	"group:group78:rwx",
179 
180 	"user::rwx,"
181 	"group::r-x,"
182 	"other::r-x,"
183 	"user:user100:r-x,"
184 	"user:user1000:---,"
185 	"group:group78:rwx",
186 
187 	"user::rwx\n"
188 	"group::r-x\n"
189 	"other::r-x\n"
190 	"user:user100:r-x:100\n"
191 	"user:user1000:---:1000\n"
192 	"group:group78:rwx:78",
193 
194 	"user::r-x\n"
195 	"group::r-x\n"
196 	"other::---\n"
197 	"user:user101:r-x\n"
198 	"group:group79:--x",
199 
200 	"user::r-x\n"
201 	"group::r-x\n"
202 	"other::---\n"
203 	"user:user101:r-x:101\n"
204 	"group:group79:--x:79",
205 
206 	"default:user::r-x\n"
207 	"default:group::r-x\n"
208 	"default:other::---\n"
209 	"default:user:user101:r-x\n"
210 	"default:group:group79:--x",
211 
212 	"user:user77:rw-p--a-R-c-o-:-------:allow\n"
213 	"user:user101:-w-pdD--------:fdin---:deny\n"
214 	"group:group78:r-----a-R-c---:------I:allow\n"
215 	"owner@:rwxp--aARWcCo-:-------:allow\n"
216 	"group@:rw-p--a-R-c---:-------:allow\n"
217 	"everyone@:r-----a-R-c--s:-------:allow",
218 
219 	"user:user77:rw-p--a-R-c-o-:-------:allow:77\n"
220 	"user:user101:-w-pdD--------:fdin---:deny:101\n"
221 	"group:group78:r-----a-R-c---:------I:allow:78\n"
222 	"owner@:rwxp--aARWcCo-:-------:allow\n"
223 	"group@:rw-p--a-R-c---:-------:allow\n"
224 	"everyone@:r-----a-R-c--s:-------:allow",
225 
226 	"user:user77:rwpaRco::allow:77\n"
227 	"user:user101:wpdD:fdin:deny:101\n"
228 	"group:group78:raRc:I:allow:78\n"
229 	"owner@:rwxpaARWcCo::allow\n"
230 	"group@:rwpaRc::allow\n"
231 	"everyone@:raRcs::allow"
232 };
233 
234 static wchar_t *
235 convert_s_to_ws(const char *s)
236 {
237 	size_t len;
238 	wchar_t *ws = NULL;
239 
240 	if (s != NULL) {
241 		len = strlen(s) + 1;
242 		ws = malloc(len * sizeof(wchar_t));
243 		assert(mbstowcs(ws, s, len) != (size_t)-1);
244 	}
245 
246 	return (ws);
247 }
248 
249 static void
250 compare_acl_text(struct archive_entry *ae, int flags, const char *s)
251 {
252 	char *text;
253 	wchar_t *wtext;
254 	wchar_t *ws;
255 	ssize_t slen;
256 
257 	ws = convert_s_to_ws(s);
258 
259 	text = archive_entry_acl_to_text(ae, &slen, flags);
260 	assertEqualString(text, s);
261 	if (text != NULL)
262 		assertEqualInt(strlen(text), slen);
263 	wtext = archive_entry_acl_to_text_w(ae, &slen, flags);
264 	assertEqualWString(wtext, ws);
265 	if (wtext != NULL) {
266 		assertEqualInt(wcslen(wtext), slen);
267 	}
268 	free(text);
269 	free(wtext);
270 	free(ws);
271 }
272 
273 DEFINE_TEST(test_acl_from_text)
274 {
275 	struct archive_entry *ae;
276 	wchar_t *ws = NULL;
277 
278 	/* Create an empty archive_entry. */
279 	assert((ae = archive_entry_new()) != NULL);
280 
281 	/* 1a. Read POSIX.1e access ACLs from text */
282 	assertEqualInt(ARCHIVE_OK,
283 	    archive_entry_acl_from_text(ae, acltext[5],
284 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
285 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
286 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0755);
287 	assertEqualInt(6, archive_entry_acl_reset(ae,
288 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
289 
290 	/* 1b. Now read POSIX.1e default ACLs and append them */
291 	assertEqualInt(ARCHIVE_OK,
292 	    archive_entry_acl_from_text(ae, acltext[7],
293 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
294 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
295 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
296 	assertEqualInt(11, archive_entry_acl_reset(ae,
297 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
298 	archive_entry_acl_clear(ae);
299 
300 	/* 1a and 1b with wide strings */
301 	ws = convert_s_to_ws(acltext[5]);
302 
303 	assertEqualInt(ARCHIVE_OK,
304 	    archive_entry_acl_from_text_w(ae, ws,
305 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
306 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
307 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0755);
308 	assertEqualInt(6, archive_entry_acl_reset(ae,
309 	    ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
310 
311 	free(ws);
312 	ws = convert_s_to_ws(acltext[7]);
313 
314 	assertEqualInt(ARCHIVE_OK,
315 	    archive_entry_acl_from_text_w(ae, ws,
316 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
317 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
318 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
319 	assertEqualInt(11, archive_entry_acl_reset(ae,
320 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
321 	archive_entry_acl_clear(ae);
322 
323 	/* 2. Read POSIX.1e default ACLs from text */
324 	assertEqualInt(ARCHIVE_OK,
325 	    archive_entry_acl_from_text(ae, acltext[7],
326 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
327 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
328 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0);
329 	assertEqualInt(5, archive_entry_acl_reset(ae,
330 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
331 	archive_entry_acl_clear(ae);
332 
333 	/* ws is still acltext[7] */
334 	assertEqualInt(ARCHIVE_OK,
335 	    archive_entry_acl_from_text_w(ae, ws,
336 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
337 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
338 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0);
339 	assertEqualInt(5, archive_entry_acl_reset(ae,
340 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
341 	archive_entry_acl_clear(ae);
342 
343 	/* 3. Read POSIX.1e access and default ACLs from text */
344 	assertEqualInt(ARCHIVE_OK,
345 	    archive_entry_acl_from_text(ae, acltext[1],
346 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
347 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
348 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
349 	assertEqualInt(11, archive_entry_acl_reset(ae,
350 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
351 	archive_entry_acl_clear(ae);
352 
353 	free(ws);
354 	ws = convert_s_to_ws(acltext[1]);
355 	assertEqualInt(ARCHIVE_OK,
356 	    archive_entry_acl_from_text_w(ae, ws,
357 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
358 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
359 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
360 	assertEqualInt(11, archive_entry_acl_reset(ae,
361 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
362 	archive_entry_acl_clear(ae);
363 
364 	/* 4. Read POSIX.1e access and default ACLs from text (short form) */
365 	assertEqualInt(ARCHIVE_OK,
366 	    archive_entry_acl_from_text(ae, acltext[2],
367 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
368 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
369 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
370 	assertEqualInt(11, archive_entry_acl_reset(ae,
371 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
372 	archive_entry_acl_clear(ae);
373 
374 	free(ws);
375 	ws = convert_s_to_ws(acltext[2]);
376 	assertEqualInt(ARCHIVE_OK,
377 	    archive_entry_acl_from_text_w(ae, ws,
378 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
379 	assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
380 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755);
381 	assertEqualInt(11, archive_entry_acl_reset(ae,
382 	    ARCHIVE_ENTRY_ACL_TYPE_POSIX1E));
383 	archive_entry_acl_clear(ae);
384 
385 	/* 5. Read NFSv4 ACLs from text */
386 	assertEqualInt(ARCHIVE_OK,
387 	    archive_entry_acl_from_text(ae, acltext[10],
388 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
389 	assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
390 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
391 	assertEqualInt(6, archive_entry_acl_reset(ae,
392 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
393 	archive_entry_acl_clear(ae);
394 
395 	free(ws);
396 	ws = convert_s_to_ws(acltext[10]);
397 
398 	assertEqualInt(ARCHIVE_OK,
399 	    archive_entry_acl_from_text_w(ae, ws,
400 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
401 	assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
402 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
403 	assertEqualInt(6, archive_entry_acl_reset(ae,
404 	    ARCHIVE_ENTRY_ACL_TYPE_NFS4));
405 	archive_entry_acl_clear(ae);
406 
407 	free(ws);
408 	archive_entry_free(ae);
409 }
410 
411 DEFINE_TEST(test_acl_to_text)
412 {
413 	struct archive_entry *ae;
414 
415 	/* Create an empty archive_entry. */
416 	assert((ae = archive_entry_new()) != NULL);
417 
418 	/* Write POSIX.1e ACLs  */
419 	assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]));
420 
421 	/* No flags should give output like getfacl(1) on linux */
422 	compare_acl_text(ae, 0, acltext[0]);
423 
424 	/* This should give the same output as previous test */
425 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
426 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, acltext[0]);
427 
428 	/* This should give the same output as previous two tests */
429 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
430 	    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
431 	    ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT, acltext[0]);
432 
433 	/* POSIX.1e access and default ACLs with appended ID */
434 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[1]);
435 
436 	/* POSIX.1e access acls only, like getfacl(1) on FreeBSD */
437 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, acltext[3]);
438 
439 	/* POSIX.1e access acls separated with comma */
440 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
441 	    ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA,
442 	    acltext[4]);
443 
444 	/* POSIX.1e access acls with appended user or group ID */
445 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
446 	    ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[5]);
447 
448 	/* POSIX.1e default acls */
449 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, acltext[6]);
450 
451 	/* POSIX.1e default acls with appended user or group ID */
452 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
453 	    ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[7]);
454 
455 	/* POSIX.1e default acls prefixed with default: */
456 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
457 	    ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT, acltext[8]);
458 
459 	/* Write NFSv4 ACLs */
460 	assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]));
461 
462 	/* NFSv4 ACLs like getfacl(1) on FreeBSD */
463 	compare_acl_text(ae, 0, acltext[9]);
464 
465 	/* NFSv4 ACLs like "getfacl -i" on FreeBSD */
466 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[10]);
467 
468 	/* NFSv4 ACLs like "getfacl -i" on FreeBSD with stripped minus chars */
469 	compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
470 	    ARCHIVE_ENTRY_ACL_STYLE_COMPACT, acltext[11]);
471 
472 	archive_entry_free(ae);
473 }
474