| @@ -486,40 +486,40 @@ sunacl_get(int cmd, int *aclcnt, int fd, | | | @@ -486,40 +486,40 @@ sunacl_get(int cmd, int *aclcnt, int fd, |
486 | break; | | 486 | break; |
487 | } | | 487 | } |
488 | } | | 488 | } |
489 | | | 489 | |
490 | *aclcnt = cnt; | | 490 | *aclcnt = cnt; |
491 | return (aclp); | | 491 | return (aclp); |
492 | } | | 492 | } |
493 | #endif /* HAVE_SUN_ACL */ | | 493 | #endif /* HAVE_SUN_ACL */ |
494 | | | 494 | |
495 | #if HAVE_POSIX_ACL || HAVE_NFS4_ACL | | 495 | #if HAVE_POSIX_ACL || HAVE_NFS4_ACL |
496 | static int translate_acl(struct archive_read_disk *a, | | 496 | static int translate_acl(struct archive_read_disk *a, |
497 | struct archive_entry *entry, | | 497 | struct archive_entry *entry, |
498 | #if HAVE_SUN_ACL | | 498 | #if HAVE_SUN_ACL |
499 | void *acl, | | 499 | void *aclp, |
500 | int aclcnt, | | 500 | int aclcnt, |
501 | #else | | 501 | #else |
502 | acl_t acl, | | 502 | acl_t acl, |
503 | #endif | | 503 | #endif |
504 | int archive_entry_acl_type); | | 504 | int archive_entry_acl_type); |
505 | | | 505 | |
506 | static int | | 506 | static int |
507 | setup_acls(struct archive_read_disk *a, | | 507 | setup_acls(struct archive_read_disk *a, |
508 | struct archive_entry *entry, int *fd) | | 508 | struct archive_entry *entry, int *fd) |
509 | { | | 509 | { |
510 | const char *accpath; | | 510 | const char *accpath; |
511 | #if HAVE_SUN_ACL | | 511 | #if HAVE_SUN_ACL |
512 | void *acl; | | 512 | void *aclp; |
513 | int aclcnt; | | 513 | int aclcnt; |
514 | #else | | 514 | #else |
515 | acl_t acl; | | 515 | acl_t acl; |
516 | #endif | | 516 | #endif |
517 | int r; | | 517 | int r; |
518 | | | 518 | |
519 | accpath = NULL; | | 519 | accpath = NULL; |
520 | | | 520 | |
521 | #if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_ACL_GET_FD_NP | | 521 | #if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_ACL_GET_FD_NP |
522 | if (*fd < 0) | | 522 | if (*fd < 0) |
523 | #else | | 523 | #else |
524 | /* For default ACLs on Linux we need reachable accpath */ | | 524 | /* For default ACLs on Linux we need reachable accpath */ |
525 | if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) | | 525 | if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) |
| @@ -537,173 +537,190 @@ setup_acls(struct archive_read_disk *a, | | | @@ -537,173 +537,190 @@ setup_acls(struct archive_read_disk *a, |
537 | if (a->tree != NULL && | | 537 | if (a->tree != NULL && |
538 | #if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_ACL_GET_FD_NP | | 538 | #if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_ACL_GET_FD_NP |
539 | *fd < 0 && | | 539 | *fd < 0 && |
540 | #endif | | 540 | #endif |
541 | (a->follow_symlinks || | | 541 | (a->follow_symlinks || |
542 | archive_entry_filetype(entry) != AE_IFLNK)) { | | 542 | archive_entry_filetype(entry) != AE_IFLNK)) { |
543 | *fd = a->open_on_current_dir(a->tree, | | 543 | *fd = a->open_on_current_dir(a->tree, |
544 | accpath, O_RDONLY | O_NONBLOCK); | | 544 | accpath, O_RDONLY | O_NONBLOCK); |
545 | } | | 545 | } |
546 | } | | 546 | } |
547 | | | 547 | |
548 | archive_entry_acl_clear(entry); | | 548 | archive_entry_acl_clear(entry); |
549 | | | 549 | |
| | | 550 | #if HAVE_SUN_ACL |
| | | 551 | aclp = NULL; |
| | | 552 | #else |
550 | acl = NULL; | | 553 | acl = NULL; |
| | | 554 | #endif |
551 | | | 555 | |
552 | #if HAVE_NFS4_ACL | | 556 | #if HAVE_NFS4_ACL |
553 | /* Try NFSv4 ACL first. */ | | 557 | /* Try NFSv4 ACL first. */ |
554 | if (*fd >= 0) | | 558 | if (*fd >= 0) |
555 | #if HAVE_SUN_ACL | | 559 | #if HAVE_SUN_ACL |
556 | acl = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL); | | 560 | aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL); |
557 | #elif HAVE_ACL_GET_FD_NP | | 561 | #elif HAVE_ACL_GET_FD_NP |
558 | acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); | | 562 | acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); |
559 | #else | | 563 | #else |
560 | acl = acl_get_fd(*fd); | | 564 | acl = acl_get_fd(*fd); |
561 | #endif | | 565 | #endif |
562 | #if HAVE_ACL_GET_LINK_NP | | 566 | #if HAVE_ACL_GET_LINK_NP |
563 | else if (!a->follow_symlinks) | | 567 | else if (!a->follow_symlinks) |
564 | acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); | | 568 | acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); |
565 | #else | | 569 | #else |
566 | else if ((!a->follow_symlinks) | | 570 | else if ((!a->follow_symlinks) |
567 | && (archive_entry_filetype(entry) == AE_IFLNK)) | | 571 | && (archive_entry_filetype(entry) == AE_IFLNK)) |
568 | /* We can't get the ACL of a symlink, so we assume it can't | | 572 | /* We can't get the ACL of a symlink, so we assume it can't |
569 | have one. */ | | 573 | have one. */ |
| | | 574 | #if HAVE_SUN_ACL |
| | | 575 | aclp = NULL; |
| | | 576 | #else |
570 | acl = NULL; | | 577 | acl = NULL; |
571 | #endif | | 578 | #endif |
| | | 579 | #endif /* !HAVE_ACL_GET_LINK_NP */ |
572 | else | | 580 | else |
573 | #if HAVE_SUN_ACL | | 581 | #if HAVE_SUN_ACL |
574 | /* Solaris reads both POSIX.1e and NFSv4 ACLs here */ | | 582 | /* Solaris reads both POSIX.1e and NFSv4 ACLs here */ |
575 | acl = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath); | | 583 | aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath); |
576 | #else | | 584 | #else |
577 | acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); | | 585 | acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4); |
578 | #endif | | 586 | #endif |
579 | | | 587 | |
580 | | | 588 | |
581 | #if HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL | | | |
582 | /* Ignore "trivial" ACLs that just mirror the file mode. */ | | 589 | /* Ignore "trivial" ACLs that just mirror the file mode. */ |
583 | if (acl != NULL) { | | | |
584 | #if HAVE_SUN_ACL | | 590 | #if HAVE_SUN_ACL |
585 | if (sun_acl_is_trivial(acl, aclcnt, archive_entry_mode(entry), | | 591 | if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt, |
586 | 1, S_ISDIR(archive_entry_mode(entry)), &r) == 0 && r == 1) | | 592 | archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)), |
| | | 593 | &r) == 0 && r == 1) { |
| | | 594 | free(aclp); |
| | | 595 | aclp = NULL; |
| | | 596 | return (ARCHIVE_OK); |
| | | 597 | } |
587 | #elif HAVE_ACL_IS_TRIVIAL_NP | | 598 | #elif HAVE_ACL_IS_TRIVIAL_NP |
588 | if (acl_is_trivial_np(acl, &r) == 0 && r == 1) | | 599 | if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) { |
| | | 600 | acl_free(acl); |
| | | 601 | acl = NULL; |
| | | 602 | return (ARCHIVE_OK); |
| | | 603 | } |
589 | #endif | | 604 | #endif |
590 | { | | 605 | |
591 | #if HAVE_SUN_ACL | | 606 | #if HAVE_SUN_ACL |
592 | free(acl); | | 607 | if (aclp != NULL) |
593 | #else | | 608 | #else |
594 | acl_free(acl); | | 609 | if (acl != NULL) |
595 | #endif | | 610 | #endif |
596 | acl = NULL; | | 611 | { |
597 | /* | | 612 | r = translate_acl(a, entry, |
598 | * Simultaneous NFSv4 and POSIX.1e ACLs for the same | | | |
599 | * entry are not allowed, so we should return here | | | |
600 | */ | | | |
601 | return (ARCHIVE_OK); | | | |
602 | } | | | |
603 | } | | | |
604 | #endif /* HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL */ | | | |
605 | if (acl != NULL) { | | | |
606 | r = translate_acl(a, entry, acl, | | | |
607 | #if HAVE_SUN_ACL | | 613 | #if HAVE_SUN_ACL |
608 | aclcnt, | | 614 | aclp, aclcnt, |
| | | 615 | #else |
| | | 616 | acl, |
609 | #endif | | 617 | #endif |
610 | ARCHIVE_ENTRY_ACL_TYPE_NFS4); | | 618 | ARCHIVE_ENTRY_ACL_TYPE_NFS4); |
611 | #if HAVE_SUN_ACL | | 619 | #if HAVE_SUN_ACL |
612 | free(acl); | | 620 | free(aclp); |
| | | 621 | aclp = NULL; |
613 | #else | | 622 | #else |
614 | acl_free(acl); | | 623 | acl_free(acl); |
| | | 624 | acl = NULL; |
615 | #endif | | 625 | #endif |
| | | 626 | |
616 | if (r != ARCHIVE_OK) { | | 627 | if (r != ARCHIVE_OK) { |
617 | archive_set_error(&a->archive, errno, | | 628 | archive_set_error(&a->archive, errno, |
618 | "Couldn't translate NFSv4 ACLs"); | | 629 | "Couldn't translate NFSv4 ACLs"); |
619 | } | | 630 | } |
620 | #if HAVE_DARWIN_ACL | | 631 | #if HAVE_DARWIN_ACL |
621 | /* | | 632 | /* |
622 | * Because Mac OS doesn't support owner@, group@ and everyone@ | | 633 | * Because Mac OS doesn't support owner@, group@ and everyone@ |
623 | * ACLs we need to add NFSv4 ACLs mirroring the file mode to | | 634 | * ACLs we need to add NFSv4 ACLs mirroring the file mode to |
624 | * the archive entry. Otherwise extraction on non-Mac platforms | | 635 | * the archive entry. Otherwise extraction on non-Mac platforms |
625 | * would lead to an invalid file mode. | | 636 | * would lead to an invalid file mode. |
626 | */ | | 637 | */ |
627 | if ((archive_entry_acl_types(entry) & | | 638 | if ((archive_entry_acl_types(entry) & |
628 | ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) | | 639 | ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) |
629 | add_trivial_nfs4_acl(entry); | | 640 | add_trivial_nfs4_acl(entry); |
630 | #endif | | 641 | #endif |
631 | return (r); | | 642 | return (r); |
632 | } | | 643 | } |
633 | #endif /* HAVE_NFS4_ACL */ | | 644 | #endif /* HAVE_NFS4_ACL */ |
634 | | | 645 | |
635 | #if HAVE_POSIX_ACL || HAVE_SUN_ACL | | 646 | #if HAVE_POSIX_ACL || HAVE_SUN_ACL |
636 | /* This code path is skipped on MacOS */ | | 647 | /* This code path is skipped on MacOS */ |
637 | | | 648 | |
638 | /* Retrieve access ACL from file. */ | | 649 | /* Retrieve access ACL from file. */ |
639 | if (*fd >= 0) | | 650 | if (*fd >= 0) |
640 | #if HAVE_SUN_ACL | | 651 | #if HAVE_SUN_ACL |
641 | acl = sunacl_get(GETACL, &aclcnt, *fd, NULL); | | 652 | aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL); |
642 | #else | | 653 | #else |
643 | acl = acl_get_fd(*fd); | | 654 | acl = acl_get_fd(*fd); |
644 | #endif | | 655 | #endif |
645 | #if HAVE_ACL_GET_LINK_NP | | 656 | #if HAVE_ACL_GET_LINK_NP |
646 | else if (!a->follow_symlinks) | | 657 | else if (!a->follow_symlinks) |
647 | acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); | | 658 | acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); |
648 | #else | | 659 | #else |
649 | else if ((!a->follow_symlinks) | | 660 | else if ((!a->follow_symlinks) |
650 | && (archive_entry_filetype(entry) == AE_IFLNK)) | | 661 | && (archive_entry_filetype(entry) == AE_IFLNK)) |
651 | /* We can't get the ACL of a symlink, so we assume it can't | | 662 | /* We can't get the ACL of a symlink, so we assume it can't |
652 | have one. */ | | 663 | have one. */ |
| | | 664 | #if HAVE_SUN_ACL |
| | | 665 | aclp = NULL; |
| | | 666 | #else |
653 | acl = NULL; | | 667 | acl = NULL; |
654 | #endif | | 668 | #endif |
| | | 669 | #endif /* !HAVE_ACL_GET_LINK_NP */ |
655 | else | | 670 | else |
656 | #if HAVE_SUN_ACL | | 671 | #if HAVE_SUN_ACL |
657 | acl = sunacl_get(GETACL, &aclcnt, 0, accpath); | | 672 | aclp = sunacl_get(GETACL, &aclcnt, 0, accpath); |
658 | #else | | 673 | #else |
659 | acl = acl_get_file(accpath, ACL_TYPE_ACCESS); | | 674 | acl = acl_get_file(accpath, ACL_TYPE_ACCESS); |
660 | #endif | | 675 | #endif |
661 | | | 676 | |
662 | | | 677 | |
663 | #if HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL | | | |
664 | /* Ignore "trivial" ACLs that just mirror the file mode. */ | | 678 | /* Ignore "trivial" ACLs that just mirror the file mode. */ |
665 | if (acl != NULL) { | | | |
666 | #if HAVE_SUN_ACL | | 679 | #if HAVE_SUN_ACL |
667 | if (sun_acl_is_trivial(acl, aclcnt, archive_entry_mode(entry), | | 680 | if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt, |
668 | 0, S_ISDIR(archive_entry_mode(entry)), &r) == 0 && r == 1) | | 681 | archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)), |
669 | #else | | 682 | &r) == 0 && r == 1) { |
670 | if (acl_is_trivial_np(acl, &r) == 0) | | 683 | free(aclp); |
| | | 684 | aclp = NULL; |
| | | 685 | } |
| | | 686 | #elif HAVE_ACL_IS_TRIVIAL_NP |
| | | 687 | if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) { |
| | | 688 | acl_free(acl); |
| | | 689 | acl = NULL; |
| | | 690 | } |
671 | #endif | | 691 | #endif |
672 | { | | 692 | |
673 | if (r) { | | | |
674 | #if HAVE_SUN_ACL | | 693 | #if HAVE_SUN_ACL |
675 | free(acl); | | 694 | if (aclp != NULL) |
676 | #else | | 695 | #else |
677 | acl_free(acl); | | 696 | if (acl != NULL) |
678 | #endif | | 697 | #endif |
679 | acl = NULL; | | 698 | { |
680 | } | | 699 | r = translate_acl(a, entry, |
681 | } | | | |
682 | } | | | |
683 | #endif | | | |
684 | | | | |
685 | if (acl != NULL) { | | | |
686 | r = translate_acl(a, entry, acl, | | | |
687 | #if HAVE_SUN_ACL | | 700 | #if HAVE_SUN_ACL |
688 | aclcnt, | | 701 | aclp, aclcnt, |
| | | 702 | #else |
| | | 703 | acl, |
689 | #endif | | 704 | #endif |
690 | ARCHIVE_ENTRY_ACL_TYPE_ACCESS); | | 705 | ARCHIVE_ENTRY_ACL_TYPE_ACCESS); |
691 | #if HAVE_SUN_ACL | | 706 | #if HAVE_SUN_ACL |
692 | free(acl); | | 707 | free(aclp); |
| | | 708 | aclp = NULL; |
693 | #else | | 709 | #else |
694 | acl_free(acl); | | 710 | acl_free(acl); |
695 | #endif | | | |
696 | acl = NULL; | | 711 | acl = NULL; |
| | | 712 | #endif |
| | | 713 | |
697 | if (r != ARCHIVE_OK) { | | 714 | if (r != ARCHIVE_OK) { |
698 | archive_set_error(&a->archive, errno, | | 715 | archive_set_error(&a->archive, errno, |
699 | "Couldn't translate access ACLs"); | | 716 | "Couldn't translate access ACLs"); |
700 | return (r); | | 717 | return (r); |
701 | } | | 718 | } |
702 | } | | 719 | } |
703 | | | 720 | |
704 | #if !HAVE_SUN_ACL | | 721 | #if !HAVE_SUN_ACL |
705 | /* Only directories can have default ACLs. */ | | 722 | /* Only directories can have default ACLs. */ |
706 | if (S_ISDIR(archive_entry_mode(entry))) { | | 723 | if (S_ISDIR(archive_entry_mode(entry))) { |
707 | #if HAVE_ACL_GET_FD_NP | | 724 | #if HAVE_ACL_GET_FD_NP |
708 | if (*fd >= 0) | | 725 | if (*fd >= 0) |
709 | acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT); | | 726 | acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT); |