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