aclutils.c revision f48205be61a214698b763ff550ab9e657525104c
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * Common Development and Distribution License (the "License").
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or http://www.opensolaris.org/os/licensing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
f48205be61a214698b763ff550ab9e657525104ccasper * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <stdlib.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <string.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <unistd.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <limits.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <grp.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <pwd.h>
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#include <strings.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/types.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/acl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <errno.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/stat.h>
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks#include <sys/varargs.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <locale.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <aclutils.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <acl_common.h>
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#include <sys/avl.h>
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_PATH 0
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_FD 1
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACE_POSIX_SUPPORTED_BITS (ACE_READ_DATA | \
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_WRITE_DATA | ACE_APPEND_DATA | ACE_EXECUTE | \
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_READ_ATTRIBUTES | ACE_READ_ACL | ACE_WRITE_ACL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_SYNCHRONIZE_SET_DENY 0x0000001
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_SYNCHRONIZE_SET_ALLOW 0x0000002
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_SYNCHRONIZE_ERR_DENY 0x0000004
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_SYNCHRONIZE_ERR_ALLOW 0x0000008
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_OWNER_SET_DENY 0x0000010
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_OWNER_SET_ALLOW 0x0000020
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_OWNER_ERR_DENY 0x0000040
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_OWNER_ERR_ALLOW 0x0000080
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_DELETE_SET_DENY 0x0000100
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_DELETE_SET_ALLOW 0x0000200
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_DELETE_ERR_DENY 0x0000400
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_DELETE_ERR_ALLOW 0x0000800
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_ATTRS_OWNER_SET_DENY 0x0001000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_ATTRS_OWNER_SET_ALLOW 0x0002000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_ATTRS_OWNER_ERR_DENY 0x0004000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_ATTRS_OWNER_ERR_ALLOW 0x0008000
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_ATTRS_WRITER_SET_DENY 0x0010000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_ATTRS_WRITER_SET_ALLOW 0x0020000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_ATTRS_WRITER_ERR_DENY 0x0040000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_ATTRS_WRITER_ERR_ALLOW 0x0080000
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_NAMED_WRITER_SET_DENY 0x0100000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_NAMED_WRITER_SET_ALLOW 0x0200000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_NAMED_WRITER_ERR_DENY 0x0400000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_WRITE_NAMED_WRITER_ERR_ALLOW 0x0800000
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_READ_NAMED_READER_SET_DENY 0x1000000
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_READ_NAMED_READER_SET_ALLOW 0x2000000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_READ_NAMED_READER_ERR_DENY 0x4000000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACL_READ_NAMED_READER_ERR_ALLOW 0x8000000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACE_VALID_MASK_BITS (\
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_READ_DATA | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_LIST_DIRECTORY | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_WRITE_DATA | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_ADD_FILE | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_APPEND_DATA | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_ADD_SUBDIRECTORY | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_READ_NAMED_ATTRS | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_WRITE_NAMED_ATTRS | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_EXECUTE | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_DELETE_CHILD | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_READ_ATTRIBUTES | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_WRITE_ATTRIBUTES | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_DELETE | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_READ_ACL | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_WRITE_ACL | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_WRITE_OWNER | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_SYNCHRONIZE)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACE_MASK_UNDEFINED 0x80000000
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks#define ACE_VALID_FLAG_BITS (ACE_FILE_INHERIT_ACE | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_DIRECTORY_INHERIT_ACE | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_NO_PROPAGATE_INHERIT_ACE | ACE_INHERIT_ONLY_ACE | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_SUCCESSFUL_ACCESS_ACE_FLAG | ACE_FAILED_ACCESS_ACE_FLAG | \
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_IDENTIFIER_GROUP | ACE_OWNER | ACE_GROUP | ACE_EVERYONE)
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks/*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * ACL conversion helpers
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491markstypedef enum {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_unused,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_user_obj,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_user,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_group, /* includes GROUP and GROUP_OBJ */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_other_obj
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks} ace_to_aent_state_t;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491markstypedef struct acevals {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uid_t key;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_node_t avl;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uint32_t mask;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uint32_t allowed;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uint32_t denied;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int aent_type;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks} acevals_t;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491markstypedef struct ace_list {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_t user_obj;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_tree_t user;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int numusers;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_t group_obj;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_tree_t group;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int numgroups;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_t other_obj;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uint32_t acl_mask;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int hasmask;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int dfacl_flag;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_to_aent_state_t state;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int seen; /* bitmask of all aclent_t a_type values seen */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks} ace_list_t;
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef union {
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *file;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int fd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} acl_inp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_t *
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_alloc(enum acl_type type)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_t *aclp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp = malloc(sizeof (acl_t));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_aclp = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_cnt = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (type) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ACE_T:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_type = ACE_T;
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_entry_size = sizeof (ace_t);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ACLENT_T:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_type = ACLENT_T;
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_entry_size = sizeof (aclent_t);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_free(aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Free acl_t structure
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_free(acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclp->acl_aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(aclp->acl_aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Determine whether a file has a trivial ACL
fa9e4066f08beec538e775443c5be79dd423fcabahrens * returns: 0 = trivial
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 1 = nontrivial
fa9e4066f08beec538e775443c5be79dd423fcabahrens * <0 some other system failure, such as ENOENT or EPERM
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_trivial(const char *filename)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int acl_flavor;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int aclcnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int cntcmd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int val = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t *acep;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_flavor = pathconf(filename, _PC_ACL_ENABLED);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_flavor == _ACL_ACE_ENABLED)
fa9e4066f08beec538e775443c5be79dd423fcabahrens cntcmd = ACE_GETACLCNT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens cntcmd = GETACLCNT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclcnt = acl(filename, cntcmd, 0, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclcnt > 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_flavor == _ACL_ACE_ENABLED) {
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks acep = malloc(sizeof (ace_t) * aclcnt);
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks if (acep == NULL)
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks return (-1);
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks if (acl(filename, ACE_GETACL,
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks aclcnt, acep) < 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(acep);
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks val = ace_trivial(acep, aclcnt);
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks free(acep);
d2443e765650e70b88cd0346e67d2aee6dd1ea3amarks
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (aclcnt > MIN_ACL_ENTRIES)
fa9e4066f08beec538e775443c5be79dd423fcabahrens val = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (val);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic uint32_t
fa9e4066f08beec538e775443c5be79dd423fcabahrensaccess_mask_set(int haswriteperm, int hasreadperm, int isowner, int isallow)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint32_t access_mask = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int acl_produce;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int synchronize_set = 0, write_owner_set = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int delete_set = 0, write_attrs_set = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int read_named_set = 0, write_named_set = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_produce = (ACL_SYNCHRONIZE_SET_ALLOW |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACL_WRITE_ATTRS_WRITER_SET_DENY);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (isallow) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens synchronize_set = ACL_SYNCHRONIZE_SET_ALLOW;
fa9e4066f08beec538e775443c5be79dd423fcabahrens write_owner_set = ACL_WRITE_OWNER_SET_ALLOW;
fa9e4066f08beec538e775443c5be79dd423fcabahrens delete_set = ACL_DELETE_SET_ALLOW;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (hasreadperm)
fa9e4066f08beec538e775443c5be79dd423fcabahrens read_named_set = ACL_READ_NAMED_READER_SET_ALLOW;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (haswriteperm)
fa9e4066f08beec538e775443c5be79dd423fcabahrens write_named_set = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (isowner)
fa9e4066f08beec538e775443c5be79dd423fcabahrens write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (haswriteperm)
fa9e4066f08beec538e775443c5be79dd423fcabahrens write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens synchronize_set = ACL_SYNCHRONIZE_SET_DENY;
fa9e4066f08beec538e775443c5be79dd423fcabahrens write_owner_set = ACL_WRITE_OWNER_SET_DENY;
fa9e4066f08beec538e775443c5be79dd423fcabahrens delete_set = ACL_DELETE_SET_DENY;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (hasreadperm)
fa9e4066f08beec538e775443c5be79dd423fcabahrens read_named_set = ACL_READ_NAMED_READER_SET_DENY;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (haswriteperm)
fa9e4066f08beec538e775443c5be79dd423fcabahrens write_named_set = ACL_WRITE_NAMED_WRITER_SET_DENY;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (isowner)
fa9e4066f08beec538e775443c5be79dd423fcabahrens write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_DENY;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (haswriteperm)
fa9e4066f08beec538e775443c5be79dd423fcabahrens write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_DENY;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If the entity is not the owner and does not
fa9e4066f08beec538e775443c5be79dd423fcabahrens * have write permissions ACE_WRITE_ATTRIBUTES will
fa9e4066f08beec538e775443c5be79dd423fcabahrens * always go in the DENY ACE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens access_mask |= ACE_WRITE_ATTRIBUTES;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_produce & synchronize_set)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access_mask |= ACE_SYNCHRONIZE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_produce & write_owner_set)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access_mask |= ACE_WRITE_OWNER;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_produce & delete_set)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access_mask |= ACE_DELETE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_produce & write_attrs_set)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access_mask |= ACE_WRITE_ATTRIBUTES;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_produce & read_named_set)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access_mask |= ACE_READ_NAMED_ATTRS;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_produce & write_named_set)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access_mask |= ACE_WRITE_NAMED_ATTRS;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (access_mask);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given an mode_t, convert it into an access_mask as used
fa9e4066f08beec538e775443c5be79dd423fcabahrens * by nfsace, assuming aclent_t -> nfsace semantics.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic uint32_t
fa9e4066f08beec538e775443c5be79dd423fcabahrensmode_to_ace_access(mode_t mode, int isdir, int isowner, int isallow)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint32_t access = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int haswriteperm = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int hasreadperm = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (isallow) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens haswriteperm = (mode & 02);
fa9e4066f08beec538e775443c5be79dd423fcabahrens hasreadperm = (mode & 04);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens haswriteperm = !(mode & 02);
fa9e4066f08beec538e775443c5be79dd423fcabahrens hasreadperm = !(mode & 04);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The following call takes care of correctly setting the following
fa9e4066f08beec538e775443c5be79dd423fcabahrens * mask bits in the access_mask:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ACE_SYNCHRONIZE, ACE_WRITE_OWNER, ACE_DELETE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ACE_WRITE_ATTRIBUTES, ACE_WRITE_NAMED_ATTRS, ACE_READ_NAMED_ATTRS
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens access = access_mask_set(haswriteperm, hasreadperm, isowner, isallow);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (isallow) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens access |= ACE_READ_ACL | ACE_READ_ATTRIBUTES;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (isowner)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access |= ACE_WRITE_ACL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (! isowner)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access |= ACE_WRITE_ACL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* read */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mode & 04) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens access |= ACE_READ_DATA;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* write */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mode & 02) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens access |= ACE_WRITE_DATA |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_APPEND_DATA;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (isdir)
fa9e4066f08beec538e775443c5be79dd423fcabahrens access |= ACE_DELETE_CHILD;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* exec */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mode & 01) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens access |= ACE_EXECUTE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (access);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given an nfsace (presumably an ALLOW entry), make a
fa9e4066f08beec538e775443c5be79dd423fcabahrens * corresponding DENY entry at the address given.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensace_make_deny(ace_t *allow, ace_t *deny, int isdir, int isowner)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memcpy(deny, allow, sizeof (ace_t));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens deny->a_who = allow->a_who;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens deny->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens deny->a_access_mask ^= ACE_POSIX_SUPPORTED_BITS;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (isdir)
fa9e4066f08beec538e775443c5be79dd423fcabahrens deny->a_access_mask ^= ACE_DELETE_CHILD;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens deny->a_access_mask &= ~(ACE_SYNCHRONIZE | ACE_WRITE_OWNER |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_DELETE | ACE_WRITE_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_WRITE_NAMED_ATTRS);
fa9e4066f08beec538e775443c5be79dd423fcabahrens deny->a_access_mask |= access_mask_set((allow->a_access_mask &
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_WRITE_DATA), (allow->a_access_mask & ACE_READ_DATA), isowner,
fa9e4066f08beec538e775443c5be79dd423fcabahrens B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Make an initial pass over an array of aclent_t's. Gather
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information such as an ACL_MASK (if any), number of users,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * number of groups, and whether the array needs to be sorted.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensln_aent_preprocess(aclent_t *aclent, int n,
fa9e4066f08beec538e775443c5be79dd423fcabahrens int *hasmask, mode_t *mask,
fa9e4066f08beec538e775443c5be79dd423fcabahrens int *numuser, int *numgroup, int *needsort)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int error = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int curtype = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens *hasmask = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *mask = 07;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *needsort = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *numuser = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *numgroup = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < n; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type < curtype)
fa9e4066f08beec538e775443c5be79dd423fcabahrens *needsort = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (aclent[i].a_type > curtype)
fa9e4066f08beec538e775443c5be79dd423fcabahrens curtype = aclent[i].a_type;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & USER)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (*numuser)++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & (GROUP | GROUP_OBJ))
fa9e4066f08beec538e775443c5be79dd423fcabahrens (*numgroup)++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & CLASS_OBJ) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*hasmask) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = EINVAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto out;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens *hasmask = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *mask = aclent[i].a_perm;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((! *hasmask) && (*numuser + *numgroup > 1)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = EINVAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto out;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensout:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (error);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Convert an array of aclent_t into an array of nfsace entries,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * following POSIX draft -> nfsv4 conversion semantics as outlined in
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the IETF draft.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensln_aent_to_ace(aclent_t *aclent, int n, ace_t **acepp, int *rescount, int isdir)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int error = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens mode_t mask;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int numuser, numgroup, needsort;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int resultsize = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i, groupi = 0, skip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t *acep, *result = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int hasmask;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = ln_aent_preprocess(aclent, n, &hasmask, &mask,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &numuser, &numgroup, &needsort);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto out;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* allow + deny for each aclent */
fa9e4066f08beec538e775443c5be79dd423fcabahrens resultsize = n * 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (hasmask) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * stick extra deny on the group_obj and on each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * user|group for the mask (the group_obj was added
fa9e4066f08beec538e775443c5be79dd423fcabahrens * into the count for numgroup)
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens resultsize += numuser + numgroup;
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* ... and don't count the mask itself */
fa9e4066f08beec538e775443c5be79dd423fcabahrens resultsize -= 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* sort the source if necessary */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (needsort)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ksort((caddr_t)aclent, n, sizeof (aclent_t), cmp2acls);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens result = acep = calloc(1, resultsize * sizeof (ace_t));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (result == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto out;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < n; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * don't process CLASS_OBJ (mask); mask was grabbed in
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ln_aent_preprocess()
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & CLASS_OBJ)
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* If we need an ACL_MASK emulator, prepend it now */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((hasmask) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens (aclent[i].a_type & (USER | GROUP | GROUP_OBJ))) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & GROUP_OBJ) {
f48205be61a214698b763ff550ab9e657525104ccasper acep->a_who = (uid_t)-1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags |=
fa9e4066f08beec538e775443c5be79dd423fcabahrens (ACE_IDENTIFIER_GROUP|ACE_GROUP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (aclent[i].a_type & USER) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_who = aclent[i].a_id;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_who = aclent[i].a_id;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags |= ACE_IDENTIFIER_GROUP;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & ACL_DEFAULT) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags |= ACE_INHERIT_ONLY_ACE |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_FILE_INHERIT_ACE |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_DIRECTORY_INHERIT_ACE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Set the access mask for the prepended deny
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ace. To do this, we invert the mask (found
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in ln_aent_preprocess()) then convert it to an
fa9e4066f08beec538e775443c5be79dd423fcabahrens * DENY ace access_mask.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_access_mask = mode_to_ace_access((mask ^ 07),
fa9e4066f08beec538e775443c5be79dd423fcabahrens isdir, 0, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep += 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* handle a_perm -> access_mask */
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_access_mask = mode_to_ace_access(aclent[i].a_perm,
fa9e4066f08beec538e775443c5be79dd423fcabahrens isdir, aclent[i].a_type & USER_OBJ, 1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* emulate a default aclent */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & ACL_DEFAULT) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags |= ACE_INHERIT_ONLY_ACE |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_FILE_INHERIT_ACE |
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_DIRECTORY_INHERIT_ACE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * handle a_perm and a_id
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * this must be done last, since it involves the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * corresponding deny aces, which are handled
fa9e4066f08beec538e775443c5be79dd423fcabahrens * differently for each different a_type.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & USER_OBJ) {
f48205be61a214698b763ff550ab9e657525104ccasper acep->a_who = (uid_t)-1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags |= ACE_OWNER;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_make_deny(acep, acep + 1, isdir, B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep += 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (aclent[i].a_type & USER) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_who = aclent[i].a_id;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_make_deny(acep, acep + 1, isdir, B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep += 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (aclent[i].a_type & (GROUP_OBJ | GROUP)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclent[i].a_type & GROUP_OBJ) {
f48205be61a214698b763ff550ab9e657525104ccasper acep->a_who = (uid_t)-1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags |= ACE_GROUP;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_who = aclent[i].a_id;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags |= ACE_IDENTIFIER_GROUP;
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Set the corresponding deny for the group ace.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The deny aces go after all of the groups, unlike
fa9e4066f08beec538e775443c5be79dd423fcabahrens * everything else, where they immediately follow
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the allow ace.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We calculate "skip", the number of slots to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * skip ahead for the deny ace, here.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The pattern is:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * MD1 A1 MD2 A2 MD3 A3 D1 D2 D3
fa9e4066f08beec538e775443c5be79dd423fcabahrens * thus, skip is
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (2 * numgroup) - 1 - groupi
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (2 * numgroup) to account for MD + A
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - 1 to account for the fact that we're on the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * access (A), not the mask (MD)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - groupi to account for the fact that we have
fa9e4066f08beec538e775443c5be79dd423fcabahrens * passed up groupi number of MD's.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens skip = (2 * numgroup) - 1 - groupi;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_make_deny(acep, acep + skip, isdir, B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we just did the last group, skip acep past
fa9e4066f08beec538e775443c5be79dd423fcabahrens * all of the denies; else, just move ahead one.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (++groupi >= numgroup)
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep += numgroup + 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep += 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (aclent[i].a_type & OTHER_OBJ) {
f48205be61a214698b763ff550ab9e657525104ccasper acep->a_who = (uid_t)-1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_flags |= ACE_EVERYONE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_make_deny(acep, acep + 1, isdir, B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep += 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = EINVAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto out;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens *acepp = result;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *rescount = resultsize;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensout:
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((result != NULL) && (resultsize > 0)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(result);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (error);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensconvert_aent_to_ace(aclent_t *aclentp, int aclcnt, int isdir,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t **retacep, int *retacecnt)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t *acep;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t *dfacep;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int acecnt = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int dfacecnt = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int dfaclstart = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int dfaclcnt = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_t *aclp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int error;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ksort((caddr_t)aclentp, aclcnt, sizeof (aclent_t), cmp2acls);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0, aclp = aclentp; i < aclcnt; aclp++, i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclp->a_type & ACL_DEFAULT)
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (i < aclcnt) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dfaclstart = i;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dfaclcnt = aclcnt - i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (dfaclcnt && isdir == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = ln_aent_to_ace(aclentp, i, &acep, &acecnt, isdir);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (dfaclcnt) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = ln_aent_to_ace(&aclentp[dfaclstart], dfaclcnt,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &dfacep, &dfacecnt, isdir);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acep) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(acep);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (dfacecnt != 0) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acep = realloc(acep, sizeof (ace_t) * (acecnt + dfacecnt));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep == NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (-1);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (dfaclcnt) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (void) memcpy(acep + acecnt, dfacep,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks sizeof (ace_t) * dfacecnt);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (dfaclcnt)
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(dfacep);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens *retacecnt = acecnt + dfacecnt;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *retacep = acep;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic void
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksacevals_init(acevals_t *vals, uid_t key)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks bzero(vals, sizeof (*vals));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->allowed = ACE_MASK_UNDEFINED;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->denied = ACE_MASK_UNDEFINED;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->mask = ACE_MASK_UNDEFINED;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->key = key;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic void
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksace_list_init(ace_list_t *al, int dfacl_flag)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_init(&al->user_obj, NULL);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_init(&al->group_obj, NULL);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_init(&al->other_obj, NULL);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks al->numusers = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks al->numgroups = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks al->acl_mask = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks al->hasmask = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks al->state = ace_unused;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks al->seen = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks al->dfacl_flag = dfacl_flag;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks/*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * Find or create an acevals holder for a given id and avl tree.
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * Note that only one thread will ever touch these avl trees, so
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * there is no need for locking.
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic acevals_t *
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksacevals_find(ace_t *ace, avl_tree_t *avl, int *num)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_t key, *rc;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_index_t where;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks key.key = ace->a_who;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks rc = avl_find(avl, &key, &where);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (rc != NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (rc);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* this memory is freed by ln_ace_to_aent()->ace_list_free() */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks rc = calloc(1, sizeof (acevals_t));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (rc == NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (rc);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_init(rc, ace->a_who);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_insert(avl, rc, where);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (*num)++;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (rc);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksaccess_mask_check(ace_t *acep, int mask_bit, int isowner)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int set_deny, err_deny;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int set_allow, err_allow;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int acl_consume;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int haswriteperm, hasreadperm;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks haswriteperm = (acep->a_access_mask & ACE_WRITE_DATA) ? 0 : 1;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks hasreadperm = (acep->a_access_mask & ACE_READ_DATA) ? 0 : 1;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks haswriteperm = (acep->a_access_mask & ACE_WRITE_DATA) ? 1 : 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks hasreadperm = (acep->a_access_mask & ACE_READ_DATA) ? 1 : 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl_consume = (ACL_SYNCHRONIZE_ERR_DENY |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_DELETE_ERR_DENY |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_WRITE_OWNER_ERR_DENY |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_WRITE_OWNER_ERR_ALLOW |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_WRITE_ATTRS_OWNER_ERR_DENY |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_WRITE_ATTRS_WRITER_SET_DENY |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_WRITE_ATTRS_WRITER_ERR_ALLOW |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_WRITE_NAMED_WRITER_ERR_DENY |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACL_READ_NAMED_READER_ERR_DENY);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (mask_bit == ACE_SYNCHRONIZE) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_deny = ACL_SYNCHRONIZE_SET_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_deny = ACL_SYNCHRONIZE_ERR_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_allow = ACL_SYNCHRONIZE_SET_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_allow = ACL_SYNCHRONIZE_ERR_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (mask_bit == ACE_WRITE_OWNER) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_deny = ACL_WRITE_OWNER_SET_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_deny = ACL_WRITE_OWNER_ERR_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_allow = ACL_WRITE_OWNER_SET_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_allow = ACL_WRITE_OWNER_ERR_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (mask_bit == ACE_DELETE) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_deny = ACL_DELETE_SET_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_deny = ACL_DELETE_ERR_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_allow = ACL_DELETE_SET_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_allow = ACL_DELETE_ERR_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (mask_bit == ACE_WRITE_ATTRIBUTES) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (isowner) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_deny = ACL_WRITE_ATTRS_OWNER_SET_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_deny = ACL_WRITE_ATTRS_OWNER_ERR_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_allow = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_allow = ACL_WRITE_ATTRS_OWNER_ERR_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (haswriteperm) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_deny = ACL_WRITE_ATTRS_WRITER_SET_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_deny = ACL_WRITE_ATTRS_WRITER_ERR_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_allow = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_allow = ACL_WRITE_ATTRS_WRITER_ERR_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_access_mask & mask_bit) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (acep->a_type & ACE_ACCESS_ALLOWED_ACE_TYPE)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (ENOTSUP);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (0);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (mask_bit == ACE_READ_NAMED_ATTRS) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!hasreadperm)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (0);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_deny = ACL_READ_NAMED_READER_SET_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_deny = ACL_READ_NAMED_READER_ERR_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_allow = ACL_READ_NAMED_READER_SET_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_allow = ACL_READ_NAMED_READER_ERR_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (mask_bit == ACE_WRITE_NAMED_ATTRS) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!haswriteperm)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (0);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_deny = ACL_WRITE_NAMED_WRITER_SET_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_deny = ACL_WRITE_NAMED_WRITER_ERR_DENY;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks set_allow = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks err_allow = ACL_WRITE_NAMED_WRITER_ERR_ALLOW;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (EINVAL);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acl_consume & set_deny) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!(acep->a_access_mask & mask_bit)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (ENOTSUP);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (acl_consume & err_deny) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_access_mask & mask_bit) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (ENOTSUP);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* ACE_ACCESS_ALLOWED_ACE_TYPE */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acl_consume & set_allow) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!(acep->a_access_mask & mask_bit)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (ENOTSUP);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (acl_consume & err_allow) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_access_mask & mask_bit) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (ENOTSUP);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (0);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksace_to_aent_legal(ace_t *acep)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int error = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int isowner;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* only ALLOW or DENY */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (acep->a_type != ACE_ACCESS_DENIED_ACE_TYPE)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* check for invalid flags */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_flags & ~(ACE_VALID_FLAG_BITS)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* some flags are illegal */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_flags & (ACE_SUCCESSFUL_ACCESS_ACE_FLAG |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_FAILED_ACCESS_ACE_FLAG |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_NO_PROPAGATE_INHERIT_ACE)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* check for invalid masks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_access_mask & ~(ACE_VALID_MASK_BITS)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_flags & ACE_OWNER)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks isowner = 1;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks isowner = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = access_mask_check(acep, ACE_SYNCHRONIZE, isowner);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = access_mask_check(acep, ACE_WRITE_OWNER, isowner);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = access_mask_check(acep, ACE_DELETE, isowner);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = access_mask_check(acep, ACE_WRITE_ATTRIBUTES, isowner);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = access_mask_check(acep, ACE_READ_NAMED_ATTRS, isowner);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = access_mask_check(acep, ACE_WRITE_NAMED_ATTRS, isowner);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* more detailed checking of masks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (! (acep->a_access_mask & ACE_READ_ATTRIBUTES)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_access_mask & ACE_WRITE_DATA) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (! (acep->a_access_mask & ACE_APPEND_DATA))) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((! (acep->a_access_mask & ACE_WRITE_DATA)) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (acep->a_access_mask & ACE_APPEND_DATA)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* ACL enforcement */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_access_mask & ACE_READ_ACL) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (acep->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_access_mask & ACE_WRITE_ACL) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (isowner)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (! isowner)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksout:
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (error);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksace_mask_to_mode(uint32_t mask, o_mode_t *modep, int isdir)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int error = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks o_mode_t mode = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uint32_t bits, wantbits;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* read */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (mask & ACE_READ_DATA)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks mode |= 04;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* write */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks wantbits = (ACE_WRITE_DATA | ACE_APPEND_DATA);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (isdir)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks wantbits |= ACE_DELETE_CHILD;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks bits = mask & wantbits;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (bits != 0) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (bits != wantbits) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks mode |= 02;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* exec */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (mask & ACE_EXECUTE) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks mode |= 01;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *modep = mode;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksout:
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (error);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksace_allow_to_mode(uint32_t mask, o_mode_t *modep, int isdir)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* ACE_READ_ACL and ACE_READ_ATTRIBUTES must both be set */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((mask & (ACE_READ_ACL | ACE_READ_ATTRIBUTES)) !=
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (ACE_READ_ACL | ACE_READ_ATTRIBUTES)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (ENOTSUP);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (ace_mask_to_mode(mask, modep, isdir));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksacevals_to_aent(acevals_t *vals, aclent_t *dest, ace_list_t *list,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uid_t owner, gid_t group, int isdir)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int error;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uint32_t flips = ACE_POSIX_SUPPORTED_BITS;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (isdir)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks flips |= ACE_DELETE_CHILD;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (vals->allowed != (vals->denied ^ flips)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((list->hasmask) && (list->acl_mask != vals->mask) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (vals->aent_type & (USER | GROUP | GROUP_OBJ))) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ace_allow_to_mode(vals->allowed, &dest->a_perm, isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dest->a_type = vals->aent_type;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (dest->a_type & (USER | GROUP)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dest->a_id = vals->key;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (dest->a_type & USER_OBJ) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dest->a_id = owner;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (dest->a_type & GROUP_OBJ) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dest->a_id = group;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (dest->a_type & OTHER_OBJ) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dest->a_id = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksout:
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (error);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksace_list_to_aent(ace_list_t *list, aclent_t **aclentp, int *aclcnt,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uid_t owner, gid_t group, int isdir)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int error = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclent_t *aent, *result = NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_t *vals;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int resultcount;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((list->seen & (USER_OBJ | GROUP_OBJ | OTHER_OBJ)) !=
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (USER_OBJ | GROUP_OBJ | OTHER_OBJ)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((! list->hasmask) && (list->numusers + list->numgroups > 0)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks resultcount = 3 + list->numusers + list->numgroups;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * This must be the same condition as below, when we add the CLASS_OBJ
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * (aka ACL mask)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((list->hasmask) || (! list->dfacl_flag))
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks resultcount += 1;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks result = aent = calloc(1, resultcount * sizeof (aclent_t));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (result == NULL) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOMEM;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* USER_OBJ */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!(list->user_obj.aent_type & USER_OBJ)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = acevals_to_aent(&list->user_obj, aent, list, owner, group,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ++aent;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* USER */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks for (vals = avl_first(&list->user); vals != NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = AVL_NEXT(&list->user, vals)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!(vals->aent_type & USER)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = acevals_to_aent(vals, aent, list, owner, group,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ++aent;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* GROUP_OBJ */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!(list->group_obj.aent_type & GROUP_OBJ)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = acevals_to_aent(&list->group_obj, aent, list, owner, group,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ++aent;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* GROUP */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks for (vals = avl_first(&list->group); vals != NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = AVL_NEXT(&list->group, vals)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!(vals->aent_type & GROUP)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = acevals_to_aent(vals, aent, list, owner, group,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ++aent;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * CLASS_OBJ (aka ACL_MASK)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * An ACL_MASK is not fabricated if the ACL is a default ACL.
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * This is to follow UFS's behavior.
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((list->hasmask) || (! list->dfacl_flag)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (list->hasmask) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uint32_t flips = ACE_POSIX_SUPPORTED_BITS;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (isdir)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks flips |= ACE_DELETE_CHILD;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ace_mask_to_mode(list->acl_mask ^ flips,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks &aent->a_perm, isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* fabricate the ACL_MASK from the group permissions */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ace_mask_to_mode(list->group_obj.allowed,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks &aent->a_perm, isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aent->a_id = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aent->a_type = CLASS_OBJ | list->dfacl_flag;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ++aent;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* OTHER_OBJ */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!(list->other_obj.aent_type & OTHER_OBJ)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = acevals_to_aent(&list->other_obj, aent, list, owner, group,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ++aent;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *aclentp = result;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *aclcnt = resultcount;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksout:
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (result != NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks free(result);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (error);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks/*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * free all data associated with an ace_list
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic void
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksace_list_free(ace_list_t *al)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_t *node;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks void *cookie;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (al == NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks cookie = NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks while ((node = avl_destroy_nodes(&al->user, &cookie)) != NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks free(node);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks cookie = NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks while ((node = avl_destroy_nodes(&al->group, &cookie)) != NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks free(node);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_destroy(&al->user);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_destroy(&al->group);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* free the container itself */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks free(al);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksacevals_compare(const void *va, const void *vb)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks const acevals_t *a = va, *b = vb;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (a->key == b->key)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (0);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (a->key > b->key)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (1);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks else
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (-1);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks/*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * Convert a list of ace_t entries to equivalent regular and default
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * aclent_t lists. Return error (ENOTSUP) when conversion is not possible.
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksln_ace_to_aent(ace_t *ace, int n, uid_t owner, gid_t group,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclent_t **aclentp, int *aclcnt, aclent_t **dfaclentp, int *dfaclcnt,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int isdir)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int error = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_t *acep;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uint32_t bits;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int i;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_list_t *normacl = NULL, *dfacl = NULL, *acl;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acevals_t *vals;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *aclentp = NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *aclcnt = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *dfaclentp = NULL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *dfaclcnt = 0;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* we need at least user_obj, group_obj, and other_obj */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (n < 6) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (ace == NULL) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks normacl = calloc(1, sizeof (ace_list_t));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (normacl == NULL) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = errno;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_create(&normacl->user, acevals_compare, sizeof (acevals_t),
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks offsetof(acevals_t, avl));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_create(&normacl->group, acevals_compare, sizeof (acevals_t),
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks offsetof(acevals_t, avl));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_list_init(normacl, 0);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dfacl = calloc(1, sizeof (ace_list_t));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (dfacl == NULL) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = errno;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_create(&dfacl->user, acevals_compare, sizeof (acevals_t),
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks offsetof(acevals_t, avl));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks avl_create(&dfacl->group, acevals_compare, sizeof (acevals_t),
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks offsetof(acevals_t, avl));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_list_init(dfacl, ACL_DEFAULT);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* process every ace_t... */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks for (i = 0; i < n; i++) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acep = &ace[i];
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* rule out certain cases quickly */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ace_to_aent_legal(acep);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * Turn off these bits in order to not have to worry about
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * them when doing the checks for compliments.
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acep->a_access_mask &= ~(ACE_WRITE_OWNER | ACE_DELETE |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_SYNCHRONIZE | ACE_WRITE_ATTRIBUTES |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_READ_NAMED_ATTRS | ACE_WRITE_NAMED_ATTRS);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* see if this should be a regular or default acl */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks bits = acep->a_flags &
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (ACE_INHERIT_ONLY_ACE |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_FILE_INHERIT_ACE |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_DIRECTORY_INHERIT_ACE);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (bits != 0) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* all or nothing on these inherit bits */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (bits != (ACE_INHERIT_ONLY_ACE |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_FILE_INHERIT_ACE |
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ACE_DIRECTORY_INHERIT_ACE)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl = dfacl;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl = normacl;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_flags & ACE_OWNER)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acl->state > ace_user_obj) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->state = ace_user_obj;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->seen |= USER_OBJ;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = &acl->user_obj;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->aent_type = USER_OBJ | acl->dfacl_flag;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if ((acep->a_flags & ACE_EVERYONE)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->state = ace_other_obj;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->seen |= OTHER_OBJ;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = &acl->other_obj;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->aent_type = OTHER_OBJ | acl->dfacl_flag;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (acep->a_flags & ACE_IDENTIFIER_GROUP) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acl->state > ace_group) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acep->a_flags & ACE_GROUP)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->seen |= GROUP_OBJ;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = &acl->group_obj;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->aent_type = GROUP_OBJ | acl->dfacl_flag;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->seen |= GROUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = acevals_find(acep, &acl->group,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks &acl->numgroups);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (vals == NULL) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOMEM;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->aent_type = GROUP | acl->dfacl_flag;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->state = ace_group;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acl->state > ace_user) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->state = ace_user;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->seen |= USER;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals = acevals_find(acep, &acl->user,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks &acl->numusers);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (vals == NULL) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOMEM;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->aent_type = USER | acl->dfacl_flag;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (!(acl->state > ace_unused)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = EINVAL;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* no more than one allowed per aclent_t */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (vals->allowed != ACE_MASK_UNDEFINED) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->allowed = acep->a_access_mask;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * it's a DENY; if there was a previous DENY, it
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * must have been an ACL_MASK.
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (vals->denied != ACE_MASK_UNDEFINED) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* ACL_MASK is for USER and GROUP only */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((acl->state != ace_user) &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (acl->state != ace_group)) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (! acl->hasmask) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->hasmask = 1;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks acl->acl_mask = vals->denied;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* check for mismatched ACL_MASK emulations */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (acl->acl_mask != vals->denied) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->mask = vals->denied;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks vals->denied = acep->a_access_mask;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /* done collating; produce the aclent_t lists */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (normacl->state != ace_unused) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ace_list_to_aent(normacl, aclentp, aclcnt,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks owner, group, isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (dfacl->state != ace_unused) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ace_list_to_aent(dfacl, dfaclentp, dfaclcnt,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks owner, group, isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error != 0) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks goto out;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksout:
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (normacl != NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_list_free(normacl);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (dfacl != NULL)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks ace_list_free(dfacl);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (error);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksconvert_ace_to_aent(ace_t *acebufp, int acecnt, int isdir,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks uid_t owner, gid_t group, aclent_t **retaclentp, int *retaclcnt)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int error;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclent_t *aclentp, *dfaclentp;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int aclcnt, dfaclcnt;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = ln_ace_to_aent(acebufp, acecnt, owner, group,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks &aclentp, &aclcnt, &dfaclentp, &dfaclcnt, isdir);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (error);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (dfaclcnt != 0) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * Slap aclentp and dfaclentp into a single array.
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclentp = realloc(aclentp, (sizeof (aclent_t) * aclcnt) +
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (sizeof (aclent_t) * dfaclcnt));
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (aclentp != NULL) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (void) memcpy(aclentp + aclcnt,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks dfaclentp, sizeof (aclent_t) * dfaclcnt);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = -1;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (aclentp) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *retaclentp = aclentp;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks *retaclcnt = aclcnt + dfaclcnt;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (dfaclentp)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks free(dfaclentp);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (error);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
0157963dec6f442e8566c5903063c99c18ac358bmarksstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrenscacl_get(acl_inp inp, int get_flag, int type, acl_t **aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *fname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int fd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ace_acl = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int error;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int getcmd, cntcmd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_t *acl_info;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int save_errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int stat_error;
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct stat64 statbuf;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens *aclp = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (type == ACL_PATH) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens fname = inp.file;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_acl = pathconf(fname, _PC_ACL_ENABLED);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens fd = inp.fd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_acl = fpathconf(fd, _PC_ACL_ENABLED);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if acl's aren't supported then
fa9e4066f08beec538e775443c5be79dd423fcabahrens * send it through the old GETACL interface
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks if (ace_acl == 0 || ace_acl == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_acl = _ACL_ACLENT_ENABLED;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace_acl & _ACL_ACE_ENABLED) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens cntcmd = ACE_GETACLCNT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens getcmd = ACE_GETACL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info = acl_alloc(ACE_T);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens cntcmd = GETACLCNT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens getcmd = GETACL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info = acl_alloc(ACLENT_T);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_info == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (type == ACL_PATH) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_cnt = acl(fname, cntcmd, 0, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_cnt = facl(fd, cntcmd, 0, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens save_errno = errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_info->acl_cnt < 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_free(acl_info);
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = save_errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_info->acl_cnt == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_free(acl_info);
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = save_errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_aclp =
fa9e4066f08beec538e775443c5be79dd423fcabahrens malloc(acl_info->acl_cnt * acl_info->acl_entry_size);
fa9e4066f08beec538e775443c5be79dd423fcabahrens save_errno = errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_info->acl_aclp == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_free(acl_info);
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = save_errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (type == ACL_PATH) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens stat_error = stat64(fname, &statbuf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = acl(fname, getcmd, acl_info->acl_cnt,
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens stat_error = fstat64(fd, &statbuf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = facl(fd, getcmd, acl_info->acl_cnt,
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens save_errno = errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_free(acl_info);
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = save_errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (stat_error == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_flags =
fa9e4066f08beec538e775443c5be79dd423fcabahrens (S_ISDIR(statbuf.st_mode) ? ACL_IS_DIR : 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_flags = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (acl_info->acl_type) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ACLENT_T:
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_info->acl_cnt <= MIN_ACL_ENTRIES)
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_flags |= ACL_IS_TRIVIAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ACE_T:
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace_trivial(acl_info->acl_aclp, acl_info->acl_cnt) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_info->acl_flags |= ACL_IS_TRIVIAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = EINVAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_free(acl_info);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((acl_info->acl_flags & ACL_IS_TRIVIAL) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens (get_flag & ACL_NO_TRIVIAL)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_free(acl_info);
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens *aclp = acl_info;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * return -1 on failure, otherwise the number of acl
fa9e4066f08beec538e775443c5be79dd423fcabahrens * entries is returned
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_get(const char *path, int get_flag, acl_t **aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_inp acl_inp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_inp.file = path;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (cacl_get(acl_inp, get_flag, ACL_PATH, aclp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensfacl_get(int fd, int get_flag, acl_t **aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_inp acl_inp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_inp.fd = fd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (cacl_get(acl_inp, get_flag, ACL_FD, aclp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksstatic int
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marksacl_translate(acl_t *aclp, int target_flavor, int isdir, uid_t owner,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks gid_t group)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks{
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int aclcnt;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks void *acldata;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks int error;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * See if we need to translate
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((target_flavor == _ACL_ACE_ENABLED && aclp->acl_type == ACE_T) ||
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks (target_flavor == _ACL_ACLENT_ENABLED &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclp->acl_type == ACLENT_T))
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (0);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (target_flavor == -1)
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (-1);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (target_flavor == _ACL_ACE_ENABLED &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclp->acl_type == ACLENT_T) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = convert_aent_to_ace(aclp->acl_aclp,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclp->acl_cnt, isdir, (ace_t **)&acldata, &aclcnt);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks errno = error;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (-1);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else if (target_flavor == _ACL_ACLENT_ENABLED &&
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclp->acl_type == ACE_T) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks error = convert_ace_to_aent(aclp->acl_aclp, aclp->acl_cnt,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks isdir, owner, group, (aclent_t **)&acldata, &aclcnt);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if (error) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks errno = error;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (-1);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks } else {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks errno = ENOTSUP;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (-1);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks }
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks /*
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks * replace old acl with newly translated acl
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks */
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks free(aclp->acl_aclp);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclp->acl_aclp = acldata;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclp->acl_cnt = aclcnt;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks aclp->acl_type = (target_flavor == _ACL_ACE_ENABLED) ? ACE_T : ACLENT_T;
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (0);
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks}
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Set an ACL, translates acl to ace_t when appropriate.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrenscacl_set(acl_inp *acl_inp, acl_t *aclp, int type)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int error = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int acl_flavor_target;
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct stat64 statbuf;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int stat_error;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int isdir;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (type == ACL_PATH) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens stat_error = stat64(acl_inp->file, &statbuf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (stat_error)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_flavor_target = pathconf(acl_inp->file, _PC_ACL_ENABLED);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens stat_error = fstat64(acl_inp->fd, &statbuf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (stat_error)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_flavor_target = fpathconf(acl_inp->fd, _PC_ACL_ENABLED);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks /*
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * If target returns an error or 0 from pathconf call then
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * fall back to UFS/POSIX Draft interface.
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * In the case of 0 we will then fail in either acl(2) or
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * acl_translate(). We could erroneously get 0 back from
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * a file system that is using fs_pathconf() and not answering
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks * the _PC_ACL_ENABLED question itself.
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks */
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks if (acl_flavor_target == 0 || acl_flavor_target == -1)
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks acl_flavor_target = _ACL_ACLENT_ENABLED;
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks
fa9e4066f08beec538e775443c5be79dd423fcabahrens isdir = S_ISDIR(statbuf.st_mode);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks if ((error = acl_translate(aclp, acl_flavor_target, isdir,
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks statbuf.st_uid, statbuf.st_gid)) != 0) {
3eb3c57322eccc9d4c2880c26f57ceb5a85c2491marks return (error);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (type == ACL_PATH) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = acl(acl_inp->file,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (aclp->acl_type == ACE_T) ? ACE_SETACL : SETACL,
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_cnt, aclp->acl_aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = facl(acl_inp->fd,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (aclp->acl_type == ACE_T) ? ACE_SETACL : SETACL,
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_cnt, aclp->acl_aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (error);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_set(const char *path, acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_inp acl_inp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_inp.file = path;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (cacl_set(&acl_inp, aclp, ACL_PATH));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensfacl_set(int fd, acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_inp acl_inp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_inp.fd = fd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (cacl_set(&acl_inp, aclp, ACL_FD));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_cnt(acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (aclp->acl_cnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_type(acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (aclp->acl_type);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_t *
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_dup(acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_t *newaclp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens newaclp = acl_alloc(aclp->acl_type);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newaclp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens newaclp->acl_aclp = malloc(aclp->acl_entry_size * aclp->acl_cnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newaclp->acl_aclp == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_free(newaclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memcpy(newaclp->acl_aclp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_aclp, aclp->acl_entry_size * aclp->acl_cnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens newaclp->acl_cnt = aclp->acl_cnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (newaclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_flags(acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (aclp->acl_flags);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid *
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_data(acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (aclp->acl_aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
49f0e51890161901ae4f49c7a47602d97b52b934marks/*
49f0e51890161901ae4f49c7a47602d97b52b934marks * Take an acl array and build an acl_t.
49f0e51890161901ae4f49c7a47602d97b52b934marks */
49f0e51890161901ae4f49c7a47602d97b52b934marksacl_t *
49f0e51890161901ae4f49c7a47602d97b52b934marksacl_to_aclp(enum acl_type type, void *acl, int count)
49f0e51890161901ae4f49c7a47602d97b52b934marks{
49f0e51890161901ae4f49c7a47602d97b52b934marks acl_t *aclp;
49f0e51890161901ae4f49c7a47602d97b52b934marks
49f0e51890161901ae4f49c7a47602d97b52b934marks
49f0e51890161901ae4f49c7a47602d97b52b934marks aclp = acl_alloc(type);
49f0e51890161901ae4f49c7a47602d97b52b934marks if (aclp == NULL)
49f0e51890161901ae4f49c7a47602d97b52b934marks return (aclp);
49f0e51890161901ae4f49c7a47602d97b52b934marks
49f0e51890161901ae4f49c7a47602d97b52b934marks aclp->acl_aclp = acl;
49f0e51890161901ae4f49c7a47602d97b52b934marks aclp->acl_cnt = count;
49f0e51890161901ae4f49c7a47602d97b52b934marks
49f0e51890161901ae4f49c7a47602d97b52b934marks return (aclp);
49f0e51890161901ae4f49c7a47602d97b52b934marks}
49f0e51890161901ae4f49c7a47602d97b52b934marks
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Remove an ACL from a file and create a trivial ACL based
fa9e4066f08beec538e775443c5be79dd423fcabahrens * off of the mode argument. After acl has been set owner/group
fa9e4066f08beec538e775443c5be79dd423fcabahrens * are updated to match owner,group arguments
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_strip(const char *file, uid_t owner, gid_t group, mode_t mode)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int error = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_t min_acl[MIN_ACL_ENTRIES];
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t min_ace_acl[6]; /* owner, group, everyone + complement denies */
fa9e4066f08beec538e775443c5be79dd423fcabahrens int acl_flavor;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int aclcnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_flavor = pathconf(file, _PC_ACL_ENABLED);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * force it through aclent flavor when file system doesn't
fa9e4066f08beec538e775443c5be79dd423fcabahrens * understand question
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
a222db82aa8aaee84f3cba02cf799fe851fa7ac3marks if (acl_flavor == 0 || acl_flavor == -1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_flavor = _ACL_ACLENT_ENABLED;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_flavor & _ACL_ACLENT_ENABLED) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[0].a_type = USER_OBJ;
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[0].a_id = owner;
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[0].a_perm = ((mode & 0700) >> 6);
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[1].a_type = GROUP_OBJ;
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[1].a_id = group;
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[1].a_perm = ((mode & 0070) >> 3);
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[2].a_type = CLASS_OBJ;
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[2].a_id = (uid_t)-1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[2].a_perm = ((mode & 0070) >> 3);
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[3].a_type = OTHER_OBJ;
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[3].a_id = (uid_t)-1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens min_acl[3].a_perm = (mode & 0007);
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclcnt = 4;
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = acl(file, SETACL, aclcnt, min_acl);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (acl_flavor & _ACL_ACE_ENABLED) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memcpy(min_ace_acl, trivial_acl, sizeof (ace_t) * 6);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Make aces match request mode
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens adjust_ace_pair(&min_ace_acl[0], (mode & 0700) >> 6);
fa9e4066f08beec538e775443c5be79dd423fcabahrens adjust_ace_pair(&min_ace_acl[2], (mode & 0070) >> 3);
fa9e4066f08beec538e775443c5be79dd423fcabahrens adjust_ace_pair(&min_ace_acl[4], mode & 0007);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = acl(file, ACE_SETACL, 6, min_ace_acl);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = EINVAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = chown(file, owner, group);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (error);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensace_match(void *entry1, void *entry2)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t *p1 = (ace_t *)entry1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t *p2 = (ace_t *)entry2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_t ace1, ace2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace1 = *p1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace2 = *p2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Need to fixup who field for abstrations for
fa9e4066f08beec538e775443c5be79dd423fcabahrens * accurate comparison, since field is undefined.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace1.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
f48205be61a214698b763ff550ab9e657525104ccasper ace1.a_who = (uid_t)-1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace2.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
f48205be61a214698b763ff550ab9e657525104ccasper ace2.a_who = (uid_t)-1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (memcmp(&ace1, &ace2, sizeof (ace_t)));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensaclent_match(void *entry1, void *entry2)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_t *aclent1 = (aclent_t *)entry1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_t *aclent2 = (aclent_t *)entry2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (memcmp(aclent1, aclent2, sizeof (aclent_t)));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Find acl entries in acl that correspond to removeacl. Search
fa9e4066f08beec538e775443c5be79dd423fcabahrens * is started from slot. The flag argument indicates whether to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * remove all matches or just the first match.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_removeentries(acl_t *acl, acl_t *removeacl, int start_slot, int flag)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i, j;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int match;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int (*acl_match)(void *acl1, void *acl2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens void *acl_entry, *remove_entry;
fa9e4066f08beec538e775443c5be79dd423fcabahrens void *start;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int found = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (flag != ACL_REMOVE_ALL && flag != ACL_REMOVE_FIRST)
fa9e4066f08beec538e775443c5be79dd423fcabahrens flag = ACL_REMOVE_FIRST;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl == NULL || removeacl == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACL_NO_ACL_ENTRY);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl->acl_type != removeacl->acl_type)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACL_DIFF_TYPE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl->acl_type == ACLENT_T)
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_match = aclent_match;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_match = ace_match;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0, remove_entry = removeacl->acl_aclp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens i != removeacl->acl_cnt; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens j = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_entry = (char *)acl->acl_aclp +
fa9e4066f08beec538e775443c5be79dd423fcabahrens (acl->acl_entry_size * start_slot);
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (;;) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens match = acl_match(acl_entry, remove_entry);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (match == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens found++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens start = (char *)acl_entry +
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl->acl_entry_size;
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memmove(acl_entry, start,
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl->acl_entry_size *
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl->acl_cnt-- - (j + 1));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (flag == ACL_REMOVE_FIRST)
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * List has changed, restart search from
fa9e4066f08beec538e775443c5be79dd423fcabahrens * beginning.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_entry = acl->acl_aclp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens j = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl_entry = ((char *)acl_entry + acl->acl_entry_size);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (++j >= acl->acl_cnt) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ((found == 0) ? EACL_NO_ACL_ENTRY : 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Replace entires entries in acl1 with the corresponding entries
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in newentries. The where argument specifies where to begin
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the replacement. If the where argument is 1 greater than the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * number of acl entries in acl1 then they are appended. If the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * where argument is 2+ greater than the number of acl entries then
fa9e4066f08beec538e775443c5be79dd423fcabahrens * EACL_INVALID_SLOT is returned.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_modifyentries(acl_t *acl1, acl_t *newentries, int where)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens int slot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int slots_needed;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int slots_left;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int newsize;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl1 == NULL || newentries == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACL_NO_ACL_ENTRY);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (where < 0 || where >= acl1->acl_cnt)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACL_INVALID_SLOT);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl1->acl_type != newentries->acl_type)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACL_DIFF_TYPE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens slot = where;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens slots_left = acl1->acl_cnt - slot + 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (slots_left < newentries->acl_cnt) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens slots_needed = newentries->acl_cnt - slots_left;
fa9e4066f08beec538e775443c5be79dd423fcabahrens newsize = (acl1->acl_entry_size * acl1->acl_cnt) +
fa9e4066f08beec538e775443c5be79dd423fcabahrens (acl1->acl_entry_size * slots_needed);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl1->acl_aclp = realloc(acl1->acl_aclp, newsize);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl1->acl_aclp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memcpy((char *)acl1->acl_aclp + (acl1->acl_entry_size * slot),
fa9e4066f08beec538e775443c5be79dd423fcabahrens newentries->acl_aclp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens newentries->acl_entry_size * newentries->acl_cnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Did ACL grow?
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((slot + newentries->acl_cnt) > acl1->acl_cnt) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl1->acl_cnt = slot + newentries->acl_cnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add acl2 entries into acl1. The where argument specifies where
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to add the entries.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_addentries(acl_t *acl1, acl_t *acl2, int where)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens int newsize;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int len;
fa9e4066f08beec538e775443c5be79dd423fcabahrens void *start;
fa9e4066f08beec538e775443c5be79dd423fcabahrens void *to;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl1 == NULL || acl2 == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACL_NO_ACL_ENTRY);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl1->acl_type != acl2->acl_type)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACL_DIFF_TYPE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * allow where to specify 1 past last slot for an append operation
fa9e4066f08beec538e775443c5be79dd423fcabahrens * but anything greater is an error.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (where < 0 || where > acl1->acl_cnt)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACL_INVALID_SLOT);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens newsize = (acl2->acl_entry_size * acl2->acl_cnt) +
fa9e4066f08beec538e775443c5be79dd423fcabahrens (acl1->acl_entry_size * acl1->acl_cnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl1->acl_aclp = realloc(acl1->acl_aclp, newsize);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl1->acl_aclp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * first push down entries where new ones will be inserted
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens to = (void *)((char *)acl1->acl_aclp +
fa9e4066f08beec538e775443c5be79dd423fcabahrens ((where + acl2->acl_cnt) * acl1->acl_entry_size));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens start = (void *)((char *)acl1->acl_aclp +
fa9e4066f08beec538e775443c5be79dd423fcabahrens where * acl1->acl_entry_size);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (where < acl1->acl_cnt) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens len = (acl1->acl_cnt - where) * acl1->acl_entry_size;
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memmove(to, start, len);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * now stick in new entries.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memmove(start, acl2->acl_aclp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl2->acl_cnt * acl2->acl_entry_size);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acl1->acl_cnt += acl2->acl_cnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * return text for an ACL error.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrenschar *
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_strerror(int errnum)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (errnum) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_GRP_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks "There is more than one group or default group entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_USER_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks "There is more than one user or default user entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_OTHER_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "There is more than one other entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_CLASS_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "There is more than one mask entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_DUPLICATE_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Duplicate user or group entries"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_MISS_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Missing user/group owner, other, mask entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_MEM_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Memory error"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_ENTRY_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Unrecognized entry type"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_INHERIT_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Invalid inheritance flags"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_FLAGS_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Unrecognized entry flags"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_PERM_MASK_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Invalid ACL permissions"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_COUNT_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Invalid ACL count"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_INVALID_SLOT:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Invalid ACL entry number specified"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_NO_ACL_ENTRY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ACL entry doesn't exist"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_DIFF_TYPE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ACL type's are different"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_INVALID_USER_GROUP:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Invalid user or group"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_INVALID_STR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "ACL string is invalid"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_FIELD_NOT_BLANK:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Field expected to be blank"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_INVALID_ACCESS_TYPE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Invalid access type"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_UNKNOWN_DATA:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Unrecognized entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_MISSING_FIELDS:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ACL specification missing required fields"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_INHERIT_NOTDIR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Inheritance flags are only allowed on directories"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case -1:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (strerror(errno));
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = EINVAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN, "Unknown error"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarksextern int yyinteractive;
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks/* PRINTFLIKE1 */
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarksvoid
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarksacl_error(const char *fmt, ...)
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks{
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks va_list va;
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks if (yyinteractive == 0)
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks return;
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks va_start(va, fmt);
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks (void) vfprintf(stderr, fmt, va);
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks va_end(va);
5a5eeccada4b11bc692e9a5015d5f4a4f188226cmarks}