test_acl_platform_posix1e.c revision 313926
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 HAVE_POSIX_ACL || HAVE_SUN_ACL 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 HAVE_SUN_ACL 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 HAVE_POSIX_ACL 66 acl_permset_t opaque_ps; 67#endif 68 69#if HAVE_SUN_ACL 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 130static int 131#if HAVE_SUN_ACL 132acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl) 133#else 134acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl) 135#endif 136{ 137#if HAVE_POSIX_ACL 138 gid_t g, *gp; 139 uid_t u, *up; 140 acl_tag_t tag_type; 141#endif 142 143 if (myacl->permset != acl_entry_get_perm(aclent)) 144 return (0); 145 146#if HAVE_SUN_ACL 147 switch (aclent->a_type) 148#else 149 acl_get_tag_type(aclent, &tag_type); 150 switch (tag_type) 151#endif 152 { 153#if HAVE_SUN_ACL 154 case DEF_USER_OBJ: 155 case USER_OBJ: 156#else 157 case ACL_USER_OBJ: 158#endif 159 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0); 160 break; 161#if HAVE_SUN_ACL 162 case DEF_USER: 163 case USER: 164#else 165 case ACL_USER: 166#endif 167 if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) 168 return (0); 169#if HAVE_SUN_ACL 170 if ((uid_t)myacl->qual != aclent->a_id) 171 return (0); 172#else 173 up = acl_get_qualifier(aclent); 174 u = *up; 175 acl_free(up); 176 if ((uid_t)myacl->qual != u) 177 return (0); 178#endif 179 break; 180#if HAVE_SUN_ACL 181 case DEF_GROUP_OBJ: 182 case GROUP_OBJ: 183#else 184 case ACL_GROUP_OBJ: 185#endif 186 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0); 187 break; 188#if HAVE_SUN_ACL 189 case DEF_GROUP: 190 case GROUP: 191#else 192 case ACL_GROUP: 193#endif 194 if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) 195 return (0); 196#if HAVE_SUN_ACL 197 if ((gid_t)myacl->qual != aclent->a_id) 198 return (0); 199#else 200 gp = acl_get_qualifier(aclent); 201 g = *gp; 202 acl_free(gp); 203 if ((gid_t)myacl->qual != g) 204 return (0); 205#endif 206 break; 207#if HAVE_SUN_ACL 208 case DEF_CLASS_OBJ: 209 case CLASS_OBJ: 210#else 211 case ACL_MASK: 212#endif 213 if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0); 214 break; 215#if HAVE_SUN_ACL 216 case DEF_OTHER_OBJ: 217 case OTHER_OBJ: 218#else 219 case ACL_OTHER: 220#endif 221 if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0); 222 break; 223 } 224 return (1); 225} 226 227static void 228#if HAVE_SUN_ACL 229compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n) 230#else 231compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n) 232#endif 233{ 234 int *marker; 235 int matched; 236 int i; 237#if HAVE_SUN_ACL 238 int e; 239 aclent_t *acl_entry; 240#else 241 int entry_id = ACL_FIRST_ENTRY; 242 acl_entry_t acl_entry; 243#endif 244 245 /* Count ACL entries in myacls array and allocate an indirect array. */ 246 marker = malloc(sizeof(marker[0]) * n); 247 if (marker == NULL) 248 return; 249 for (i = 0; i < n; i++) 250 marker[i] = i; 251 252 /* 253 * Iterate over acls in system acl object, try to match each 254 * one with an item in the myacls array. 255 */ 256#if HAVE_SUN_ACL 257 for(e = 0; e < acl->acl_cnt; e++) { 258 acl_entry = &((aclent_t *)acl->acl_aclp)[e]; 259#else 260 while (1 == acl_get_entry(acl, entry_id, &acl_entry)) { 261 /* After the first time... */ 262 entry_id = ACL_NEXT_ENTRY; 263#endif 264 265 /* Search for a matching entry (tag and qualifier) */ 266 for (i = 0, matched = 0; i < n && !matched; i++) { 267 if (acl_match(acl_entry, &myacls[marker[i]])) { 268 /* We found a match; remove it. */ 269 marker[i] = marker[n - 1]; 270 n--; 271 matched = 1; 272 } 273 } 274 275 /* TODO: Print out more details in this case. */ 276 failure("ACL entry on file that shouldn't be there"); 277 assert(matched == 1); 278 } 279 280 /* Dump entries in the myacls array that weren't in the system acl. */ 281 for (i = 0; i < n; ++i) { 282 failure(" ACL entry missing from file: " 283 "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", 284 myacls[marker[i]].type, myacls[marker[i]].permset, 285 myacls[marker[i]].tag, myacls[marker[i]].qual, 286 myacls[marker[i]].name); 287 assert(0); /* Record this as a failure. */ 288 } 289 free(marker); 290} 291 292#endif 293 294 295/* 296 * Verify ACL restore-to-disk. This test is Platform-specific. 297 */ 298 299DEFINE_TEST(test_acl_platform_posix1e_restore) 300{ 301#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL 302 skipping("POSIX.1e ACLs are not supported on this platform"); 303#else /* HAVE_SUN_ACL || HAVE_POSIX_ACL */ 304 struct stat st; 305 struct archive *a; 306 struct archive_entry *ae; 307 int n, fd; 308 char *func; 309#if HAVE_SUN_ACL 310 acl_t *acl, *acl2; 311#else 312 acl_t acl; 313#endif 314 315 /* 316 * First, do a quick manual set/read of ACL data to 317 * verify that the local filesystem does support ACLs. 318 * If it doesn't, we'll simply skip the remaining tests. 319 */ 320#if HAVE_SUN_ACL 321 n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl); 322 failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno)); 323 assertEqualInt(0, n); 324#else 325 acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx"); 326 failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); 327 assert((void *)acl != NULL); 328#endif 329 330 /* Create a test file and try ACL on it. */ 331 fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777); 332 failure("Could not create test file?!"); 333 if (!assert(fd >= 0)) { 334 acl_free(acl); 335 return; 336 } 337 338#if HAVE_SUN_ACL 339 n = facl_get(fd, 0, &acl2); 340 if (n != 0) { 341 close(fd); 342 acl_free(acl); 343 } 344 if (errno == ENOSYS) { 345 skipping("POSIX.1e ACLs are not supported on this filesystem"); 346 return; 347 } 348 failure("facl_get(): errno = %d (%s)", errno, strerror(errno)); 349 assertEqualInt(0, n); 350 351 if (acl2->acl_type != ACLENT_T) { 352 acl_free(acl2); 353 skipping("POSIX.1e ACLs are not supported on this filesystem"); 354 return; 355 } 356 acl_free(acl2); 357 358 func = "facl_set()"; 359 n = facl_set(fd, acl); 360#else 361 func = "acl_set_fd()"; 362 n = acl_set_fd(fd, acl); 363#endif 364 acl_free(acl); 365 if (n != 0) { 366#if HAVE_SUN_ACL 367 if (errno == ENOSYS) 368#else 369 if (errno == EOPNOTSUPP || errno == EINVAL) 370#endif 371 { 372 close(fd); 373 skipping("POSIX.1e ACLs are not supported on this filesystem"); 374 return; 375 } 376 } 377 failure("%s: errno = %d (%s)", func, errno, strerror(errno)); 378 assertEqualInt(0, n); 379 380#if HAVE_SUN_ACL 381 382#endif 383 close(fd); 384 385 /* Create a write-to-disk object. */ 386 assert(NULL != (a = archive_write_disk_new())); 387 archive_write_disk_set_options(a, 388 ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL); 389 390 /* Populate an archive entry with some metadata, including ACL info */ 391 ae = archive_entry_new(); 392 assert(ae != NULL); 393 archive_entry_set_pathname(ae, "test0"); 394 archive_entry_set_mtime(ae, 123456, 7890); 395 archive_entry_set_size(ae, 0); 396 archive_test_set_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); 397 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 398 archive_entry_free(ae); 399 400 /* Close the archive. */ 401 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 402 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 403 404 /* Verify the data on disk. */ 405 assertEqualInt(0, stat("test0", &st)); 406 assertEqualInt(st.st_mtime, 123456); 407#if HAVE_SUN_ACL 408 n = acl_get("test0", 0, &acl); 409 failure("acl_get(): errno = %d (%s)", errno, strerror(errno)); 410 assertEqualInt(0, n); 411#else 412 acl = acl_get_file("test0", ACL_TYPE_ACCESS); 413 failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno)); 414 assert(acl != (acl_t)NULL); 415#endif 416 compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0])); 417 acl_free(acl); 418#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */ 419} 420 421/* 422 * Verify ACL read-from-disk. This test is Platform-specific. 423 */ 424DEFINE_TEST(test_acl_platform_posix1e_read) 425{ 426#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL 427 skipping("POSIX.1e ACLs are not supported on this platform"); 428#else 429 struct archive *a; 430 struct archive_entry *ae; 431 int n, fd, flags, dflags; 432 char *func, *acl_text; 433 const char *acl1_text, *acl2_text, *acl3_text; 434#if HAVE_SUN_ACL 435 acl_t *acl, *acl1, *acl2, *acl3; 436#else 437 acl_t acl1, acl2, acl3; 438#endif 439 440 /* 441 * Manually construct a directory and two files with 442 * different ACLs. This also serves to verify that ACLs 443 * are supported on the local filesystem. 444 */ 445 446 /* Create a test file f1 with acl1 */ 447#if HAVE_SUN_ACL 448 acl1_text = "user::rwx," 449 "group::rwx," 450 "other:rwx," 451 "user:1:rw-," 452 "group:15:r-x," 453 "mask:rwx"; 454 n = acl_fromtext(acl1_text, &acl1); 455 failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno)); 456 assertEqualInt(0, n); 457#else 458 acl1_text = "user::rwx\n" 459 "group::rwx\n" 460 "other::rwx\n" 461 "user:1:rw-\n" 462 "group:15:r-x\n" 463 "mask::rwx"; 464 acl1 = acl_from_text(acl1_text); 465 failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); 466 assert((void *)acl1 != NULL); 467#endif 468 fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777); 469 failure("Could not create test file?!"); 470 if (!assert(fd >= 0)) { 471 acl_free(acl1); 472 return; 473 } 474#if HAVE_SUN_ACL 475 /* Check if Solaris filesystem supports POSIX.1e ACLs */ 476 n = facl_get(fd, 0, &acl); 477 if (n != 0) 478 close(fd); 479 if (n != 0 && errno == ENOSYS) { 480 acl_free(acl1); 481 skipping("POSIX.1e ACLs are not supported on this filesystem"); 482 return; 483 } 484 failure("facl_get(): errno = %d (%s)", errno, strerror(errno)); 485 assertEqualInt(0, n); 486 487 if (acl->acl_type != ACLENT_T) { 488 acl_free(acl); 489 acl_free(acl1); 490 close(fd); 491 skipping("POSIX.1e ACLs are not supported on this filesystem"); 492 return; 493 } 494 495 func = "facl_set()"; 496 n = facl_set(fd, acl1); 497#else 498 func = "acl_set_fd()"; 499 n = acl_set_fd(fd, acl1); 500#endif 501 acl_free(acl1); 502 503 if (n != 0) { 504#if HAVE_SUN_ACL 505 if (errno == ENOSYS) 506#else 507 if (errno == EOPNOTSUPP || errno == EINVAL) 508#endif 509 { 510 close(fd); 511 skipping("POSIX.1e ACLs are not supported on this filesystem"); 512 return; 513 } 514 } 515 failure("%s: errno = %d (%s)", func, errno, strerror(errno)); 516 assertEqualInt(0, n); 517 518 close(fd); 519 520 assertMakeDir("d", 0700); 521 522 /* 523 * Create file d/f1 with acl2 524 * 525 * This differs from acl1 in the u:1: and g:15: permissions. 526 * 527 * This file deliberately has the same name but a different ACL. 528 * Github Issue #777 explains how libarchive's directory traversal 529 * did not always correctly enter directories before attempting 530 * to read ACLs, resulting in reading the ACL from a like-named 531 * file in the wrong directory. 532 */ 533#if HAVE_SUN_ACL 534 acl2_text = "user::rwx," 535 "group::rwx," 536 "other:---," 537 "user:1:r--," 538 "group:15:r--," 539 "mask:rwx"; 540 n = acl_fromtext(acl2_text, &acl2); 541 failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno)); 542 assertEqualInt(0, n); 543#else 544 acl2_text = "user::rwx\n" 545 "group::rwx\n" 546 "other::---\n" 547 "user:1:r--\n" 548 "group:15:r--\n" 549 "mask::rwx"; 550 acl2 = acl_from_text(acl2_text); 551 failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); 552 assert((void *)acl2 != NULL); 553#endif 554 fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777); 555 failure("Could not create test file?!"); 556 if (!assert(fd >= 0)) { 557 acl_free(acl2); 558 return; 559 } 560#if HAVE_SUN_ACL 561 func = "facl_set()"; 562 n = facl_set(fd, acl2); 563#else 564 func = "acl_set_fd()"; 565 n = acl_set_fd(fd, acl2); 566#endif 567 acl_free(acl2); 568 if (n != 0) 569 close(fd); 570 failure("%s: errno = %d (%s)", func, errno, strerror(errno)); 571 assertEqualInt(0, n); 572 close(fd); 573 574 /* Create directory d2 with default ACLs */ 575 assertMakeDir("d2", 0755); 576 577#if HAVE_SUN_ACL 578 acl3_text = "user::rwx," 579 "group::r-x," 580 "other:r-x," 581 "user:2:r--," 582 "group:16:-w-," 583 "mask:rwx," 584 "default:user::rwx," 585 "default:user:1:r--," 586 "default:group::r-x," 587 "default:group:15:r--," 588 "default:mask:rwx," 589 "default:other:r-x"; 590 n = acl_fromtext(acl3_text, &acl3); 591 failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno)); 592 assertEqualInt(0, n); 593#else 594 acl3_text = "user::rwx\n" 595 "user:1:r--\n" 596 "group::r-x\n" 597 "group:15:r--\n" 598 "mask::rwx\n" 599 "other::r-x"; 600 acl3 = acl_from_text(acl3_text); 601 failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); 602 assert((void *)acl3 != NULL); 603#endif 604 605#if HAVE_SUN_ACL 606 func = "acl_set()"; 607 n = acl_set("d2", acl3); 608#else 609 func = "acl_set_file()"; 610 n = acl_set_file("d2", ACL_TYPE_DEFAULT, acl3); 611#endif 612 acl_free(acl3); 613 614 failure("%s: errno = %d (%s)", func, errno, strerror(errno)); 615 assertEqualInt(0, n); 616 617 /* Create a read-from-disk object. */ 618 assert(NULL != (a = archive_read_disk_new())); 619 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); 620 assert(NULL != (ae = archive_entry_new())); 621 622#if HAVE_SUN_ACL 623 flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E 624 | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 625 | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS; 626 dflags = flags; 627#else 628 flags = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; 629 dflags = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; 630#endif 631 632 /* Walk the dir until we see both of the files */ 633 while (ARCHIVE_OK == archive_read_next_header2(a, ae)) { 634 archive_read_disk_descend(a); 635 if (strcmp(archive_entry_pathname(ae), "./f1") == 0) { 636 acl_text = archive_entry_acl_to_text(ae, NULL, flags); 637 assertEqualString(acl_text, acl1_text); 638 free(acl_text); 639 } else if (strcmp(archive_entry_pathname(ae), "./d/f1") == 0) { 640 acl_text = archive_entry_acl_to_text(ae, NULL, flags); 641 assertEqualString(acl_text, acl2_text); 642 free(acl_text); 643 } else if (strcmp(archive_entry_pathname(ae), "./d2") == 0) { 644 acl_text = archive_entry_acl_to_text(ae, NULL, dflags); 645 assertEqualString(acl_text, acl3_text); 646 free(acl_text); 647 } 648 } 649 650 archive_entry_free(ae); 651 assertEqualInt(ARCHIVE_OK, archive_free(a)); 652#endif 653} 654