Deleted Added
full compact
archive_read_disk_entry_from_file.c (305754) archive_read_disk_entry_from_file.c (306321)
1/*-
2 * Copyright (c) 2003-2009 Tim Kientzle
3 * Copyright (c) 2010-2012 Michihiro NAKAJIMA
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:

--- 11 unchanged lines hidden (view full) ---

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
27#include "archive_platform.h"
1/*-
2 * Copyright (c) 2003-2009 Tim Kientzle
3 * Copyright (c) 2010-2012 Michihiro NAKAJIMA
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:

--- 11 unchanged lines hidden (view full) ---

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
27#include "archive_platform.h"
28__FBSDID("$FreeBSD: stable/11/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c 305754 2016-09-12 22:07:00Z mm $");
28__FBSDID("$FreeBSD: stable/11/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c 306321 2016-09-25 22:02:27Z mm $");
29
30/* This is the tree-walking code for POSIX systems. */
31#if !defined(_WIN32) || defined(__CYGWIN__)
32
33#ifdef HAVE_SYS_TYPES_H
34/* Mac OSX requires sys/types.h before sys/acl.h. */
35#include <sys/types.h>
36#endif

--- 369 unchanged lines hidden (view full) ---

406 struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
407
408static int
409setup_acls(struct archive_read_disk *a,
410 struct archive_entry *entry, int *fd)
411{
412 const char *accpath;
413 acl_t acl;
29
30/* This is the tree-walking code for POSIX systems. */
31#if !defined(_WIN32) || defined(__CYGWIN__)
32
33#ifdef HAVE_SYS_TYPES_H
34/* Mac OSX requires sys/types.h before sys/acl.h. */
35#include <sys/types.h>
36#endif

--- 369 unchanged lines hidden (view full) ---

406 struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
407
408static int
409setup_acls(struct archive_read_disk *a,
410 struct archive_entry *entry, int *fd)
411{
412 const char *accpath;
413 acl_t acl;
414#if HAVE_ACL_IS_TRIVIAL_NP
415 int r;
414 int r;
416#endif
417
418 accpath = archive_entry_sourcepath(entry);
419 if (accpath == NULL)
420 accpath = archive_entry_pathname(entry);
421
422 if (*fd < 0 && a->tree != NULL) {
423 if (a->follow_symlinks ||
424 archive_entry_filetype(entry) != AE_IFLNK)

--- 43 unchanged lines hidden (view full) ---

468 * Simultaneous NFSv4 and POSIX.1e ACLs for the same
469 * entry are not allowed, so we should return here
470 */
471 return (ARCHIVE_OK);
472 }
473 }
474#endif
475 if (acl != NULL) {
415
416 accpath = archive_entry_sourcepath(entry);
417 if (accpath == NULL)
418 accpath = archive_entry_pathname(entry);
419
420 if (*fd < 0 && a->tree != NULL) {
421 if (a->follow_symlinks ||
422 archive_entry_filetype(entry) != AE_IFLNK)

--- 43 unchanged lines hidden (view full) ---

466 * Simultaneous NFSv4 and POSIX.1e ACLs for the same
467 * entry are not allowed, so we should return here
468 */
469 return (ARCHIVE_OK);
470 }
471 }
472#endif
473 if (acl != NULL) {
476 translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
474 r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
477 acl_free(acl);
475 acl_free(acl);
478 return (ARCHIVE_OK);
476 if (r != ARCHIVE_OK) {
477 archive_set_error(&a->archive, errno,
478 "Couldn't translate NFSv4 ACLs: %s", accpath);
479 }
480 return (r);
479 }
480#endif /* ACL_TYPE_NFS4 */
481
482 /* Retrieve access ACL from file. */
483 if (*fd >= 0)
484 acl = acl_get_fd(*fd);
485#if HAVE_ACL_GET_LINK_NP
486 else if (!a->follow_symlinks)

--- 14 unchanged lines hidden (view full) ---

501 if (r) {
502 acl_free(acl);
503 acl = NULL;
504 }
505 }
506#endif
507
508 if (acl != NULL) {
481 }
482#endif /* ACL_TYPE_NFS4 */
483
484 /* Retrieve access ACL from file. */
485 if (*fd >= 0)
486 acl = acl_get_fd(*fd);
487#if HAVE_ACL_GET_LINK_NP
488 else if (!a->follow_symlinks)

