aclutils.c revision fa9e4066f08beec538e775443c5be79dd423fcab
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Common Development and Distribution License, Version 1.0 only
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (the "License"). You may not use this file except in compliance
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 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/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright 2005 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>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/types.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/acl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <errno.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/stat.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <locale.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <aclutils.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <acl_common.h>
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_ALLOW 0x0000002
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_SYNCHRONIZE_SET_DENY 0x0000001
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_OWNER_SET_ALLOW 0x0000020
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_OWNER_SET_DENY 0x0000010
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_ATTRS_OWNER_SET_ALLOW 0x0002000
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_ATTRS_OWNER_SET_DENY 0x0001000
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_ATTRS_WRITER_SET_DENY 0x0010000
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_DELETE_SET_ALLOW 0x0000200
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_DELETE_SET_DENY 0x0000100
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_READ_NAMED_READER_SET_ALLOW 0x2000000
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_NAMED_WRITER_SET_ALLOW 0x0200000
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_NAMED_WRITER_SET_DENY 0x0100000
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_ATTRS_OWNER_SET_ALLOW 0x0002000
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_ATTRS_WRITER_SET_ALLOW 0x0020000
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_OWNER_ERR_DENY 0x0000040
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_READ_NAMED_READER_SET_DENY 0x1000000
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ACL_WRITE_NAMED_WRITER_SET_ALLO W0x0200000
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 if (acl_flavor == -1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
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) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aclcnt != 6)
fa9e4066f08beec538e775443c5be79dd423fcabahrens val = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep = malloc(sizeof (ace_t) * aclcnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acep == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl(filename, ACE_GETACL,
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclcnt, acep) < 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(acep);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens val = ace_trivial(acep, aclcnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(acep);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
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) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_who = -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) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_who = -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) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_who = -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) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens acep->a_who = -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 ace_t *newacep;
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) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens dfaclstart = aclcnt - i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens dfaclcnt = 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens newacep = malloc(sizeof (ace_t) * (acecnt + dfacecnt));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newacep == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memcpy(newacep, acep, sizeof (ace_t) * acecnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (dfaclcnt) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memcpy(newacep + acecnt, dfacep,
fa9e4066f08beec538e775443c5be79dd423fcabahrens sizeof (ace_t) * dfacecnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(acep);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (dfaclcnt)
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(dfacep);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens *retacecnt = acecnt + dfacecnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *retacep = newacep;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic 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 if (ace_acl == -1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if acl's aren't supported then
fa9e4066f08beec538e775443c5be79dd423fcabahrens * send it through the old GETACL interface
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace_acl == 0) {
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
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 ace_t *acep = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int acecnt;
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
fa9e4066f08beec538e775443c5be79dd423fcabahrens isdir = S_ISDIR(statbuf.st_mode);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_flavor_target == -1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Translate aclent_t ACL's to ACE ACL's.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_flavor_target == _ACL_ACE_ENABLED &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_type == ACLENT_T) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = convert_aent_to_ace(aclp->acl_aclp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_cnt, isdir, &acep, &acecnt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = ENOTSUP;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * replace old acl with newly translated acl
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(aclp->acl_aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_aclp = acep;
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_cnt = acecnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->acl_type = ACE_T;
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
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 if (acl_flavor == -1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * force it through aclent flavor when file system doesn't
fa9e4066f08beec538e775443c5be79dd423fcabahrens * understand question
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acl_flavor == 0)
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))
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace1.a_who = -1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ace2.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace2.a_who = -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
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensaclent_perms(int perm, char *txt_perms)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (perm & S_IROTH)
fa9e4066f08beec538e775443c5be79dd423fcabahrens txt_perms[0] = 'r';
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens txt_perms[0] = '-';
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (perm & S_IWOTH)
fa9e4066f08beec538e775443c5be79dd423fcabahrens txt_perms[1] = 'w';
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens txt_perms[1] = '-';
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (perm & S_IXOTH)
fa9e4066f08beec538e775443c5be79dd423fcabahrens txt_perms[2] = 'x';
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens txt_perms[2] = '-';
fa9e4066f08beec538e775443c5be79dd423fcabahrens txt_perms[3] = '\0';
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic char *
fa9e4066f08beec538e775443c5be79dd423fcabahrenspruname(uid_t uid)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct passwd *passwdp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens static char uidp[10]; /* big enough */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens passwdp = getpwuid(uid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (passwdp == (struct passwd *)NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* could not get passwd information: display uid instead */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) sprintf(uidp, "%ld", (long)uid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (uidp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (passwdp->pw_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic char *
fa9e4066f08beec538e775443c5be79dd423fcabahrensprgname(gid_t gid)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct group *groupp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens static char gidp[10]; /* big enough */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens groupp = getgrgid(gid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (groupp == (struct group *)NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* could not get group information: display gid instead */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) sprintf(gidp, "%ld", (long)gid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gidp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (groupp->gr_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensaclent_printacl(acl_t *aclp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_t *tp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int aclcnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int mask;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int slot = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char perm[4];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* display ACL: assume it is sorted. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclcnt = aclp->acl_cnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (tp = aclp->acl_aclp; aclcnt--; tp++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (tp->a_type == CLASS_OBJ)
fa9e4066f08beec538e775443c5be79dd423fcabahrens mask = tp->a_perm;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclcnt = aclp->acl_cnt;
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (tp = aclp->acl_aclp; aclcnt--; tp++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" %d:", slot++);
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (tp->a_type) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case USER:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("user:%s:%s\t\t",
fa9e4066f08beec538e775443c5be79dd423fcabahrens pruname(tp->a_id), perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms((tp->a_perm & mask), perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("#effective:%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case USER_OBJ:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* no need to display uid */
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("user::%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case GROUP:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("group:%s:%s\t\t",
fa9e4066f08beec538e775443c5be79dd423fcabahrens prgname(tp->a_id), perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm & mask, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("#effective:%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case GROUP_OBJ:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("group::%s\t\t", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm & mask, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("#effective:%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case CLASS_OBJ:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("mask:%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case OTHER_OBJ:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("other:%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case DEF_USER:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("default:user:%s:%s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens pruname(tp->a_id), perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case DEF_USER_OBJ:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("default:user::%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case DEF_GROUP:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("default:group:%s:%s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens prgname(tp->a_id), perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case DEF_GROUP_OBJ:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("default:group::%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case DEF_CLASS_OBJ:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("default:mask:%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case DEF_OTHER_OBJ:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_perms(tp->a_perm, perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("default:other:%s\n", perm);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("unrecognized entry\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrenssplit_line(char *str, int cols)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *ptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int len;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int last_split;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char pad[11];
fa9e4066f08beec538e775443c5be79dd423fcabahrens int pad_len;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens len = strlen(str);
fa9e4066f08beec538e775443c5be79dd423fcabahrens ptr = str;
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strcpy(pad, "");
fa9e4066f08beec538e775443c5be79dd423fcabahrens pad_len = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ptr = str;
fa9e4066f08beec538e775443c5be79dd423fcabahrens last_split = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i != len; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((i + pad_len + 4) >= cols) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%s%.*s\n", pad, last_split, ptr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens ptr = &ptr[last_split];
fa9e4066f08beec538e775443c5be79dd423fcabahrens len = strlen(ptr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens i = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens pad_len = 4;
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strcpy(pad, " ");
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ptr[i] == '/' || ptr[i] == ':') {
fa9e4066f08beec538e775443c5be79dd423fcabahrens last_split = i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (i == len) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%s%s\n", pad, ptr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensace_printacl(acl_t *aclp, int cols)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int slot = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *token;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *acltext;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens acltext = acl_totext(aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acltext == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens token = strtok(acltext, ",");
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (token == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(acltext);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens do {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" %d:", slot++);
fa9e4066f08beec538e775443c5be79dd423fcabahrens split_line(token, cols - 5);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } while (token = strtok(NULL, ","));
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(acltext);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * pretty print an ACL.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * For aclent_t ACL's the format is
fa9e4066f08beec538e775443c5be79dd423fcabahrens * similar to the old format used by getfacl,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * with the addition of adding a "slot" number
fa9e4066f08beec538e775443c5be79dd423fcabahrens * before each entry.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * for ace_t ACL's the cols variable will break up
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the long lines into multiple lines and will also
fa9e4066f08beec538e775443c5be79dd423fcabahrens * print a "slot" number.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrensacl_printacl(acl_t *aclp, int cols)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (aclp->acl_type) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ACLENT_T:
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclent_printacl(aclp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ACE_T:
fa9e4066f08beec538e775443c5be79dd423fcabahrens ace_printacl(aclp, cols);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
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,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "There is more than one user group owner entry"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EACL_USER_ERROR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "There is more than one user owner 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}