usr/src/lib/libsec/common/aclutils.c
author ahrens
Mon, 31 Oct 2005 11:33:35 -0800
changeset 789 b348f31ed315
child 1231 64215f768e86
permissions -rw-r--r--
PSARC 2002/240 ZFS 6338653 Integrate ZFS PSARC 2004/652 - DKIOCFLUSH 5096886 Write caching disks need mechanism to flush cache to physical media
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 * with the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    22
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <stdlib.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <string.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <unistd.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <limits.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <grp.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <pwd.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/types.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
#include <sys/acl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <errno.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/stat.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
#include <locale.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include <aclutils.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <acl_common.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
#define	ACL_PATH	0
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#define	ACL_FD		1
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
#define	ACE_POSIX_SUPPORTED_BITS (ACE_READ_DATA | \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
    ACE_WRITE_DATA | ACE_APPEND_DATA | ACE_EXECUTE | \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
    ACE_READ_ATTRIBUTES | ACE_READ_ACL | ACE_WRITE_ACL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
#define	ACL_SYNCHRONIZE_SET_ALLOW		0x0000002
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
#define	ACL_SYNCHRONIZE_SET_DENY		0x0000001
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
#define	ACL_WRITE_OWNER_SET_ALLOW		0x0000020
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
#define	ACL_WRITE_OWNER_SET_DENY		0x0000010
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
#define	ACL_WRITE_ATTRS_OWNER_SET_ALLOW		0x0002000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
#define	ACL_WRITE_ATTRS_OWNER_SET_DENY		0x0001000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
#define	ACL_WRITE_ATTRS_WRITER_SET_DENY		0x0010000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
#define	ACL_DELETE_SET_ALLOW			0x0000200
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
#define	ACL_DELETE_SET_DENY			0x0000100
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
#define	ACL_READ_NAMED_READER_SET_ALLOW		0x2000000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
#define	ACL_WRITE_NAMED_WRITER_SET_ALLOW	0x0200000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
#define	ACL_WRITE_NAMED_WRITER_SET_DENY		0x0100000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
#define	ACL_WRITE_ATTRS_OWNER_SET_ALLOW		0x0002000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
#define	ACL_WRITE_ATTRS_WRITER_SET_ALLOW	0x0020000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
#define	ACL_WRITE_OWNER_ERR_DENY		0x0000040
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
#define	ACL_READ_NAMED_READER_SET_DENY		0x1000000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
#define	ACL_WRITE_NAMED_WRITER_SET_ALLO		W0x0200000
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
typedef union {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	const char *file;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
	int  fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
} acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
acl_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
acl_alloc(enum acl_type type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
	acl_t *aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
	aclp = malloc(sizeof (acl_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
	if (aclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
	aclp->acl_aclp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
	aclp->acl_cnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	switch (type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
	case ACE_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
		aclp->acl_type = ACE_T;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
		aclp->acl_entry_size = sizeof (ace_t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
	case ACLENT_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
		aclp->acl_type = ACLENT_T;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
		aclp->acl_entry_size = sizeof (aclent_t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
	default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
		acl_free(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
		aclp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
	return (aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
 * Free acl_t structure
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
acl_free(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
	if (aclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
	if (aclp->acl_aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
		free(aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	free(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
 * Determine whether a file has a trivial ACL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
 * returns: 	0 = trivial
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
 *		1 = nontrivial
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
 *		<0 some other system failure, such as ENOENT or EPERM
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
acl_trivial(const char *filename)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
	int acl_flavor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
	int aclcnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
	int cntcmd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	int val = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
	ace_t *acep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	acl_flavor = pathconf(filename, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	if (acl_flavor == -1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	if (acl_flavor == _ACL_ACE_ENABLED)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
		cntcmd = ACE_GETACLCNT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
		cntcmd = GETACLCNT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
	aclcnt = acl(filename, cntcmd, 0, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
	if (aclcnt > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
		if (acl_flavor == _ACL_ACE_ENABLED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
			if (aclcnt != 6)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
				val = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
			else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
				acep = malloc(sizeof (ace_t) * aclcnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
				if (acep == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
					return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
				if (acl(filename, ACE_GETACL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
				    aclcnt, acep) < 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
					free(acep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
					return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
				val = ace_trivial(acep, aclcnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
				free(acep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
		} else if (aclcnt > MIN_ACL_ENTRIES)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
			val = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
	return (val);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
static uint32_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
access_mask_set(int haswriteperm, int hasreadperm, int isowner, int isallow)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
	uint32_t access_mask = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
	int acl_produce;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
	int synchronize_set = 0, write_owner_set = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	int delete_set = 0, write_attrs_set = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	int read_named_set = 0, write_named_set = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	acl_produce = (ACL_SYNCHRONIZE_SET_ALLOW |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	    ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	    ACL_WRITE_ATTRS_WRITER_SET_DENY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	if (isallow) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
		synchronize_set = ACL_SYNCHRONIZE_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
		write_owner_set = ACL_WRITE_OWNER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
		delete_set = ACL_DELETE_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
		if (hasreadperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
			read_named_set = ACL_READ_NAMED_READER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
		if (haswriteperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
			write_named_set = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
		if (isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
			write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
		else if (haswriteperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
			write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
		synchronize_set = ACL_SYNCHRONIZE_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
		write_owner_set = ACL_WRITE_OWNER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
		delete_set = ACL_DELETE_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
		if (hasreadperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
			read_named_set = ACL_READ_NAMED_READER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
		if (haswriteperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
			write_named_set = ACL_WRITE_NAMED_WRITER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
		if (isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
			write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
		else if (haswriteperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
			write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
			 * If the entity is not the owner and does not
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
			 * have write permissions ACE_WRITE_ATTRIBUTES will
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
			 * always go in the DENY ACE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
			access_mask |= ACE_WRITE_ATTRIBUTES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
	if (acl_produce & synchronize_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
		access_mask |= ACE_SYNCHRONIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	if (acl_produce & write_owner_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
		access_mask |= ACE_WRITE_OWNER;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
	if (acl_produce & delete_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
		access_mask |= ACE_DELETE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	if (acl_produce & write_attrs_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
		access_mask |= ACE_WRITE_ATTRIBUTES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
	if (acl_produce & read_named_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
		access_mask |= ACE_READ_NAMED_ATTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
	if (acl_produce & write_named_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
		access_mask |= ACE_WRITE_NAMED_ATTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
	return (access_mask);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
 * Given an mode_t, convert it into an access_mask as used
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
 * by nfsace, assuming aclent_t -> nfsace semantics.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
static uint32_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
mode_to_ace_access(mode_t mode, int isdir, int isowner, int isallow)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
	uint32_t access = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
	int haswriteperm = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
	int hasreadperm = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
	if (isallow) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
		haswriteperm = (mode & 02);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
		hasreadperm = (mode & 04);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
		haswriteperm = !(mode & 02);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
		hasreadperm = !(mode & 04);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	 * The following call takes care of correctly setting the following
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	 * mask bits in the access_mask:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	 * ACE_SYNCHRONIZE, ACE_WRITE_OWNER, ACE_DELETE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	 * ACE_WRITE_ATTRIBUTES, ACE_WRITE_NAMED_ATTRS, ACE_READ_NAMED_ATTRS
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	access = access_mask_set(haswriteperm, hasreadperm, isowner, isallow);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	if (isallow) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
		access |= ACE_READ_ACL | ACE_READ_ATTRIBUTES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
		if (isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
			access |= ACE_WRITE_ACL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
		if (! isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
			access |= ACE_WRITE_ACL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
	/* read */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
	if (mode & 04) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		access |= ACE_READ_DATA;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
	/* write */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
	if (mode & 02) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
		access |= ACE_WRITE_DATA |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
		    ACE_APPEND_DATA;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
		if (isdir)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
			access |= ACE_DELETE_CHILD;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	/* exec */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
	if (mode & 01) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
		access |= ACE_EXECUTE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
	return (access);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
 * Given an nfsace (presumably an ALLOW entry), make a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
 * corresponding DENY entry at the address given.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
ace_make_deny(ace_t *allow, ace_t *deny, int isdir, int isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	(void) memcpy(deny, allow, sizeof (ace_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	deny->a_who = allow->a_who;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
	deny->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
	deny->a_access_mask ^= ACE_POSIX_SUPPORTED_BITS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
	if (isdir)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
		deny->a_access_mask ^= ACE_DELETE_CHILD;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
	deny->a_access_mask &= ~(ACE_SYNCHRONIZE | ACE_WRITE_OWNER |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
	    ACE_DELETE | ACE_WRITE_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
	    ACE_WRITE_NAMED_ATTRS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
	deny->a_access_mask |= access_mask_set((allow->a_access_mask &
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
	    ACE_WRITE_DATA), (allow->a_access_mask & ACE_READ_DATA), isowner,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
	    B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
 * Make an initial pass over an array of aclent_t's.  Gather
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
 * information such as an ACL_MASK (if any), number of users,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
 * number of groups, and whether the array needs to be sorted.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
ln_aent_preprocess(aclent_t *aclent, int n,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
    int *hasmask, mode_t *mask,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
    int *numuser, int *numgroup, int *needsort)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	int curtype = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
	*hasmask = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	*mask = 07;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	*needsort = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	*numuser = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	*numgroup = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	for (i = 0; i < n; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
		if (aclent[i].a_type < curtype)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
			*needsort = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
		else if (aclent[i].a_type > curtype)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
			curtype = aclent[i].a_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
		if (aclent[i].a_type & USER)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
			(*numuser)++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
		if (aclent[i].a_type & (GROUP | GROUP_OBJ))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
			(*numgroup)++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
		if (aclent[i].a_type & CLASS_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
			if (*hasmask) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
				error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
				goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
			} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
				*hasmask = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
				*mask = aclent[i].a_perm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	if ((! *hasmask) && (*numuser + *numgroup > 1)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
		error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
		goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
out:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
 * Convert an array of aclent_t into an array of nfsace entries,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
 * following POSIX draft -> nfsv4 conversion semantics as outlined in
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
 * the IETF draft.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
ln_aent_to_ace(aclent_t *aclent, int n, ace_t **acepp, int *rescount, int isdir)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	mode_t mask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
	int numuser, numgroup, needsort;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
	int resultsize = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
	int i, groupi = 0, skip;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
	ace_t *acep, *result = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
	int hasmask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
	error = ln_aent_preprocess(aclent, n, &hasmask, &mask,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
	    &numuser, &numgroup, &needsort);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
	if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
		goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
	/* allow + deny for each aclent */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
	resultsize = n * 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
	if (hasmask) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
		 * stick extra deny on the group_obj and on each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
		 * user|group for the mask (the group_obj was added
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
		 * into the count for numgroup)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
		resultsize += numuser + numgroup;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
		/* ... and don't count the mask itself */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
		resultsize -= 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	/* sort the source if necessary */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
	if (needsort)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
		ksort((caddr_t)aclent, n, sizeof (aclent_t), cmp2acls);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
	result = acep = calloc(1, resultsize * sizeof (ace_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
	if (result == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
		goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
	for (i = 0; i < n; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
		 * don't process CLASS_OBJ (mask); mask was grabbed in
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
		 * ln_aent_preprocess()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
		if (aclent[i].a_type & CLASS_OBJ)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
		/* If we need an ACL_MASK emulator, prepend it now */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
		if ((hasmask) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
		    (aclent[i].a_type & (USER | GROUP | GROUP_OBJ))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
			acep->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
			acep->a_flags = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
			if (aclent[i].a_type & GROUP_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
				acep->a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
				acep->a_flags |=
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
				    (ACE_IDENTIFIER_GROUP|ACE_GROUP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
			} else if (aclent[i].a_type & USER) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
				acep->a_who = aclent[i].a_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
			} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
				acep->a_who = aclent[i].a_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
				acep->a_flags |= ACE_IDENTIFIER_GROUP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
			if (aclent[i].a_type & ACL_DEFAULT) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
				acep->a_flags |= ACE_INHERIT_ONLY_ACE |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
				    ACE_FILE_INHERIT_ACE |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
				    ACE_DIRECTORY_INHERIT_ACE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
			 * Set the access mask for the prepended deny
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
			 * ace.  To do this, we invert the mask (found
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
			 * in ln_aent_preprocess()) then convert it to an
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
			 * DENY ace access_mask.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
			acep->a_access_mask = mode_to_ace_access((mask ^ 07),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
			    isdir, 0, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
			acep += 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   442
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   443
		/* handle a_perm -> access_mask */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   444
		acep->a_access_mask = mode_to_ace_access(aclent[i].a_perm,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
		    isdir, aclent[i].a_type & USER_OBJ, 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
		/* emulate a default aclent */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
		if (aclent[i].a_type & ACL_DEFAULT) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
			acep->a_flags |= ACE_INHERIT_ONLY_ACE |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
			    ACE_FILE_INHERIT_ACE |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
			    ACE_DIRECTORY_INHERIT_ACE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
		 * handle a_perm and a_id
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
		 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
		 * this must be done last, since it involves the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
		 * corresponding deny aces, which are handled
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
		 * differently for each different a_type.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
		if (aclent[i].a_type & USER_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
			acep->a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
			acep->a_flags |= ACE_OWNER;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
			ace_make_deny(acep, acep + 1, isdir, B_TRUE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
			acep += 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
		} else if (aclent[i].a_type & USER) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
			acep->a_who = aclent[i].a_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
			ace_make_deny(acep, acep + 1, isdir, B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
			acep += 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
		} else if (aclent[i].a_type & (GROUP_OBJ | GROUP)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
			if (aclent[i].a_type & GROUP_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
				acep->a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
				acep->a_flags |= ACE_GROUP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
			} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
				acep->a_who = aclent[i].a_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
			acep->a_flags |= ACE_IDENTIFIER_GROUP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
			 * Set the corresponding deny for the group ace.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
			 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
			 * The deny aces go after all of the groups, unlike
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
			 * everything else, where they immediately follow
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
			 * the allow ace.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
			 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
			 * We calculate "skip", the number of slots to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
			 * skip ahead for the deny ace, here.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
			 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
			 * The pattern is:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
			 * MD1 A1 MD2 A2 MD3 A3 D1 D2 D3
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
			 * thus, skip is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
			 * (2 * numgroup) - 1 - groupi
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
			 * (2 * numgroup) to account for MD + A
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
			 * - 1 to account for the fact that we're on the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
			 * access (A), not the mask (MD)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
			 * - groupi to account for the fact that we have
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
			 * passed up groupi number of MD's.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
			skip = (2 * numgroup) - 1 - groupi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
			ace_make_deny(acep, acep + skip, isdir, B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
			 * If we just did the last group, skip acep past
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
			 * all of the denies; else, just move ahead one.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
			if (++groupi >= numgroup)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
				acep += numgroup + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
				acep += 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
		} else if (aclent[i].a_type & OTHER_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
			acep->a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
			acep->a_flags |= ACE_EVERYONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
			ace_make_deny(acep, acep + 1, isdir, B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
			acep += 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
			error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
			goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
	*acepp = result;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
	*rescount = resultsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
out:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
	if (error != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
		if ((result != NULL) && (resultsize > 0)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
			free(result);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
convert_aent_to_ace(aclent_t *aclentp, int aclcnt, int isdir,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
    ace_t **retacep, int *retacecnt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
	ace_t *acep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
	ace_t *dfacep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
	ace_t *newacep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
	int acecnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
	int dfacecnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
	int dfaclstart = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
	int dfaclcnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
	aclent_t *aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
	ksort((caddr_t)aclentp, aclcnt, sizeof (aclent_t), cmp2acls);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
	for (i = 0, aclp = aclentp; i < aclcnt; aclp++, i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
		if (aclp->a_type & ACL_DEFAULT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
	if (i < aclcnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
		dfaclstart = aclcnt - i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
		dfaclcnt = i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
	if (dfaclcnt && isdir == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
	error = ln_aent_to_ace(aclentp, i,  &acep, &acecnt, isdir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
	if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
	if (dfaclcnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
		error = ln_aent_to_ace(&aclentp[dfaclstart], dfaclcnt,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
		    &dfacep, &dfacecnt, isdir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
		if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
			if (acep) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
				free(acep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	newacep = malloc(sizeof (ace_t) * (acecnt + dfacecnt));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
	if (newacep == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
	(void) memcpy(newacep, acep, sizeof (ace_t) * acecnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
	if (dfaclcnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
		(void) memcpy(newacep + acecnt, dfacep,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
		    sizeof (ace_t) * dfacecnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
	free(acep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
	if (dfaclcnt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
		free(dfacep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
	*retacecnt = acecnt + dfacecnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
	*retacep = newacep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
cacl_get(acl_inp inp, int get_flag, int type, acl_t **aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
	const char *fname;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
	int fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
	int ace_acl = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
	int getcmd, cntcmd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
	acl_t *acl_info;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
	int	save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
	int	stat_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
	struct stat64 statbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
	*aclp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
		fname = inp.file;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
		ace_acl = pathconf(fname, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
		fd = inp.fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
		ace_acl = fpathconf(fd, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
	if (ace_acl == -1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
	 * if acl's aren't supported then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
	 * send it through the old GETACL interface
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
	if (ace_acl == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
		ace_acl = _ACL_ACLENT_ENABLED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
	if (ace_acl & _ACL_ACE_ENABLED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
		cntcmd = ACE_GETACLCNT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
		getcmd = ACE_GETACL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
		acl_info = acl_alloc(ACE_T);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
		cntcmd = GETACLCNT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
		getcmd = GETACL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
		acl_info = acl_alloc(ACLENT_T);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
	if (acl_info == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
		acl_info->acl_cnt = acl(fname, cntcmd, 0, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
		acl_info->acl_cnt = facl(fd, cntcmd, 0, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   647
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   648
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   649
	save_errno = errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   650
	if (acl_info->acl_cnt < 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   651
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   652
		errno = save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   653
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   654
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   655
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   656
	if (acl_info->acl_cnt == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   657
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
		errno = save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
	acl_info->acl_aclp =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   663
	    malloc(acl_info->acl_cnt * acl_info->acl_entry_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   664
	save_errno = errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   665
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   666
	if (acl_info->acl_aclp == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
		errno = save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   669
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   670
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   671
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   672
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   673
		stat_error = stat64(fname, &statbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   674
		error = acl(fname, getcmd, acl_info->acl_cnt,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   675
		    acl_info->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   676
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   677
		stat_error = fstat64(fd, &statbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   678
		error = facl(fd, getcmd, acl_info->acl_cnt,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
		    acl_info->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   681
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   682
	save_errno = errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   683
	if (error == -1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   684
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
		errno = save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   689
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   690
	if (stat_error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
		acl_info->acl_flags =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
		    (S_ISDIR(statbuf.st_mode) ? ACL_IS_DIR : 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   693
	} else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
		acl_info->acl_flags = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
	switch (acl_info->acl_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
	case ACLENT_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   698
		if (acl_info->acl_cnt <= MIN_ACL_ENTRIES)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
			acl_info->acl_flags |= ACL_IS_TRIVIAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
	case ACE_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
		if (ace_trivial(acl_info->acl_aclp, acl_info->acl_cnt) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
			acl_info->acl_flags |= ACL_IS_TRIVIAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
	default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
		errno = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   709
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   710
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   711
	if ((acl_info->acl_flags & ACL_IS_TRIVIAL) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   712
	    (get_flag & ACL_NO_TRIVIAL)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   713
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   714
		errno = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   718
	*aclp = acl_info;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   719
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   721
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   722
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   723
 * return -1 on failure, otherwise the number of acl
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
 * entries is returned
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
acl_get(const char *path, int get_flag, acl_t **aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
	acl_inp acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
	acl_inp.file = path;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
	return (cacl_get(acl_inp, get_flag, ACL_PATH, aclp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
facl_get(int fd, int get_flag, acl_t **aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   737
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   738
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
	acl_inp acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   740
	acl_inp.fd = fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   741
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
	return (cacl_get(acl_inp, get_flag, ACL_FD, aclp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   743
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   744
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   746
 * Set an ACL, translates acl to ace_t when appropriate.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   749
cacl_set(acl_inp *acl_inp, acl_t *aclp, int type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   750
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   751
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   752
	int acl_flavor_target;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   753
	ace_t *acep = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   754
	int acecnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   755
	struct stat64 statbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
	int stat_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
	int isdir;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
		stat_error = stat64(acl_inp->file, &statbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
		if (stat_error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
		acl_flavor_target = pathconf(acl_inp->file, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
		stat_error = fstat64(acl_inp->fd, &statbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   767
		if (stat_error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
		acl_flavor_target = fpathconf(acl_inp->fd, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   772
	isdir = S_ISDIR(statbuf.st_mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
	if (acl_flavor_target == -1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   775
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   776
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   777
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   778
	 * Translate aclent_t ACL's to ACE ACL's.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
	if (acl_flavor_target ==  _ACL_ACE_ENABLED &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   781
	    aclp->acl_type == ACLENT_T) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   782
		error = convert_aent_to_ace(aclp->acl_aclp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
		    aclp->acl_cnt, isdir, &acep, &acecnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   784
		if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   785
			errno = ENOTSUP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
		 * replace old acl with newly translated acl
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
		free(aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
		aclp->acl_aclp = acep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
		aclp->acl_cnt = acecnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
		aclp->acl_type = ACE_T;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   796
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
		error = acl(acl_inp->file,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
		    (aclp->acl_type == ACE_T) ? ACE_SETACL : SETACL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
		    aclp->acl_cnt, aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
		error = facl(acl_inp->fd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   803
		    (aclp->acl_type == ACE_T) ? ACE_SETACL : SETACL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   804
		    aclp->acl_cnt, aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
acl_set(const char *path, acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
	acl_inp acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
	acl_inp.file = path;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
	return (cacl_set(&acl_inp, aclp, ACL_PATH));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   821
facl_set(int fd, acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
	acl_inp acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
	acl_inp.fd = fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
	return (cacl_set(&acl_inp, aclp, ACL_FD));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   831
acl_cnt(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
	return (aclp->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
acl_type(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
	return (aclp->acl_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
acl_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
acl_dup(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
	acl_t *newaclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
	newaclp = acl_alloc(aclp->acl_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
	if (newaclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
	newaclp->acl_aclp = malloc(aclp->acl_entry_size * aclp->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
	if (newaclp->acl_aclp == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
		acl_free(newaclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
	(void) memcpy(newaclp->acl_aclp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
	    aclp->acl_aclp, aclp->acl_entry_size * aclp->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
	newaclp->acl_cnt = aclp->acl_cnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
	return (newaclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
acl_flags(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
	return (aclp->acl_flags);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
void *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
acl_data(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
	return (aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
 * Remove an ACL from a file and create a trivial ACL based
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
 * off of the mode argument.  After acl has been set owner/group
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
 * are updated to match owner,group arguments
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
acl_strip(const char *file, uid_t owner, gid_t group, mode_t mode)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
	int	error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
	aclent_t min_acl[MIN_ACL_ENTRIES];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   886
	ace_t	min_ace_acl[6];	/* owner, group, everyone + complement denies */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   887
	int	acl_flavor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
	int	aclcnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
	acl_flavor = pathconf(file, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
	if (acl_flavor == -1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   893
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   894
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   895
	 * force it through aclent flavor when file system doesn't
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   896
	 * understand question
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   897
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   898
	if (acl_flavor == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   899
		acl_flavor = _ACL_ACLENT_ENABLED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   900
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
	if (acl_flavor & _ACL_ACLENT_ENABLED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
		min_acl[0].a_type = USER_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
		min_acl[0].a_id   = owner;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
		min_acl[0].a_perm = ((mode & 0700) >> 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
		min_acl[1].a_type = GROUP_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   906
		min_acl[1].a_id   = group;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   907
		min_acl[1].a_perm = ((mode & 0070) >> 3);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   908
		min_acl[2].a_type = CLASS_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
		min_acl[2].a_id   = (uid_t)-1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
		min_acl[2].a_perm = ((mode & 0070) >> 3);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   911
		min_acl[3].a_type = OTHER_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
		min_acl[3].a_id   = (uid_t)-1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
		min_acl[3].a_perm = (mode & 0007);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
		aclcnt = 4;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   915
		error = acl(file, SETACL, aclcnt, min_acl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   916
	} else if (acl_flavor & _ACL_ACE_ENABLED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   917
		(void) memcpy(min_ace_acl, trivial_acl, sizeof (ace_t) * 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   918
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   919
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   920
		 * Make aces match request mode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   921
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   922
		adjust_ace_pair(&min_ace_acl[0], (mode & 0700) >> 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   923
		adjust_ace_pair(&min_ace_acl[2], (mode & 0070) >> 3);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   924
		adjust_ace_pair(&min_ace_acl[4], mode & 0007);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   925
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   926
		error = acl(file, ACE_SETACL, 6, min_ace_acl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   927
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   928
		errno = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
		error = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   930
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   932
	if (error == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
		error = chown(file, owner, group);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   934
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   935
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
ace_match(void *entry1, void *entry2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
	ace_t *p1 = (ace_t *)entry1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
	ace_t *p2 = (ace_t *)entry2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
	ace_t ace1, ace2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
	ace1 = *p1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
	ace2 = *p2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   947
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   948
	 * Need to fixup who field for abstrations for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
	 * accurate comparison, since field is undefined.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   950
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   951
	if (ace1.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   952
		ace1.a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   953
	if (ace2.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   954
		ace2.a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   955
	return (memcmp(&ace1, &ace2, sizeof (ace_t)));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   956
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   957
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   958
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   959
aclent_match(void *entry1, void *entry2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   960
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   961
	aclent_t *aclent1 = (aclent_t *)entry1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   962
	aclent_t *aclent2 = (aclent_t *)entry2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   963
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   964
	return (memcmp(aclent1, aclent2, sizeof (aclent_t)));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   965
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   966
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   967
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   968
 * Find acl entries in acl that correspond to removeacl.  Search
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   969
 * is started from slot.  The flag argument indicates whether to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   970
 * remove all matches or just the first match.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   971
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   972
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   973
acl_removeentries(acl_t *acl, acl_t *removeacl, int start_slot, int flag)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   974
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   975
	int i, j;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   976
	int match;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   977
	int (*acl_match)(void *acl1, void *acl2);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   978
	void *acl_entry, *remove_entry;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   979
	void *start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   980
	int found = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   981
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   982
	if (flag != ACL_REMOVE_ALL && flag != ACL_REMOVE_FIRST)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   983
		flag = ACL_REMOVE_FIRST;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   984
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
	if (acl == NULL || removeacl == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   986
		return (EACL_NO_ACL_ENTRY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
	if (acl->acl_type != removeacl->acl_type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
		return (EACL_DIFF_TYPE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
	if (acl->acl_type == ACLENT_T)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
		acl_match = aclent_match;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
		acl_match = ace_match;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
	for (i = 0, remove_entry = removeacl->acl_aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
	    i != removeacl->acl_cnt; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
		j = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
		acl_entry = (char *)acl->acl_aclp +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1001
		    (acl->acl_entry_size * start_slot);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
		for (;;) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1003
			match = acl_match(acl_entry, remove_entry);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
			if (match == 0)  {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1005
				found++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1006
				start = (char *)acl_entry +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1007
				    acl->acl_entry_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1008
				(void) memmove(acl_entry, start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
				    acl->acl_entry_size *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1010
				    acl->acl_cnt-- - (j + 1));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
				if (flag == ACL_REMOVE_FIRST)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1013
					break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1015
				 * List has changed, restart search from
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
				 * beginning.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
				acl_entry = acl->acl_aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
				j = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
				continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1022
			acl_entry = ((char *)acl_entry + acl->acl_entry_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
			if (++j >= acl->acl_cnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1024
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1025
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1026
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1027
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1028
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1029
	return ((found == 0) ? EACL_NO_ACL_ENTRY : 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1030
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1031
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1032
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1033
 * Replace entires entries in acl1 with the corresponding entries
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1034
 * in newentries.  The where argument specifies where to begin
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1035
 * the replacement.  If the where argument is 1 greater than the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1036
 * number of acl entries in acl1 then they are appended.  If the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1037
 * where argument is 2+ greater than the number of acl entries then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1038
 * EACL_INVALID_SLOT is returned.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1039
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1040
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1041
acl_modifyentries(acl_t *acl1, acl_t *newentries, int where)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1042
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1043
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1044
	int slot;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
	int slots_needed;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1046
	int slots_left;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1047
	int newsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1048
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1049
	if (acl1 == NULL || newentries == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1050
		return (EACL_NO_ACL_ENTRY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1052
	if (where < 0 || where >= acl1->acl_cnt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1053
		return (EACL_INVALID_SLOT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1054
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1055
	if (acl1->acl_type != newentries->acl_type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1056
		return (EACL_DIFF_TYPE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1057
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1058
	slot = where;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1059
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1060
	slots_left = acl1->acl_cnt - slot + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1061
	if (slots_left < newentries->acl_cnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1062
		slots_needed = newentries->acl_cnt - slots_left;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1063
		newsize = (acl1->acl_entry_size * acl1->acl_cnt) +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1064
		    (acl1->acl_entry_size * slots_needed);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1065
		acl1->acl_aclp = realloc(acl1->acl_aclp, newsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1066
		if (acl1->acl_aclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1067
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1068
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1069
	(void) memcpy((char *)acl1->acl_aclp + (acl1->acl_entry_size * slot),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1070
	    newentries->acl_aclp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1071
	    newentries->acl_entry_size * newentries->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1072
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1073
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1074
	 * Did ACL grow?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1075
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1076
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1077
	if ((slot + newentries->acl_cnt) > acl1->acl_cnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1078
		acl1->acl_cnt = slot + newentries->acl_cnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1079
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1080
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1081
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1082
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1083
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1084
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1085
 * Add acl2 entries into acl1.  The where argument specifies where
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1086
 * to add the entries.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1087
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1088
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1089
acl_addentries(acl_t *acl1, acl_t *acl2, int where)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1090
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1091
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1092
	int newsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1093
	int len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1094
	void *start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1095
	void *to;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1096
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1097
	if (acl1 == NULL || acl2 == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
		return (EACL_NO_ACL_ENTRY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1099
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
	if (acl1->acl_type != acl2->acl_type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
		return (EACL_DIFF_TYPE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
	 * allow where to specify 1 past last slot for an append operation
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
	 * but anything greater is an error.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1106
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
	if (where < 0 || where > acl1->acl_cnt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1108
		return (EACL_INVALID_SLOT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1110
	newsize = (acl2->acl_entry_size * acl2->acl_cnt) +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
	    (acl1->acl_entry_size * acl1->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1112
	acl1->acl_aclp = realloc(acl1->acl_aclp, newsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
	if (acl1->acl_aclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
	 * first push down entries where new ones will be inserted
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1118
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1119
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1120
	to = (void *)((char *)acl1->acl_aclp +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1121
	    ((where + acl2->acl_cnt) * acl1->acl_entry_size));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1122
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
	start = (void *)((char *)acl1->acl_aclp +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1124
	    where * acl1->acl_entry_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1125
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1126
	if (where < acl1->acl_cnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
		len = (acl1->acl_cnt - where) * acl1->acl_entry_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1128
		(void) memmove(to, start, len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1130
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1131
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1132
	 * now stick in new entries.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1133
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1134
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
	(void) memmove(start, acl2->acl_aclp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1136
	    acl2->acl_cnt * acl2->acl_entry_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1138
	acl1->acl_cnt += acl2->acl_cnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1139
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1141
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
aclent_perms(int perm, char *txt_perms)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1144
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
	if (perm & S_IROTH)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1146
		txt_perms[0] = 'r';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1147
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1148
		txt_perms[0] = '-';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1149
	if (perm & S_IWOTH)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
		txt_perms[1] = 'w';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
		txt_perms[1] = '-';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1153
	if (perm & S_IXOTH)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
		txt_perms[2] = 'x';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1156
		txt_perms[2] = '-';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1157
	txt_perms[3] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1158
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1159
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
static char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
pruname(uid_t uid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1162
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1163
	struct passwd	*passwdp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1164
	static char	uidp[10];	/* big enough */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1165
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1166
	passwdp = getpwuid(uid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1167
	if (passwdp == (struct passwd *)NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
		/* could not get passwd information: display uid instead */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1169
		(void) sprintf(uidp, "%ld", (long)uid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
		return (uidp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1171
	} else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1172
		return (passwdp->pw_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1173
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1174
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1175
static char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1176
prgname(gid_t gid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1177
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1178
	struct group	*groupp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1179
	static char	gidp[10];	/* big enough */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1180
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
	groupp = getgrgid(gid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1182
	if (groupp == (struct group *)NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
		/* could not get group information: display gid instead */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
		(void) sprintf(gidp, "%ld", (long)gid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
		return (gidp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1186
	} else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1187
		return (groupp->gr_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1190
aclent_printacl(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1191
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1192
	aclent_t *tp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1193
	int aclcnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
	int mask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1195
	int slot = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1196
	char perm[4];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
	/* display ACL: assume it is sorted. */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
	aclcnt = aclp->acl_cnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1200
	for (tp = aclp->acl_aclp; aclcnt--; tp++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1201
		if (tp->a_type == CLASS_OBJ)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1202
			mask = tp->a_perm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1203
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1204
	aclcnt = aclp->acl_cnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1205
	for (tp = aclp->acl_aclp; aclcnt--; tp++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1206
		(void) printf("     %d:", slot++);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1207
		switch (tp->a_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1208
		case USER:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1209
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1210
			(void) printf("user:%s:%s\t\t",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1211
			    pruname(tp->a_id), perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
			aclent_perms((tp->a_perm & mask), perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1213
			(void) printf("#effective:%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1214
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1215
		case USER_OBJ:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1216
			/* no need to display uid */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1217
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1218
			(void) printf("user::%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1219
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1220
		case GROUP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1221
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1222
			(void) printf("group:%s:%s\t\t",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1223
			    prgname(tp->a_id), perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1224
			aclent_perms(tp->a_perm & mask, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1225
			(void) printf("#effective:%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1226
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1227
		case GROUP_OBJ:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1228
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1229
			(void) printf("group::%s\t\t", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1230
			aclent_perms(tp->a_perm & mask, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1231
			(void) printf("#effective:%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1232
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1233
		case CLASS_OBJ:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1234
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1235
			(void) printf("mask:%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1236
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1237
		case OTHER_OBJ:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1238
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1239
			(void) printf("other:%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1240
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1241
		case DEF_USER:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1242
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1243
			(void) printf("default:user:%s:%s\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1244
			    pruname(tp->a_id), perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1245
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1246
		case DEF_USER_OBJ:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1247
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1248
			(void) printf("default:user::%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1249
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1250
		case DEF_GROUP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1251
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1252
			(void) printf("default:group:%s:%s\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1253
			    prgname(tp->a_id), perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1254
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1255
		case DEF_GROUP_OBJ:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1256
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
			(void) printf("default:group::%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
		case DEF_CLASS_OBJ:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
			(void) printf("default:mask:%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1263
		case DEF_OTHER_OBJ:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1264
			aclent_perms(tp->a_perm, perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1265
			(void) printf("default:other:%s\n", perm);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1266
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1267
		default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1268
			(void) fprintf(stderr,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1269
			    gettext("unrecognized entry\n"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1270
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1271
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1272
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1273
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1274
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1275
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1276
split_line(char *str, int cols)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1277
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1278
	char *ptr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1279
	int len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1280
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1281
	int last_split;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1282
	char pad[11];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1283
	int pad_len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1284
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1285
	len = strlen(str);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1286
	ptr = str;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1287
	(void) strcpy(pad, "");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1288
	pad_len = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1289
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1290
	ptr = str;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1291
	last_split = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1292
	for (i = 0; i != len; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1293
		if ((i + pad_len + 4) >= cols) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1294
			(void) printf("%s%.*s\n", pad, last_split, ptr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1295
			ptr = &ptr[last_split];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1296
			len = strlen(ptr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1297
			i = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1298
			pad_len = 4;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1299
			(void) strcpy(pad, "         ");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1300
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1301
			if (ptr[i] == '/' || ptr[i] == ':') {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1302
				last_split = i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1303
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1304
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1305
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1306
	if (i == len) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1307
		(void) printf("%s%s\n", pad, ptr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1308
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1309
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1310
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1311
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1312
ace_printacl(acl_t *aclp, int cols)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1313
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1314
	int  slot = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1315
	char *token;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1316
	char *acltext;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1317
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1318
	acltext = acl_totext(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1319
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1320
	if (acltext == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1321
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1322
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1323
	token = strtok(acltext, ",");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1324
	if (token == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1325
		free(acltext);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1326
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1327
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1328
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1329
	do {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1330
		(void) printf("     %d:", slot++);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1331
		split_line(token, cols - 5);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1332
	} while (token = strtok(NULL, ","));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1333
	free(acltext);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1334
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1335
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1336
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1337
 * pretty print an ACL.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1338
 * For aclent_t ACL's the format is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1339
 * similar to the old format used by getfacl,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1340
 * with the addition of adding a "slot" number
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1341
 * before each entry.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1342
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1343
 * for ace_t ACL's the cols variable will break up
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1344
 * the long lines into multiple lines and will also
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1345
 * print a "slot" number.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1346
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1347
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1348
acl_printacl(acl_t *aclp, int cols)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1349
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1350
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1351
	switch (aclp->acl_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1352
	case ACLENT_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1353
		aclent_printacl(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1354
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1355
	case ACE_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1356
		ace_printacl(aclp, cols);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1357
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1358
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1359
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1360
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1361
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1362
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1363
 * return text for an ACL error.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1364
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1365
char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1366
acl_strerror(int errnum)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1367
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1368
	switch (errnum) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1369
	case EACL_GRP_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1370
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1371
		    "There is more than one user group owner entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1372
	case EACL_USER_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1373
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1374
		    "There is more than one user owner entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1375
	case EACL_OTHER_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1376
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1377
		    "There is more than one other entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1378
	case EACL_CLASS_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1379
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1380
		    "There is more than one mask entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1381
	case EACL_DUPLICATE_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1382
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1383
		    "Duplicate user or group entries"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1384
	case EACL_MISS_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1385
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1386
		    "Missing user/group owner, other, mask entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1387
	case EACL_MEM_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1388
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1389
		    "Memory error"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1390
	case EACL_ENTRY_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1391
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1392
		    "Unrecognized entry type"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1393
	case EACL_INHERIT_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1394
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1395
		    "Invalid inheritance flags"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1396
	case EACL_FLAGS_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1397
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1398
		    "Unrecognized entry flags"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1399
	case EACL_PERM_MASK_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1400
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1401
		    "Invalid ACL permissions"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1402
	case EACL_COUNT_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1403
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1404
		    "Invalid ACL count"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1405
	case EACL_INVALID_SLOT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1406
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1407
		    "Invalid ACL entry number specified"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1408
	case EACL_NO_ACL_ENTRY:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1409
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1410
		    "ACL entry doesn't exist"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1411
	case EACL_DIFF_TYPE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1412
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1413
		    "ACL type's are different"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1414
	case EACL_INVALID_USER_GROUP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1415
		return (dgettext(TEXT_DOMAIN, "Invalid user or group"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1416
	case EACL_INVALID_STR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1417
		return (dgettext(TEXT_DOMAIN, "ACL string is invalid"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1418
	case EACL_FIELD_NOT_BLANK:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1419
		return (dgettext(TEXT_DOMAIN, "Field expected to be blank"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1420
	case EACL_INVALID_ACCESS_TYPE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1421
		return (dgettext(TEXT_DOMAIN, "Invalid access type"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1422
	case EACL_UNKNOWN_DATA:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1423
		return (dgettext(TEXT_DOMAIN, "Unrecognized entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1424
	case EACL_MISSING_FIELDS:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1425
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1426
		    "ACL specification missing required fields"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1427
	case EACL_INHERIT_NOTDIR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1428
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1429
		    "Inheritance flags are only allowed on directories"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1430
	case -1:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1431
		return (strerror(errno));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1432
	default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1433
		errno = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1434
		return (dgettext(TEXT_DOMAIN, "Unknown error"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1435
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1436
}