--- 14 unchanged lines hidden (view full) ---

503 if (r) {
504 acl_free(acl);
505 acl = NULL;
506 }
507 }
508#endif
509
510 if (acl != NULL) {
509 translate_acl(a, entry, acl,
511 r = translate_acl(a, entry, acl,
510 ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
511 acl_free(acl);
512 acl = NULL;
512 ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
513 acl_free(acl);
514 acl = NULL;
515 if (r != ARCHIVE_OK) {
516 archive_set_error(&a->archive, errno,
517 "Couldn't translate access ACLs: %s", accpath);
518 return (r);
519 }
513 }
514
515 /* Only directories can have default ACLs. */
516 if (S_ISDIR(archive_entry_mode(entry))) {
517 acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
518 if (acl != NULL) {
520 }
521
522 /* Only directories can have default ACLs. */
523 if (S_ISDIR(archive_entry_mode(entry))) {
524 acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
525 if (acl != NULL) {
519 translate_acl(a, entry, acl,
526 r = translate_acl(a, entry, acl,
520 ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
521 acl_free(acl);
527 ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
528 acl_free(acl);
529 if (r != ARCHIVE_OK) {
530 archive_set_error(&a->archive, errno,
531 "Couldn't translate default ACLs: %s",
532 accpath);
533 return (r);
534 }
522 }
523 }
524 return (ARCHIVE_OK);
525}
526
527/*
528 * Translate system ACL into libarchive internal structure.
529 */

--- 39 unchanged lines hidden (view full) ---

569static int
570translate_acl(struct archive_read_disk *a,
571 struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
572{
573 acl_tag_t acl_tag;
574#ifdef ACL_TYPE_NFS4
575 acl_entry_type_t acl_type;
576 acl_flagset_t acl_flagset;
535 }
536 }
537 return (ARCHIVE_OK);
538}
539
540/*
541 * Translate system ACL into libarchive internal structure.
542 */

--- 39 unchanged lines hidden (view full) ---

582static int
583translate_acl(struct archive_read_disk *a,
584 struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
585{
586 acl_tag_t acl_tag;
587#ifdef ACL_TYPE_NFS4
588 acl_entry_type_t acl_type;
589 acl_flagset_t acl_flagset;
577 int brand, r;
590 int brand;
578#endif
579 acl_entry_t acl_entry;
580 acl_permset_t acl_permset;
581 int i, entry_acl_type;
591#endif
592 acl_entry_t acl_entry;
593 acl_permset_t acl_permset;
594 int i, entry_acl_type;
582 int s, ae_id, ae_tag, ae_perm;
595 int r, s, ae_id, ae_tag, ae_perm;
583 const char *ae_name;
584
585#ifdef ACL_TYPE_NFS4
586 // FreeBSD "brands" ACLs as POSIX.1e or NFSv4
587 // Make sure the "brand" on this ACL is consistent
588 // with the default_entry_acl_type bits provided.
596 const char *ae_name;
597
598#ifdef ACL_TYPE_NFS4
599 // FreeBSD "brands" ACLs as POSIX.1e or NFSv4
600 // Make sure the "brand" on this ACL is consistent
601 // with the default_entry_acl_type bits provided.
589 acl_get_brand_np(acl, &brand);
602 if (acl_get_brand_np(acl, &brand) != 0) {
603 archive_set_error(&a->archive, errno,
604 "Failed to read ACL brand");
605 return (ARCHIVE_WARN);
606 }
590 switch (brand) {
591 case ACL_BRAND_POSIX:
592 switch (default_entry_acl_type) {
593 case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
594 case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
595 break;
596 default:
607 switch (brand) {
608 case ACL_BRAND_POSIX:
609 switch (default_entry_acl_type) {
610 case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
611 case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
612 break;
613 default:
597 // XXX set warning message?
598 return ARCHIVE_FAILED;
614 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
615 "Invalid ACL entry type for POSIX.1e ACL");
616 return (ARCHIVE_WARN);
599 }
600 break;
601 case ACL_BRAND_NFS4:
602 if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
617 }
618 break;
619 case ACL_BRAND_NFS4:
620 if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
603 // XXX set warning message?
604 return ARCHIVE_FAILED;
621 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
622 "Invalid ACL entry type for NFSv4 ACL");
623 return (ARCHIVE_WARN);
605 }
606 break;
607 default:
624 }
625 break;
626 default:
608 // XXX set warning message?
609 return ARCHIVE_FAILED;
627 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
628 "Unknown ACL brand");
629 return (ARCHIVE_WARN);
610 break;
611 }
612#endif
613
614
615 s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
630 break;
631 }
632#endif
633
634
635 s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
636 if (s == -1) {
637 archive_set_error(&a->archive, errno,
638 "Failed to get first ACL entry");
639 return (ARCHIVE_WARN);
640 }
616 while (s == 1) {
617 ae_id = -1;
618 ae_name = NULL;
619 ae_perm = 0;
620
641 while (s == 1) {
642 ae_id = -1;
643 ae_name = NULL;
644 ae_perm = 0;
645
621 acl_get_tag_type(acl_entry, &acl_tag);
646 if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
647 archive_set_error(&a->archive, errno,
648 "Failed to get ACL tag type");
649 return (ARCHIVE_WARN);
650 }
622 switch (acl_tag) {
623 case ACL_USER:
624 ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
625 ae_name = archive_read_disk_uname(&a->archive, ae_id);
626 ae_tag = ARCHIVE_ENTRY_ACL_USER;
627 break;
628 case ACL_GROUP:
629 ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);

--- 18 unchanged lines hidden (view full) ---

648 break;
649#endif
650 default:
651 /* Skip types that libarchive can't support. */
652 s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
653 continue;
654 }
655
651 switch (acl_tag) {
652 case ACL_USER:
653 ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
654 ae_name = archive_read_disk_uname(&a->archive, ae_id);
655 ae_tag = ARCHIVE_ENTRY_ACL_USER;
656 break;
657 case ACL_GROUP:
658 ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);

