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 --- |