test_acl_platform_posix1e.c revision 316337
1/*- 2 * Copyright (c) 2003-2008 Tim Kientzle 3 * Copyright (c) 2017 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: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $"); 28 29#if ARCHIVE_ACL_POSIX1E 30#include <sys/acl.h> 31#if HAVE_ACL_GET_PERM 32#include <acl/libacl.h> 33#define ACL_GET_PERM acl_get_perm 34#elif HAVE_ACL_GET_PERM_NP 35#define ACL_GET_PERM acl_get_perm_np 36#endif 37 38static struct archive_test_acl_t acls2[] = { 39 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ, 40 ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, 41 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 42 ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, 43 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0, 44 ARCHIVE_ENTRY_ACL_USER, 78, "user78" }, 45 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, 46 ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, 47 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007, 48 ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, 49 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 50 ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE, 51 ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, 52 { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 53 ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EXECUTE, 54 ARCHIVE_ENTRY_ACL_MASK, -1, "" }, 55}; 56 57static int 58#if ARCHIVE_ACL_SUNOS 59acl_entry_get_perm(aclent_t *aclent) 60#else 61acl_entry_get_perm(acl_entry_t aclent) 62#endif 63{ 64 int permset = 0; 65#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL 66 acl_permset_t opaque_ps; 67#endif 68 69#if ARCHIVE_ACL_SUNOS 70 if (aclent->a_perm & 1) 71 permset |= ARCHIVE_ENTRY_ACL_EXECUTE; 72 if (aclent->a_perm & 2) 73 permset |= ARCHIVE_ENTRY_ACL_WRITE; 74 if (aclent->a_perm & 4) 75 permset |= ARCHIVE_ENTRY_ACL_READ; 76#else 77 /* translate the silly opaque permset to a bitmap */ 78 acl_get_permset(aclent, &opaque_ps); 79 if (ACL_GET_PERM(opaque_ps, ACL_EXECUTE)) 80 permset |= ARCHIVE_ENTRY_ACL_EXECUTE; 81 if (ACL_GET_PERM(opaque_ps, ACL_WRITE)) 82 permset |= ARCHIVE_ENTRY_ACL_WRITE; 83 if (ACL_GET_PERM(opaque_ps, ACL_READ)) 84 permset |= ARCHIVE_ENTRY_ACL_READ; 85#endif 86 return permset; 87} 88 89#if 0 90static int 91acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_tag) { 92 int entry_id = ACL_FIRST_ENTRY; 93 acl_entry_t acl_entry; 94 acl_tag_t acl_tag_type; 95 96 while (1 == acl_get_entry(acl, entry_id, &acl_entry)) { 97 /* After the first time... */ 98 entry_id = ACL_NEXT_ENTRY; 99 100 /* If this matches, return perm mask */ 101 acl_get_tag_type(acl_entry, &acl_tag_type); 102 if (acl_tag_type == requested_tag_type) { 103 switch (acl_tag_type) { 104 case ACL_USER_OBJ: 105 if ((uid_t)requested_tag == *(uid_t *)(acl_get_qualifier(acl_entry))) { 106 return acl_entry_get_perm(acl_entry); 107 } 108 break; 109 case ACL_GROUP_OBJ: 110 if ((gid_t)requested_tag == *(gid_t *)(acl_get_qualifier(acl_entry))) { 111 return acl_entry_get_perm(acl_entry); 112 } 113 break; 114 case ACL_USER: 115 case ACL_GROUP: 116 case ACL_OTHER: 117 return acl_entry_get_perm(acl_entry); 118 default: 119 failure("Unexpected ACL tag type"); 120 assert(0); 121 } 122 } 123 124 125 } 126 return -1; 127} 128#endif 129 130#if ARCHIVE_ACL_SUNOS 131static int 132acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl) 133{ 134 135 if (myacl->permset != acl_entry_get_perm(aclent)) 136 return (0); 137 138 switch (aclent->a_type) { 139 case DEF_USER_OBJ: 140 case USER_OBJ: 141 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0); 142 break; 143 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 144 return (0); 145 if ((uid_t)myacl->qual != aclent->a_id) 146 return (0); 147 break; 148 case DEF_GROUP_OBJ: 149 case GROUP_OBJ: 150 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0); 151 break; 152 case DEF_GROUP: 153 case GROUP: 154 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 155 return (0); 156 if ((gid_t)myacl->qual != aclent->a_id) 157 return (0); 158 break; 159 case DEF_CLASS_OBJ: 160 case CLASS_OBJ: 161 if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0); 162 break; 163 case DEF_OTHER_OBJ: 164 case OTHER_OBJ: 165 if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0); 166 break; 167 } 168 return (1); 169} 170 171#else /* ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL */ 172static int 173acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl) 174{ 175 gid_t g, *gp; 176 uid_t u, *up; 177 acl_tag_t tag_type; 178 179 if (myacl->permset != acl_entry_get_perm(aclent)) 180 return (0); 181 182 acl_get_tag_type(aclent, &tag_type); 183 switch (tag_type) { 184 case ACL_USER_OBJ: 185 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0); 186 break; 187 case ACL_USER: 188 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 189 return (0); 190 up = acl_get_qualifier(aclent); 191 u = *up; 192 acl_free(up); 193 if ((uid_t)myacl->qual != u) 194 return (0); 195 break; 196 case ACL_GROUP_OBJ: 197 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0); 198 break; 199 case ACL_GROUP: 200 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 201 return (0); 202 gp = acl_get_qualifier(aclent); 203 g = *gp; 204 acl_free(gp); 205 if ((gid_t)myacl->qual != g) 206 return (0); 207 break; 208 case ACL_MASK: 209 if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0); 210 break; 211 case ACL_OTHER: 212 if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0); 213 break; 214 } 215 return (1); 216} 217#endif 218 219static void 220compare_acls( 221#if ARCHIVE_ACL_SUNOS 222 void *aclp, int aclcnt, 223#else 224 acl_t acl, 225#endif 226 struct archive_test_acl_t *myacls, int n) 227{ 228 int *marker; 229 int matched; 230 int i; 231#if ARCHIVE_ACL_SUNOS 232 int e; 233 aclent_t *acl_entry; 234#else 235 int entry_id = ACL_FIRST_ENTRY; 236 acl_entry_t acl_entry; 237#endif 238 239 /* Count ACL entries in myacls array and allocate an indirect array. */ 240 marker = malloc(sizeof(marker[0]) * n); 241 if (marker == NULL) 242 return; 243 for (i = 0; i < n; i++) 244 marker[i] = i; 245 246 /* 247 * Iterate over acls in system acl object, try to match each 248 * one with an item in the myacls array. 249 */ 250#if ARCHIVE_ACL_SUNOS 251 for(e = 0; e < aclcnt; e++) { 252 acl_entry = &((aclent_t *)aclp)[e]; 253#else 254 while (1 == acl_get_entry(acl, entry_id, &acl_entry)) { 255 /* After the first time... */ 256 entry_id = ACL_NEXT_ENTRY; 257#endif 258 259 /* Search for a matching entry (tag and qualifier) */ 260 for (i = 0, matched = 0; i < n && !matched; i++) { 261 if (acl_match(acl_entry, &myacls[marker[i]])) { 262 /* We found a match; remove it. */ 263 marker[i] = marker[n - 1]; 264 n--; 265 matched = 1; 266 } 267 } 268 269 /* TODO: Print out more details in this case. */ 270 failure("ACL entry on file that shouldn't be there"); 271 assert(matched == 1); 272 } 273 274 /* Dump entries in the myacls array that weren't in the system acl. */ 275 for (i = 0; i < n; ++i) { 276 failure(" ACL entry missing from file: " 277 "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", 278 myacls[marker[i]].type, myacls[marker[i]].permset, 279 myacls[marker[i]].tag, myacls[marker[i]].qual, 280 myacls[marker[i]].name); 281 assert(0); /* Record this as a failure. */ 282 } 283 free(marker); 284} 285#endif 286 287/* 288 * Verify ACL restore-to-disk. This test is Platform-specific. 289 */ 290 291DEFINE_TEST(test_acl_platform_posix1e_restore) 292{ 293#if !ARCHIVE_ACL_POSIX1E 294 skipping("POSIX.1e ACLs are not supported on this platform"); 295#else /* ARCHIVE_ACL_POSIX1E */ 296 struct stat st; 297 struct archive *a; 298 struct archive_entry *ae; 299#if ARCHIVE_ACL_SUNOS 300 void *aclp; 301 int aclcnt; 302#else 303 acl_t acl; 304#endif 305 306 assertMakeFile("pretest", 0644, "a"); 307 308 if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_POSIX1E) { 309 skipping("POSIX.1e ACLs are not writable on this filesystem"); 310 return; 311 } 312 313 /* Create a write-to-disk object. */ 314 assert(NULL != (a = archive_write_disk_new())); 315 archive_write_disk_set_options(a, 316 ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL); 317 318 /* Populate an archive entry with some metadata, including ACL info */ 319 ae = archive_entry_new(); 320 assert(ae != NULL); 321 archive_entry_set_pathname(ae, "test0"); 322 archive_entry_set_mtime(ae, 123456, 7890); 323 archive_entry_set_size(ae, 0); 324 assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); 325 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 326 archive_entry_free(ae); 327 328 /* Close the archive. */ 329 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 330 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 331 332 /* Verify the data on disk. */ 333 assertEqualInt(0, stat("test0", &st)); 334 assertEqualInt(st.st_mtime, 123456); 335#if ARCHIVE_ACL_SUNOS 336 aclp = sunacl_get(GETACL, &aclcnt, 0, "test0"); 337 failure("acl(): errno = %d (%s)", errno, strerror(errno)); 338 assert(aclp != NULL); 339#else 340 acl = acl_get_file("test0", ACL_TYPE_ACCESS); 341 failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno)); 342 assert(acl != (acl_t)NULL); 343#endif 344#if ARCHIVE_ACL_SUNOS 345 compare_acls(aclp, aclcnt, acls2, sizeof(acls2)/sizeof(acls2[0])); 346 free(aclp); 347 aclp = NULL; 348#else 349 compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0])); 350 acl_free(acl); 351#endif 352 353#endif /* ARCHIVE_ACL_POSIX1E */ 354} 355 356/* 357 * Verify ACL read-from-disk. This test is Platform-specific. 358 */ 359DEFINE_TEST(test_acl_platform_posix1e_read) 360{ 361#if !ARCHIVE_ACL_POSIX1E 362 skipping("POSIX.1e ACLs are not supported on this platform"); 363#else /* ARCHIVE_ACL_POSIX1E */ 364 struct archive *a; 365 struct archive_entry *ae; 366 int n, fd, flags, dflags; 367 char *func, *acl_text; 368 const char *acl1_text, *acl2_text, *acl3_text; 369#if ARCHIVE_ACL_SUNOS 370 void *aclp; 371 int aclcnt; 372#else 373 acl_t acl1, acl2, acl3; 374#endif 375 376 /* 377 * Manually construct a directory and two files with 378 * different ACLs. This also serves to verify that ACLs 379 * are supported on the local filesystem. 380 */ 381 382 /* Create a test file f1 with acl1 */ 383#if ARCHIVE_ACL_SUNOS 384 acl1_text = "user::rwx," 385 "group::rwx," 386 "other:rwx," 387 "user:1:rw-," 388 "group:15:r-x," 389 "mask:rwx"; 390 aclent_t aclp1[] = { 391 { USER_OBJ, -1, 4 | 2 | 1 }, 392 { USER, 1, 4 | 2 }, 393 { GROUP_OBJ, -1, 4 | 2 | 1 }, 394 { GROUP, 15, 4 | 1 }, 395 { CLASS_OBJ, -1, 4 | 2 | 1 }, 396 { OTHER_OBJ, -1, 4 | 2 | 1 } 397 }; 398#else 399 acl1_text = "user::rwx\n" 400 "group::rwx\n" 401 "other::rwx\n" 402 "user:1:rw-\n" 403 "group:15:r-x\n" 404 "mask::rwx"; 405 acl1 = acl_from_text(acl1_text); 406 failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); 407 assert((void *)acl1 != NULL); 408#endif 409 fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777); 410 failure("Could not create test file?!"); 411 if (!assert(fd >= 0)) { 412#if !ARCHIVE_ACL_SUNOS 413 acl_free(acl1); 414#endif 415 return; 416 } 417#if ARCHIVE_ACL_SUNOS 418 /* Check if Solaris filesystem supports POSIX.1e ACLs */ 419 aclp = sunacl_get(GETACL, &aclcnt, fd, NULL); 420 if (aclp == 0) 421 close(fd); 422 if (errno == ENOSYS || errno == ENOTSUP) { 423 skipping("POSIX.1e ACLs are not supported on this filesystem"); 424 return; 425 } 426 failure("facl(): errno = %d (%s)", errno, strerror(errno)); 427 assert(aclp != NULL); 428 429 func = "facl()"; 430 n = facl(fd, SETACL, (int)(sizeof(aclp1)/sizeof(aclp1[0])), aclp1); 431#else 432 func = "acl_set_fd()"; 433 n = acl_set_fd(fd, acl1); 434#endif 435#if !ARCHIVE_ACL_SUNOS 436 acl_free(acl1); 437#endif 438 439 if (n != 0) { 440#if ARCHIVE_ACL_SUNOS 441 if (errno == ENOSYS || errno == ENOTSUP) 442#else 443 if (errno == EOPNOTSUPP || errno == EINVAL) 444#endif 445 { 446 close(fd); 447 skipping("POSIX.1e ACLs are not supported on this filesystem"); 448 return; 449 } 450 } 451 failure("%s: errno = %d (%s)", func, errno, strerror(errno)); 452 assertEqualInt(0, n); 453 454 close(fd); 455 456 assertMakeDir("d", 0700); 457 458 /* 459 * Create file d/f1 with acl2 460 * 461 * This differs from acl1 in the u:1: and g:15: permissions. 462 * 463 * This file deliberately has the same name but a different ACL. 464 * Github Issue #777 explains how libarchive's directory traversal 465 * did not always correctly enter directories before attempting 466 * to read ACLs, resulting in reading the ACL from a like-named 467 * file in the wrong directory. 468 */ 469#if ARCHIVE_ACL_SUNOS 470 acl2_text = "user::rwx," 471 "group::rwx," 472 "other:---," 473 "user:1:r--," 474 "group:15:r--," 475 "mask:rwx"; 476 aclent_t aclp2[] = { 477 { USER_OBJ, -1, 4 | 2 | 1 }, 478 { USER, 1, 4 }, 479 { GROUP_OBJ, -1, 4 | 2 | 1}, 480 { GROUP, 15, 4 }, 481 { CLASS_OBJ, -1, 4 | 2 | 1}, 482 { OTHER_OBJ, -1, 0 } 483 }; 484#else 485 acl2_text = "user::rwx\n" 486 "group::rwx\n" 487 "other::---\n" 488 "user:1:r--\n" 489 "group:15:r--\n" 490 "mask::rwx"; 491 acl2 = acl_from_text(acl2_text); 492 failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); 493 assert((void *)acl2 != NULL); 494#endif 495 fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777); 496 failure("Could not create test file?!"); 497 if (!assert(fd >= 0)) { 498#if !ARCHIVE_ACL_SUNOS 499 acl_free(acl2); 500#endif 501 return; 502 } 503#if ARCHIVE_ACL_SUNOS 504 func = "facl()"; 505 n = facl(fd, SETACL, (int)(sizeof(aclp2) / sizeof(aclp2[0])), aclp2); 506#else 507 func = "acl_set_fd()"; 508 n = acl_set_fd(fd, acl2); 509 acl_free(acl2); 510#endif 511 if (n != 0) 512 close(fd); 513 failure("%s: errno = %d (%s)", func, errno, strerror(errno)); 514 assertEqualInt(0, n); 515 close(fd); 516 517 /* Create nested directory d2 with default ACLs */ 518 assertMakeDir("d/d2", 0755); 519 520#if ARCHIVE_ACL_SUNOS 521 acl3_text = "user::rwx," 522 "group::r-x," 523 "other:r-x," 524 "user:2:r--," 525 "group:16:-w-," 526 "mask:rwx," 527 "default:user::rwx," 528 "default:user:1:r--," 529 "default:group::r-x," 530 "default:group:15:r--," 531 "default:mask:rwx," 532 "default:other:r-x"; 533 aclent_t aclp3[] = { 534 { USER_OBJ, -1, 4 | 2 | 1 }, 535 { USER, 2, 4 }, 536 { GROUP_OBJ, -1, 4 | 1 }, 537 { GROUP, 16, 2 }, 538 { CLASS_OBJ, -1, 4 | 2 | 1 }, 539 { OTHER_OBJ, -1, 4 | 1 }, 540 { USER_OBJ | ACL_DEFAULT, -1, 4 | 2 | 1 }, 541 { USER | ACL_DEFAULT, 1, 4 }, 542 { GROUP_OBJ | ACL_DEFAULT, -1, 4 | 1 }, 543 { GROUP | ACL_DEFAULT, 15, 4 }, 544 { CLASS_OBJ | ACL_DEFAULT, -1, 4 | 2 | 1}, 545 { OTHER_OBJ | ACL_DEFAULT, -1, 4 | 1 } 546 }; 547#else 548 acl3_text = "user::rwx\n" 549 "user:1:r--\n" 550 "group::r-x\n" 551 "group:15:r--\n" 552 "mask::rwx\n" 553 "other::r-x"; 554 acl3 = acl_from_text(acl3_text); 555 failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); 556 assert((void *)acl3 != NULL); 557#endif 558 559#if ARCHIVE_ACL_SUNOS 560 func = "acl()"; 561 n = acl("d/d2", SETACL, (int)(sizeof(aclp3) / sizeof(aclp3[0])), aclp3); 562#else 563 func = "acl_set_file()"; 564 n = acl_set_file("d/d2", ACL_TYPE_DEFAULT, acl3); 565 acl_free(acl3); 566#endif 567 failure("%s: errno = %d (%s)", func, errno, strerror(errno)); 568 assertEqualInt(0, n); 569 570 /* Create a read-from-disk object. */ 571 assert(NULL != (a = archive_read_disk_new())); 572 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); 573 assert(NULL != (ae = archive_entry_new())); 574 575#if ARCHIVE_ACL_SUNOS 576 flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E 577 | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 578 | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS; 579 dflags = flags; 580#else 581 flags = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; 582 dflags = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; 583#endif 584 585 /* Walk the dir until we see both of the files */ 586 while (ARCHIVE_OK == archive_read_next_header2(a, ae)) { 587 archive_read_disk_descend(a); 588 if (strcmp(archive_entry_pathname(ae), "./f1") == 0) { 589 acl_text = archive_entry_acl_to_text(ae, NULL, flags); 590 assertEqualString(acl_text, acl1_text); 591 free(acl_text); 592 } else if (strcmp(archive_entry_pathname(ae), "./d/f1") == 0) { 593 acl_text = archive_entry_acl_to_text(ae, NULL, flags); 594 assertEqualString(acl_text, acl2_text); 595 free(acl_text); 596 } else if (strcmp(archive_entry_pathname(ae), "./d/d2") == 0) { 597 acl_text = archive_entry_acl_to_text(ae, NULL, dflags); 598 assertEqualString(acl_text, acl3_text); 599 free(acl_text); 600 } 601 } 602 603 archive_entry_free(ae); 604 assertEqualInt(ARCHIVE_OK, archive_free(a)); 605#endif /* ARCHIVE_ACL_POSIX1E */ 606} 607