--- 18 unchanged lines hidden (view full) ---

677 break;
678#endif
679 default:
680 /* Skip types that libarchive can't support. */
681 s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
682 continue;
683 }
684
656 // XXX acl type maps to allow/deny/audit/YYYY bits
657 // XXX acl_get_entry_type_np on FreeBSD returns EINVAL for
658 // non-NFSv4 ACLs
685 // XXX acl_type maps to allow/deny/audit/YYYY bits
659 entry_acl_type = default_entry_acl_type;
660#ifdef ACL_TYPE_NFS4
686 entry_acl_type = default_entry_acl_type;
687#ifdef ACL_TYPE_NFS4
661 r = acl_get_entry_type_np(acl_entry, &acl_type);
662 if (r == 0) {
688 if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
689 /*
690 * acl_get_entry_type_np() falis with non-NFSv4 ACLs
691 */
692 if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) {
693 archive_set_error(&a->archive, errno, "Failed "
694 "to get ACL type from a NFSv4 ACL entry");
695 return (ARCHIVE_WARN);
696 }
663 switch (acl_type) {
664 case ACL_ENTRY_TYPE_ALLOW:
665 entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
666 break;
667 case ACL_ENTRY_TYPE_DENY:
668 entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
669 break;
670 case ACL_ENTRY_TYPE_AUDIT:
671 entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
672 break;
673 case ACL_ENTRY_TYPE_ALARM:
674 entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
675 break;
697 switch (acl_type) {
698 case ACL_ENTRY_TYPE_ALLOW:
699 entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
700 break;
701 case ACL_ENTRY_TYPE_DENY:
702 entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
703 break;
704 case ACL_ENTRY_TYPE_AUDIT:
705 entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
706 break;
707 case ACL_ENTRY_TYPE_ALARM:
708 entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
709 break;
710 default:
711 archive_set_error(&a->archive, errno,
712 "Invalid NFSv4 ACL entry type");
713 return (ARCHIVE_WARN);
676 }
714 }
677 }
678
715
679 /*
680 * Libarchive stores "flag" (NFSv4 inheritance bits)
681 * in the ae_perm bitmap.
682 */
683 // XXX acl_get_flagset_np on FreeBSD returns EINVAL for
684 // non-NFSv4 ACLs
685 r = acl_get_flagset_np(acl_entry, &acl_flagset);
686 if (r == 0) {
716 /*
717 * Libarchive stores "flag" (NFSv4 inheritance bits)
718 * in the ae_perm bitmap.
719 *
720 * acl_get_flagset_np() fails with non-NFSv4 ACLs
721 */
722 if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
723 archive_set_error(&a->archive, errno,
724 "Failed to get flagset from a NFSv4 ACL entry");
725 return (ARCHIVE_WARN);
726 }
687 for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
727 for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
688 if (acl_get_flag_np(acl_flagset,
689 acl_inherit_map[i].platform_inherit))
728 r = acl_get_flag_np(acl_flagset,
729 acl_inherit_map[i].platform_inherit);
730 if (r == -1) {
731 archive_set_error(&a->archive, errno,
732 "Failed to check flag in a NFSv4 "
733 "ACL flagset");
734 return (ARCHIVE_WARN);
735 } else if (r)
690 ae_perm |= acl_inherit_map[i].archive_inherit;
691 }
692 }
693#endif
694
736 ae_perm |= acl_inherit_map[i].archive_inherit;
737 }
738 }
739#endif
740
695 acl_get_permset(acl_entry, &acl_permset);
741 if (acl_get_permset(acl_entry, &acl_permset) != 0) {
742 archive_set_error(&a->archive, errno,
743 "Failed to get ACL permission set");
744 return (ARCHIVE_WARN);
745 }
696 for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
697 /*
698 * acl_get_perm() is spelled differently on different
699 * platforms; see above.
700 */
746 for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
747 /*
748 * acl_get_perm() is spelled differently on different
749 * platforms; see above.
750 */
701 if (ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm))
751 r = ACL_GET_PERM(acl_permset, acl_perm_map[i].platform_perm);
752 if (r == -1) {
753 archive_set_error(&a->archive, errno,
754 "Failed to check permission in an ACL permission set");
755 return (ARCHIVE_WARN);
756 } else if (r)
702 ae_perm |= acl_perm_map[i].archive_perm;
703 }
704
705 archive_entry_acl_add_entry(entry, entry_acl_type,
706 ae_perm, ae_tag,
707 ae_id, ae_name);
708
709 s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
757 ae_perm |= acl_perm_map[i].archive_perm;
758 }
759
760 archive_entry_acl_add_entry(entry, entry_acl_type,
761 ae_perm, ae_tag,
762 ae_id, ae_name);
763
764 s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
765 if (s == -1) {
766 archive_set_error(&a->archive, errno,
767 "Failed to get next ACL entry");
768 return (ARCHIVE_WARN);
769 }
710 }
711 return (ARCHIVE_OK);
712}
713#else
714static int
715setup_acls(struct archive_read_disk *a,
716 struct archive_entry *entry, int *fd)
717{

--- 586 unchanged lines hidden ---
770 }
771 return (ARCHIVE_OK);
772}
773#else
774static int
775setup_acls(struct archive_read_disk *a,
776 struct archive_entry *entry, int *fd)
777{

--- 586 unchanged lines hidden ---