char get_acl(char *filename) { acl_t acl; acl_entry_t dummy; ssize_t xattr; char str[10]; xattr = 0; acl = NULL; acl = acl_get_link_np(filename, ACL_TYPE_EXTENDED); if (acl && acl_get_entry(acl, ACL_FIRST_ENTRY, &dummy) == -1) { acl_free(acl); acl = NULL; } xattr = listxattr(filename, NULL, 0, XATTR_NOFOLLOW); if (xattr < 0) xattr = 0; str[1] = '\0'; if (xattr > 0) str[0] = '@'; else if (acl) str[0] = '+'; else str[0] = ' '; return (str[0]); }
static int setup_acls_posix1e(struct archive_read_disk *a, struct archive_entry *entry, int fd) { const char *accpath; acl_t acl; accpath = archive_entry_sourcepath(entry); if (accpath == NULL) accpath = archive_entry_pathname(entry); archive_entry_acl_clear(entry); /* Retrieve access ACL from file. */ if (fd >= 0) acl = acl_get_fd(fd); #if HAVE_ACL_GET_LINK_NP else if (!a->follow_symlinks) acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); #else else if ((!a->follow_symlinks) && (archive_entry_filetype(entry) == AE_IFLNK)) /* We can't get the ACL of a symlink, so we assume it can't have one. */ acl = NULL; #endif else acl = acl_get_file(accpath, ACL_TYPE_ACCESS); if (acl != NULL) { setup_acl_posix1e(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); acl_free(acl); } /* Only directories can have default ACLs. */ if (S_ISDIR(archive_entry_mode(entry))) { acl = acl_get_file(accpath, ACL_TYPE_DEFAULT); if (acl != NULL) { setup_acl_posix1e(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); acl_free(acl); } } return (ARCHIVE_OK); }
/* * Add a + after the standard rwxrwxrwx mode if the file has an * ACL. strmode() reserves space at the end of the string. */ static void aclmode(char *buf, const FTSENT *p) { char name[MAXPATHLEN + 1]; int ret, trivial; static dev_t previous_dev = NODEV; static int supports_acls = -1; static int type = ACL_TYPE_ACCESS; acl_t facl; /* * XXX: ACLs are not supported on whiteouts and device files * residing on UFS. */ if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) || S_ISWHT(p->fts_statp->st_mode)) return; if (previous_dev == p->fts_statp->st_dev && supports_acls == 0) return; if (p->fts_level == FTS_ROOTLEVEL) snprintf(name, sizeof(name), "%s", p->fts_name); else snprintf(name, sizeof(name), "%s/%s", p->fts_parent->fts_accpath, p->fts_name); if (previous_dev != p->fts_statp->st_dev) { previous_dev = p->fts_statp->st_dev; supports_acls = 0; ret = lpathconf(name, _PC_ACL_NFS4); if (ret > 0) { type = ACL_TYPE_NFS4; supports_acls = 1; } else if (ret < 0 && errno != EINVAL) { xo_warn("%s", name); return; } if (supports_acls == 0) { ret = lpathconf(name, _PC_ACL_EXTENDED); if (ret > 0) { type = ACL_TYPE_ACCESS; supports_acls = 1; } else if (ret < 0 && errno != EINVAL) { xo_warn("%s", name); return; } } } if (supports_acls == 0) return; facl = acl_get_link_np(name, type); if (facl == NULL) { xo_warn("%s", name); return; } if (acl_is_trivial_np(facl, &trivial)) { acl_free(facl); xo_warn("%s", name); return; } if (!trivial) buf[10] = '+'; acl_free(facl); }
static int setup_acls(struct archive_read_disk *a, struct archive_entry *entry, int *fd) { const char *accpath; acl_t acl; #if HAVE_ACL_IS_TRIVIAL_NP int r; #endif accpath = archive_entry_sourcepath(entry); if (accpath == NULL) accpath = archive_entry_pathname(entry); archive_entry_acl_clear(entry); /* Try NFS4 ACL first. */ if (*fd >= 0) acl = acl_get_fd(*fd); #if HAVE_ACL_GET_LINK_NP else if (!a->follow_symlinks) acl = acl_get_link_np(accpath, ACL_TYPE_NFS4); #else else if ((!a->follow_symlinks) && (archive_entry_filetype(entry) == AE_IFLNK)) /* We can't get the ACL of a symlink, so we assume it can't have one. */ acl = NULL; #endif else acl = acl_get_file(accpath, ACL_TYPE_NFS4); #if HAVE_ACL_IS_TRIVIAL_NP /* Ignore "trivial" ACLs that just mirror the file mode. */ acl_is_trivial_np(acl, &r); if (r) { acl_free(acl); acl = NULL; } #endif if (acl != NULL) { translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4); acl_free(acl); return (ARCHIVE_OK); } /* Retrieve access ACL from file. */ if (*fd >= 0) acl = acl_get_fd(*fd); #if HAVE_ACL_GET_LINK_NP else if (!a->follow_symlinks) acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); #else else if ((!a->follow_symlinks) && (archive_entry_filetype(entry) == AE_IFLNK)) /* We can't get the ACL of a symlink, so we assume it can't have one. */ acl = NULL; #endif else acl = acl_get_file(accpath, ACL_TYPE_ACCESS); if (acl != NULL) { translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); acl_free(acl); } /* Only directories can have default ACLs. */ if (S_ISDIR(archive_entry_mode(entry))) { acl = acl_get_file(accpath, ACL_TYPE_DEFAULT); if (acl != NULL) { translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); acl_free(acl); } } return (ARCHIVE_OK); }
archive_entry_acl_clear(entry); acl = NULL; #ifdef ACL_TYPE_NFS4 /* Try NFS4 ACL first. */ if (*fd >= 0) #if HAVE_ACL_GET_FD_NP acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4); #else acl = acl_get_fd(*fd); #endif #if HAVE_ACL_GET_LINK_NP else if (!a->follow_symlinks) acl = acl_get_link_np(accpath, ACL_TYPE_NFS4); #else else if ((!a->follow_symlinks) && (archive_entry_filetype(entry) == AE_IFLNK)) /* We can't get the ACL of a symlink, so we assume it can't have one. */ acl = NULL; #endif else acl = acl_get_file(accpath, ACL_TYPE_NFS4); #if HAVE_ACL_IS_TRIVIAL_NP if (acl != NULL && acl_is_trivial_np(acl, &r) == 0) { /* Ignore "trivial" ACLs that just mirror the file mode. */ if (r) { acl_free(acl);
static int print_acl(char *path, acl_type_t type, int hflag, int iflag, int nflag, int qflag, int vflag) { struct stat sb; acl_t acl; char *acl_text; int error, flags = 0, ret; if (hflag) error = lstat(path, &sb); else error = stat(path, &sb); if (error == -1) { warn("%s: stat() failed", path); return(-1); } if (hflag) ret = lpathconf(path, _PC_ACL_NFS4); else ret = pathconf(path, _PC_ACL_NFS4); if (ret > 0) { if (type == ACL_TYPE_DEFAULT) { warnx("%s: there are no default entries in NFSv4 ACLs", path); return (-1); } type = ACL_TYPE_NFS4; } else if (ret < 0 && errno != EINVAL) { warn("%s: pathconf(..., _PC_ACL_NFS4) failed", path); return (-1); } if (more_than_one) printf("\n"); else more_than_one++; if (!qflag) printf("# file: %s\n# owner: %s\n# group: %s\n", path, getuname(sb.st_uid), getgname(sb.st_gid)); if (hflag) acl = acl_get_link_np(path, type); else acl = acl_get_file(path, type); if (!acl) { if (errno != EOPNOTSUPP) { warn("%s", path); return(-1); } errno = 0; if (type == ACL_TYPE_DEFAULT) return(0); acl = acl_from_stat(sb); if (!acl) { warn("%s: acl_from_stat() failed", path); return(-1); } } if (iflag) flags |= ACL_TEXT_APPEND_ID; if (nflag) flags |= ACL_TEXT_NUMERIC_IDS; if (vflag) flags |= ACL_TEXT_VERBOSE; acl_text = acl_to_text_np(acl, 0, flags); if (!acl_text) { warn("%s: acl_to_text_np() failed", path); return(-1); } printf("%s", acl_text); (void)acl_free(acl); (void)acl_free(acl_text); return(0); }