2 * Copyright (c) 2003-2010 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
26 __FBSDID("$FreeBSD$");
28 #if defined(__FreeBSD__) && __FreeBSD__ >= 8
36 int qual; /* GID or UID of user/group, depending on tag. */
37 const char *name; /* Name of user/group, depending on tag. */
40 static struct myacl_t acls_reg[] = {
41 /* For this test, we need the file owner to be able to read and write the ACL. */
42 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
43 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
44 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
46 /* An entry for each type. */
47 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
48 ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
49 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
50 ARCHIVE_ENTRY_ACL_USER, 109, "user109" },
52 /* An entry for each permission. */
53 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
54 ARCHIVE_ENTRY_ACL_USER, 112, "user112" },
55 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA,
56 ARCHIVE_ENTRY_ACL_USER, 113, "user113" },
57 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA,
58 ARCHIVE_ENTRY_ACL_USER, 115, "user115" },
59 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA,
60 ARCHIVE_ENTRY_ACL_USER, 117, "user117" },
61 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
62 ARCHIVE_ENTRY_ACL_USER, 119, "user119" },
63 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
64 ARCHIVE_ENTRY_ACL_USER, 120, "user120" },
65 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
66 ARCHIVE_ENTRY_ACL_USER, 122, "user122" },
67 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
68 ARCHIVE_ENTRY_ACL_USER, 123, "user123" },
69 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
70 ARCHIVE_ENTRY_ACL_USER, 124, "user124" },
71 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
72 ARCHIVE_ENTRY_ACL_USER, 125, "user125" },
73 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
74 ARCHIVE_ENTRY_ACL_USER, 126, "user126" },
75 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
76 ARCHIVE_ENTRY_ACL_USER, 127, "user127" },
77 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
78 ARCHIVE_ENTRY_ACL_USER, 128, "user128" },
80 /* One entry for each qualifier. */
81 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
82 ARCHIVE_ENTRY_ACL_USER, 135, "user135" },
83 // { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
84 // ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
85 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
86 ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" },
87 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
88 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
89 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
90 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
94 static struct myacl_t acls_dir[] = {
95 /* For this test, we need to be able to read and write the ACL. */
96 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
97 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
99 /* An entry for each type. */
100 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
101 ARCHIVE_ENTRY_ACL_USER, 101, "user101" },
102 { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
103 ARCHIVE_ENTRY_ACL_USER, 102, "user102" },
105 /* An entry for each permission. */
106 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
107 ARCHIVE_ENTRY_ACL_USER, 201, "user201" },
108 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE,
109 ARCHIVE_ENTRY_ACL_USER, 202, "user202" },
110 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
111 ARCHIVE_ENTRY_ACL_USER, 203, "user203" },
112 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS,
113 ARCHIVE_ENTRY_ACL_USER, 204, "user204" },
114 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS,
115 ARCHIVE_ENTRY_ACL_USER, 205, "user205" },
116 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD,
117 ARCHIVE_ENTRY_ACL_USER, 206, "user206" },
118 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
119 ARCHIVE_ENTRY_ACL_USER, 207, "user207" },
120 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES,
121 ARCHIVE_ENTRY_ACL_USER, 208, "user208" },
122 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE,
123 ARCHIVE_ENTRY_ACL_USER, 209, "user209" },
124 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL,
125 ARCHIVE_ENTRY_ACL_USER, 210, "user210" },
126 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL,
127 ARCHIVE_ENTRY_ACL_USER, 211, "user211" },
128 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER,
129 ARCHIVE_ENTRY_ACL_USER, 212, "user212" },
130 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
131 ARCHIVE_ENTRY_ACL_USER, 213, "user213" },
133 /* One entry with each inheritance value. */
134 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
135 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT,
136 ARCHIVE_ENTRY_ACL_USER, 301, "user301" },
137 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
138 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
139 ARCHIVE_ENTRY_ACL_USER, 302, "user302" },
141 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
142 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT,
143 ARCHIVE_ENTRY_ACL_USER, 303, "user303" },
144 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
145 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
146 ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
150 /* FreeBSD does not support audit entries. */
151 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
152 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS,
153 ARCHIVE_ENTRY_ACL_USER, 401, "user401" },
154 { ARCHIVE_ENTRY_ACL_TYPE_AUDIT,
155 ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS,
156 ARCHIVE_ENTRY_ACL_USER, 402, "user402" },
159 /* One entry for each qualifier. */
160 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
161 ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
162 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
163 ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
164 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
165 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
166 { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
167 ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
171 set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
175 archive_entry_acl_clear(ae);
177 assertEqualInt(ARCHIVE_OK,
178 archive_entry_acl_add_entry(ae,
179 acls[0].type, acls[0].permset, acls[0].tag,
180 acls[0].qual, acls[0].name));
182 for (i = start; i < end; i++) {
183 assertEqualInt(ARCHIVE_OK,
184 archive_entry_acl_add_entry(ae,
185 acls[i].type, acls[i].permset, acls[i].tag,
186 acls[i].qual, acls[i].name));
191 acl_permset_to_bitmap(acl_permset_t opaque_ps)
193 static struct { int machine; int portable; } perms[] = {
194 {ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
195 {ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
196 {ACL_READ, ARCHIVE_ENTRY_ACL_READ},
197 {ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
198 {ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
199 {ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
200 {ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
201 {ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
202 {ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
203 {ACL_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
204 {ACL_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
205 {ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
206 {ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
207 {ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
208 {ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
209 {ACL_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
210 {ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
211 {ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
212 {ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
216 for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
217 if (acl_get_perm_np(opaque_ps, perms[i].machine))
218 permset |= perms[i].portable;
223 acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
225 static struct { int machine; int portable; } flags[] = {
226 {ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
227 {ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
228 {ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
229 {ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
233 for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
234 if (acl_get_flag_np(opaque_fs, flags[i].machine))
235 flagset |= flags[i].portable;
240 acl_match(acl_entry_t aclent, struct myacl_t *myacl)
245 acl_permset_t opaque_ps;
246 acl_flagset_t opaque_fs;
249 acl_get_tag_type(aclent, &tag_type);
251 /* translate the silly opaque permset to a bitmap */
252 acl_get_permset(aclent, &opaque_ps);
253 acl_get_flagset_np(aclent, &opaque_fs);
254 perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
255 if (perms != myacl->permset)
260 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
263 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
265 up = acl_get_qualifier(aclent);
268 if ((uid_t)myacl->qual != u)
272 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
275 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
277 gp = acl_get_qualifier(aclent);
280 if ((gid_t)myacl->qual != g)
284 if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
287 if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
294 compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start, int end)
297 int entry_id = ACL_FIRST_ENTRY;
300 acl_entry_t acl_entry;
303 marker = malloc(sizeof(marker[0]) * (n + 1));
304 for (i = 0; i < n; i++)
305 marker[i] = i + start;
306 /* Always include the first ACE. */
313 * Iterate over acls in system acl object, try to match each
314 * one with an item in the myacls array.
316 while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
317 /* After the first time... */
318 entry_id = ACL_NEXT_ENTRY;
320 /* Search for a matching entry (tag and qualifier) */
321 for (i = 0, matched = 0; i < n && !matched; i++) {
322 if (acl_match(acl_entry, &myacls[marker[i]])) {
323 /* We found a match; remove it. */
324 marker[i] = marker[n - 1];
330 failure("ACL entry on file %s that shouldn't be there", filename);
331 assert(matched == 1);
334 /* Dump entries in the myacls array that weren't in the system acl. */
335 for (i = 0; i < n; ++i) {
336 failure(" ACL entry %d missing from %s: "
337 "type=%d,permset=%x,tag=%d,qual=%d,name=``%s''\n",
339 myacls[marker[i]].type, myacls[marker[i]].permset,
340 myacls[marker[i]].tag, myacls[marker[i]].qual,
341 myacls[marker[i]].name);
342 assert(0); /* Record this as a failure. */
348 compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char *filename, int start, int end)
353 int type, permset, tag, qual;
356 /* Count ACL entries in myacls array and allocate an indirect array. */
358 marker = malloc(sizeof(marker[0]) * (n + 1));
359 for (i = 0; i < n; i++)
360 marker[i] = i + start;
361 /* Always include the first ACE. */
368 * Iterate over acls in entry, try to match each
369 * one with an item in the myacls array.
371 assertEqualInt(n, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
372 while (ARCHIVE_OK == archive_entry_acl_next(ae,
373 ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) {
375 /* Search for a matching entry (tag and qualifier) */
376 for (i = 0, matched = 0; i < n && !matched; i++) {
377 if (tag == myacls[marker[i]].tag
378 && qual == myacls[marker[i]].qual
379 && permset == myacls[marker[i]].permset
380 && type == myacls[marker[i]].type) {
381 /* We found a match; remove it. */
382 marker[i] = marker[n - 1];
388 failure("ACL entry on file that shouldn't be there: "
389 "type=%d,permset=%x,tag=%d,qual=%d",
390 type,permset,tag,qual);
391 assert(matched == 1);
394 /* Dump entries in the myacls array that weren't in the system acl. */
395 for (i = 0; i < n; ++i) {
396 failure(" ACL entry %d missing from %s: "
397 "type=%d,permset=%x,tag=%d,qual=%d,name=``%s''\n",
399 myacls[marker[i]].type, myacls[marker[i]].permset,
400 myacls[marker[i]].tag, myacls[marker[i]].qual,
401 myacls[marker[i]].name);
402 assert(0); /* Record this as a failure. */
409 * Verify ACL restore-to-disk. This test is FreeBSD-specific.
412 DEFINE_TEST(test_acl_freebsd_nfs4)
414 #if !defined(__FreeBSD__)
415 skipping("FreeBSD-specific NFS4 ACL restore test");
416 #elif __FreeBSD__ < 8
417 skipping("NFS4 ACLs supported only on FreeBSD 8.0 and later");
422 struct archive_entry *ae;
427 * First, do a quick manual set/read of ACL data to
428 * verify that the local filesystem does support ACLs.
429 * If it doesn't, we'll simply skip the remaining tests.
431 acl = acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
432 assert((void *)acl != NULL);
433 /* Create a test dir and try to set an ACL on it. */
434 if (!assertMakeDir("pretest", 0755)) {
439 n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
441 if (n != 0 && errno == EOPNOTSUPP) {
442 skipping("NFS4 ACL tests require that NFS4 ACLs"
443 " be enabled on the filesystem");
446 if (n != 0 && errno == EINVAL) {
447 skipping("This filesystem does not support NFS4 ACLs");
450 failure("acl_set_file(): errno = %d (%s)",
451 errno, strerror(errno));
452 assertEqualInt(0, n);
454 /* Create a write-to-disk object. */
455 assert(NULL != (a = archive_write_disk_new()));
456 archive_write_disk_set_options(a,
457 ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL);
459 /* Populate an archive entry with some metadata, including ACL info */
460 ae = archive_entry_new();
462 archive_entry_set_pathname(ae, "testall");
463 archive_entry_set_filetype(ae, AE_IFREG);
464 archive_entry_set_perm(ae, 0654);
465 archive_entry_set_mtime(ae, 123456, 7890);
466 archive_entry_set_size(ae, 0);
467 set_acls(ae, acls_reg, 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
469 /* Write the entry to disk, including ACLs. */
470 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
472 /* Likewise for a dir. */
473 archive_entry_set_pathname(ae, "dirall");
474 archive_entry_set_filetype(ae, AE_IFDIR);
475 archive_entry_set_perm(ae, 0654);
476 archive_entry_set_mtime(ae, 123456, 7890);
477 set_acls(ae, acls_dir, 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
478 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
480 for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
481 sprintf(buff, "dir%d", i);
482 archive_entry_set_pathname(ae, buff);
483 archive_entry_set_filetype(ae, AE_IFDIR);
484 archive_entry_set_perm(ae, 0654);
485 archive_entry_set_mtime(ae, 123456 + i, 7891 + i);
486 set_acls(ae, acls_dir, i, i + 1);
487 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
490 archive_entry_free(ae);
492 /* Close the archive. */
493 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
494 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
496 /* Verify the data on disk. */
497 assertEqualInt(0, stat("testall", &st));
498 assertEqualInt(st.st_mtime, 123456);
499 acl = acl_get_file("testall", ACL_TYPE_NFS4);
500 assert(acl != (acl_t)NULL);
501 compare_acls(acl, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
504 /* Verify single-permission dirs on disk. */
505 for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
506 sprintf(buff, "dir%d", i);
507 assertEqualInt(0, stat(buff, &st));
508 assertEqualInt(st.st_mtime, 123456 + i);
509 acl = acl_get_file(buff, ACL_TYPE_NFS4);
510 assert(acl != (acl_t)NULL);
511 compare_acls(acl, acls_dir, buff, i, i + 1);
515 /* Verify "dirall" on disk. */
516 assertEqualInt(0, stat("dirall", &st));
517 assertEqualInt(st.st_mtime, 123456);
518 acl = acl_get_file("dirall", ACL_TYPE_NFS4);
519 assert(acl != (acl_t)NULL);
520 compare_acls(acl, acls_dir, "dirall", 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
523 /* Read and compare ACL via archive_read_disk */
524 a = archive_read_disk_new();
526 ae = archive_entry_new();
528 archive_entry_set_pathname(ae, "testall");
529 assertEqualInt(ARCHIVE_OK,
530 archive_read_disk_entry_from_file(a, ae, -1, NULL));
531 compare_entry_acls(ae, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
532 archive_entry_free(ae);
533 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
535 /* Read and compare ACL via archive_read_disk */
536 a = archive_read_disk_new();
538 ae = archive_entry_new();
540 archive_entry_set_pathname(ae, "dirall");
541 assertEqualInt(ARCHIVE_OK,
542 archive_read_disk_entry_from_file(a, ae, -1, NULL));
543 compare_entry_acls(ae, acls_dir, "dirall", 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
544 archive_entry_free(ae);
545 assertEqualInt(ARCHIVE_OK, archive_read_free(a));