Example #1
0
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);
}
Example #3
0
/*
 * 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);
}
Example #5
0
	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);
Example #6
0
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);
}