usr/src/lib/libsec/common/aclutils.c
author marks
Tue, 09 May 2006 09:51:11 -0700
changeset 1953 7d218c488035
parent 1666 07697c578888
child 4321 a8930ec16e52
permissions -rw-r--r--
6421216 ufsrestore should use acl_set() for setting ACLs
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
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
     5
 * Common Development and Distribution License (the "License").
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1231
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <stdlib.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <string.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <unistd.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <limits.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <grp.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <pwd.h>
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    34
#include <strings.h>
789
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>
1420
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
    39
#include <sys/varargs.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include <locale.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <aclutils.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
#include <acl_common.h>
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    43
#include <sys/avl.h>
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    44
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    45
#define	offsetof(s, m)	((size_t)(&(((s *)0)->m)))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
#define	ACL_PATH	0
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
#define	ACL_FD		1
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
#define	ACE_POSIX_SUPPORTED_BITS (ACE_READ_DATA | \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
    ACE_WRITE_DATA | ACE_APPEND_DATA | ACE_EXECUTE | \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
    ACE_READ_ATTRIBUTES | ACE_READ_ACL | ACE_WRITE_ACL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    55
#define	ACL_SYNCHRONIZE_SET_DENY		0x0000001
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
#define	ACL_SYNCHRONIZE_SET_ALLOW		0x0000002
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    57
#define	ACL_SYNCHRONIZE_ERR_DENY		0x0000004
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    58
#define	ACL_SYNCHRONIZE_ERR_ALLOW		0x0000008
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    60
#define	ACL_WRITE_OWNER_SET_DENY		0x0000010
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
#define	ACL_WRITE_OWNER_SET_ALLOW		0x0000020
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    62
#define	ACL_WRITE_OWNER_ERR_DENY		0x0000040
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    63
#define	ACL_WRITE_OWNER_ERR_ALLOW		0x0000080
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    65
#define	ACL_DELETE_SET_DENY			0x0000100
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    66
#define	ACL_DELETE_SET_ALLOW			0x0000200
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    67
#define	ACL_DELETE_ERR_DENY			0x0000400
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    68
#define	ACL_DELETE_ERR_ALLOW			0x0000800
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    69
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    70
#define	ACL_WRITE_ATTRS_OWNER_SET_DENY		0x0001000
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
#define	ACL_WRITE_ATTRS_OWNER_SET_ALLOW		0x0002000
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    72
#define	ACL_WRITE_ATTRS_OWNER_ERR_DENY		0x0004000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    73
#define	ACL_WRITE_ATTRS_OWNER_ERR_ALLOW		0x0008000
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
#define	ACL_WRITE_ATTRS_WRITER_SET_DENY		0x0010000
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    76
#define	ACL_WRITE_ATTRS_WRITER_SET_ALLOW	0x0020000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    77
#define	ACL_WRITE_ATTRS_WRITER_ERR_DENY		0x0040000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    78
#define	ACL_WRITE_ATTRS_WRITER_ERR_ALLOW	0x0080000
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    80
#define	ACL_WRITE_NAMED_WRITER_SET_DENY		0x0100000
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
#define	ACL_WRITE_NAMED_WRITER_SET_ALLOW	0x0200000
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    82
#define	ACL_WRITE_NAMED_WRITER_ERR_DENY		0x0400000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    83
#define	ACL_WRITE_NAMED_WRITER_ERR_ALLOW	0x0800000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    84
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    85
#define	ACL_READ_NAMED_READER_SET_DENY		0x1000000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    86
#define	ACL_READ_NAMED_READER_SET_ALLOW		0x2000000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    87
#define	ACL_READ_NAMED_READER_ERR_DENY		0x4000000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    88
#define	ACL_READ_NAMED_READER_ERR_ALLOW		0x8000000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    89
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    90
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    91
#define	ACE_VALID_MASK_BITS (\
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    92
    ACE_READ_DATA | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    93
    ACE_LIST_DIRECTORY | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    94
    ACE_WRITE_DATA | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    95
    ACE_ADD_FILE | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    96
    ACE_APPEND_DATA | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    97
    ACE_ADD_SUBDIRECTORY | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    98
    ACE_READ_NAMED_ATTRS | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
    99
    ACE_WRITE_NAMED_ATTRS | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   100
    ACE_EXECUTE | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   101
    ACE_DELETE_CHILD | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   102
    ACE_READ_ATTRIBUTES | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   103
    ACE_WRITE_ATTRIBUTES | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   104
    ACE_DELETE | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   105
    ACE_READ_ACL | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   106
    ACE_WRITE_ACL | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   107
    ACE_WRITE_OWNER | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   108
    ACE_SYNCHRONIZE)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   109
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   110
#define	ACE_MASK_UNDEFINED			0x80000000
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   111
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   112
#define	ACE_VALID_FLAG_BITS (ACE_FILE_INHERIT_ACE | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   113
    ACE_DIRECTORY_INHERIT_ACE | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   114
    ACE_NO_PROPAGATE_INHERIT_ACE | ACE_INHERIT_ONLY_ACE | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   115
    ACE_SUCCESSFUL_ACCESS_ACE_FLAG | ACE_FAILED_ACCESS_ACE_FLAG | \
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   116
    ACE_IDENTIFIER_GROUP | ACE_OWNER | ACE_GROUP | ACE_EVERYONE)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   118
/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   119
 * ACL conversion helpers
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   120
 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   121
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   122
typedef enum {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   123
	ace_unused,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   124
	ace_user_obj,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   125
	ace_user,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   126
	ace_group, /* includes GROUP and GROUP_OBJ */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   127
	ace_other_obj
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   128
} ace_to_aent_state_t;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   130
typedef struct acevals {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   131
	uid_t key;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   132
	avl_node_t avl;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   133
	uint32_t mask;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   134
	uint32_t allowed;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   135
	uint32_t denied;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   136
	int aent_type;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   137
} acevals_t;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   138
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   139
typedef struct ace_list {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   140
	acevals_t user_obj;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   141
	avl_tree_t user;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   142
	int numusers;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   143
	acevals_t group_obj;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   144
	avl_tree_t group;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   145
	int numgroups;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   146
	acevals_t other_obj;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   147
	uint32_t acl_mask;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   148
	int hasmask;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   149
	int dfacl_flag;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   150
	ace_to_aent_state_t state;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   151
	int seen; /* bitmask of all aclent_t a_type values seen */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   152
} ace_list_t;
1231
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   153
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
typedef union {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	const char *file;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
	int  fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
} acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
acl_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
acl_alloc(enum acl_type type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	acl_t *aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	aclp = malloc(sizeof (acl_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
	if (aclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
	aclp->acl_aclp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
	aclp->acl_cnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
	switch (type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	case ACE_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
		aclp->acl_type = ACE_T;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
		aclp->acl_entry_size = sizeof (ace_t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
	case ACLENT_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
		aclp->acl_type = ACLENT_T;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
		aclp->acl_entry_size = sizeof (aclent_t);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
		acl_free(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
		aclp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	return (aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
 * Free acl_t structure
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
acl_free(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
	if (aclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
	if (aclp->acl_aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
		free(aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
	free(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
 * Determine whether a file has a trivial ACL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
 * returns: 	0 = trivial
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
 *		1 = nontrivial
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
 *		<0 some other system failure, such as ENOENT or EPERM
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
acl_trivial(const char *filename)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	int acl_flavor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
	int aclcnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
	int cntcmd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
	int val = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
	ace_t *acep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	acl_flavor = pathconf(filename, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
	if (acl_flavor == _ACL_ACE_ENABLED)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
		cntcmd = ACE_GETACLCNT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
		cntcmd = GETACLCNT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	aclcnt = acl(filename, cntcmd, 0, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	if (aclcnt > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
		if (acl_flavor == _ACL_ACE_ENABLED) {
1231
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   227
			acep = malloc(sizeof (ace_t) * aclcnt);
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   228
			if (acep == NULL)
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   229
				return (-1);
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   230
			if (acl(filename, ACE_GETACL,
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   231
			    aclcnt, acep) < 0) {
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   232
				free(acep);
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   233
				return (-1);
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   234
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
1231
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   236
			val = ace_trivial(acep, aclcnt);
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   237
			free(acep);
64215f768e86 6354804 The file's ACL was changed when cp it from one ZFS file system to another one.
marks
parents: 789
diff changeset
   238
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
		} else if (aclcnt > MIN_ACL_ENTRIES)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
			val = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
	return (val);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
static uint32_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
access_mask_set(int haswriteperm, int hasreadperm, int isowner, int isallow)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
	uint32_t access_mask = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
	int acl_produce;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	int synchronize_set = 0, write_owner_set = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	int delete_set = 0, write_attrs_set = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	int read_named_set = 0, write_named_set = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	acl_produce = (ACL_SYNCHRONIZE_SET_ALLOW |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	    ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	    ACL_WRITE_ATTRS_WRITER_SET_DENY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	if (isallow) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
		synchronize_set = ACL_SYNCHRONIZE_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
		write_owner_set = ACL_WRITE_OWNER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
		delete_set = ACL_DELETE_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
		if (hasreadperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
			read_named_set = ACL_READ_NAMED_READER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
		if (haswriteperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
			write_named_set = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
		if (isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
			write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
		else if (haswriteperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
			write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
		synchronize_set = ACL_SYNCHRONIZE_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		write_owner_set = ACL_WRITE_OWNER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
		delete_set = ACL_DELETE_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
		if (hasreadperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
			read_named_set = ACL_READ_NAMED_READER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
		if (haswriteperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
			write_named_set = ACL_WRITE_NAMED_WRITER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
		if (isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
			write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
		else if (haswriteperm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
			write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_DENY;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
		else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
			 * If the entity is not the owner and does not
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
			 * have write permissions ACE_WRITE_ATTRIBUTES will
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
			 * always go in the DENY ACE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
			access_mask |= ACE_WRITE_ATTRIBUTES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
	if (acl_produce & synchronize_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
		access_mask |= ACE_SYNCHRONIZE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
	if (acl_produce & write_owner_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
		access_mask |= ACE_WRITE_OWNER;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
	if (acl_produce & delete_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
		access_mask |= ACE_DELETE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
	if (acl_produce & write_attrs_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
		access_mask |= ACE_WRITE_ATTRIBUTES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
	if (acl_produce & read_named_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
		access_mask |= ACE_READ_NAMED_ATTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
	if (acl_produce & write_named_set)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
		access_mask |= ACE_WRITE_NAMED_ATTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
	return (access_mask);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
 * Given an mode_t, convert it into an access_mask as used
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
 * by nfsace, assuming aclent_t -> nfsace semantics.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
static uint32_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
mode_to_ace_access(mode_t mode, int isdir, int isowner, int isallow)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
	uint32_t access = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
	int haswriteperm = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	int hasreadperm = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	if (isallow) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
		haswriteperm = (mode & 02);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
		hasreadperm = (mode & 04);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
		haswriteperm = !(mode & 02);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
		hasreadperm = !(mode & 04);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	 * The following call takes care of correctly setting the following
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	 * mask bits in the access_mask:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	 * ACE_SYNCHRONIZE, ACE_WRITE_OWNER, ACE_DELETE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	 * ACE_WRITE_ATTRIBUTES, ACE_WRITE_NAMED_ATTRS, ACE_READ_NAMED_ATTRS
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	access = access_mask_set(haswriteperm, hasreadperm, isowner, isallow);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
	if (isallow) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
		access |= ACE_READ_ACL | ACE_READ_ATTRIBUTES;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
		if (isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
			access |= ACE_WRITE_ACL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
		if (! isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
			access |= ACE_WRITE_ACL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	/* read */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
	if (mode & 04) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
		access |= ACE_READ_DATA;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
	/* write */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
	if (mode & 02) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
		access |= ACE_WRITE_DATA |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
		    ACE_APPEND_DATA;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
		if (isdir)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
			access |= ACE_DELETE_CHILD;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
	/* exec */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	if (mode & 01) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
		access |= ACE_EXECUTE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	return (access);
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
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
 * Given an nfsace (presumably an ALLOW entry), make a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
 * corresponding DENY entry at the address given.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
ace_make_deny(ace_t *allow, ace_t *deny, int isdir, int isowner)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
	(void) memcpy(deny, allow, sizeof (ace_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
	deny->a_who = allow->a_who;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
	deny->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
	deny->a_access_mask ^= ACE_POSIX_SUPPORTED_BITS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
	if (isdir)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
		deny->a_access_mask ^= ACE_DELETE_CHILD;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
	deny->a_access_mask &= ~(ACE_SYNCHRONIZE | ACE_WRITE_OWNER |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
	    ACE_DELETE | ACE_WRITE_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
	    ACE_WRITE_NAMED_ATTRS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
	deny->a_access_mask |= access_mask_set((allow->a_access_mask &
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
	    ACE_WRITE_DATA), (allow->a_access_mask & ACE_READ_DATA), isowner,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
	    B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
 * Make an initial pass over an array of aclent_t's.  Gather
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
 * information such as an ACL_MASK (if any), number of users,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
 * number of groups, and whether the array needs to be sorted.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
ln_aent_preprocess(aclent_t *aclent, int n,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
    int *hasmask, mode_t *mask,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
    int *numuser, int *numgroup, int *needsort)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
	int curtype = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
	*hasmask = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
	*mask = 07;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
	*needsort = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
	*numuser = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
	*numgroup = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
	for (i = 0; i < n; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
		if (aclent[i].a_type < curtype)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
			*needsort = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
		else if (aclent[i].a_type > curtype)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
			curtype = aclent[i].a_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
		if (aclent[i].a_type & USER)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
			(*numuser)++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
		if (aclent[i].a_type & (GROUP | GROUP_OBJ))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
			(*numgroup)++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
		if (aclent[i].a_type & CLASS_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
			if (*hasmask) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
				error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
				goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
			} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
				*hasmask = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
				*mask = aclent[i].a_perm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
	if ((! *hasmask) && (*numuser + *numgroup > 1)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
		error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
		goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
out:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
 * Convert an array of aclent_t into an array of nfsace entries,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
 * following POSIX draft -> nfsv4 conversion semantics as outlined in
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
 * the IETF draft.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
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
   442
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   443
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   444
	mode_t mask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
	int numuser, numgroup, needsort;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
	int resultsize = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
	int i, groupi = 0, skip;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
	ace_t *acep, *result = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
	int hasmask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
	error = ln_aent_preprocess(aclent, n, &hasmask, &mask,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
	    &numuser, &numgroup, &needsort);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
	if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
		goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
	/* allow + deny for each aclent */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
	resultsize = n * 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
	if (hasmask) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
		 * stick extra deny on the group_obj and on each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
		 * user|group for the mask (the group_obj was added
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
		 * into the count for numgroup)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
		resultsize += numuser + numgroup;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
		/* ... and don't count the mask itself */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
		resultsize -= 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
	/* sort the source if necessary */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	if (needsort)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
		ksort((caddr_t)aclent, n, sizeof (aclent_t), cmp2acls);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
	result = acep = calloc(1, resultsize * sizeof (ace_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
	if (result == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
		goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
	for (i = 0; i < n; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
		 * don't process CLASS_OBJ (mask); mask was grabbed in
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
		 * ln_aent_preprocess()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
		if (aclent[i].a_type & CLASS_OBJ)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
		/* If we need an ACL_MASK emulator, prepend it now */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
		if ((hasmask) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
		    (aclent[i].a_type & (USER | GROUP | GROUP_OBJ))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
			acep->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
			acep->a_flags = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
			if (aclent[i].a_type & GROUP_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
				acep->a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
				acep->a_flags |=
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
				    (ACE_IDENTIFIER_GROUP|ACE_GROUP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
			} else if (aclent[i].a_type & USER) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
				acep->a_who = aclent[i].a_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
			} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
				acep->a_who = aclent[i].a_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
				acep->a_flags |= ACE_IDENTIFIER_GROUP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
			if (aclent[i].a_type & ACL_DEFAULT) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
				acep->a_flags |= ACE_INHERIT_ONLY_ACE |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
				    ACE_FILE_INHERIT_ACE |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
				    ACE_DIRECTORY_INHERIT_ACE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
			 * Set the access mask for the prepended deny
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
			 * ace.  To do this, we invert the mask (found
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
			 * in ln_aent_preprocess()) then convert it to an
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
			 * DENY ace access_mask.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
			acep->a_access_mask = mode_to_ace_access((mask ^ 07),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
			    isdir, 0, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
			acep += 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
		/* handle a_perm -> access_mask */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
		acep->a_access_mask = mode_to_ace_access(aclent[i].a_perm,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
		    isdir, aclent[i].a_type & USER_OBJ, 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
		/* emulate a default aclent */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
		if (aclent[i].a_type & ACL_DEFAULT) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
			acep->a_flags |= ACE_INHERIT_ONLY_ACE |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
			    ACE_FILE_INHERIT_ACE |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
			    ACE_DIRECTORY_INHERIT_ACE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
		}
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
		 * handle a_perm and a_id
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
		 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
		 * this must be done last, since it involves the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
		 * corresponding deny aces, which are handled
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
		 * differently for each different a_type.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
		if (aclent[i].a_type & USER_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
			acep->a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
			acep->a_flags |= ACE_OWNER;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
			ace_make_deny(acep, acep + 1, isdir, B_TRUE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
			acep += 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
		} else if (aclent[i].a_type & USER) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
			acep->a_who = aclent[i].a_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
			ace_make_deny(acep, acep + 1, isdir, B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
			acep += 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
		} else if (aclent[i].a_type & (GROUP_OBJ | GROUP)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
			if (aclent[i].a_type & GROUP_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
				acep->a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
				acep->a_flags |= ACE_GROUP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
			} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
				acep->a_who = aclent[i].a_id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
			acep->a_flags |= ACE_IDENTIFIER_GROUP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
			 * Set the corresponding deny for the group ace.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
			 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
			 * The deny aces go after all of the groups, unlike
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
			 * everything else, where they immediately follow
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
			 * the allow ace.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
			 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
			 * We calculate "skip", the number of slots to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
			 * skip ahead for the deny ace, here.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
			 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
			 * The pattern is:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
			 * MD1 A1 MD2 A2 MD3 A3 D1 D2 D3
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
			 * thus, skip is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
			 * (2 * numgroup) - 1 - groupi
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
			 * (2 * numgroup) to account for MD + A
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
			 * - 1 to account for the fact that we're on the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
			 * access (A), not the mask (MD)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
			 * - groupi to account for the fact that we have
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
			 * passed up groupi number of MD's.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
			skip = (2 * numgroup) - 1 - groupi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
			ace_make_deny(acep, acep + skip, isdir, B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
			 * If we just did the last group, skip acep past
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
			 * all of the denies; else, just move ahead one.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
			if (++groupi >= numgroup)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
				acep += numgroup + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
				acep += 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
		} else if (aclent[i].a_type & OTHER_OBJ) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
			acep->a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
			acep->a_flags |= ACE_EVERYONE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
			ace_make_deny(acep, acep + 1, isdir, B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
			acep += 2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
			error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
			goto out;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
	*acepp = result;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
	*rescount = resultsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
out:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
	if (error != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
		if ((result != NULL) && (resultsize > 0)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
			free(result);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
convert_aent_to_ace(aclent_t *aclentp, int aclcnt, int isdir,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
    ace_t **retacep, int *retacecnt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
	ace_t *acep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
	ace_t *dfacep;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
	int acecnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
	int dfacecnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
	int dfaclstart = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
	int dfaclcnt = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
	aclent_t *aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
	ksort((caddr_t)aclentp, aclcnt, sizeof (aclent_t), cmp2acls);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
	for (i = 0, aclp = aclentp; i < aclcnt; aclp++, i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
		if (aclp->a_type & ACL_DEFAULT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
	if (i < aclcnt) {
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   627
		dfaclstart = i;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   628
		dfaclcnt = aclcnt - i;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
	if (dfaclcnt && isdir == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
	error = ln_aent_to_ace(aclentp, i,  &acep, &acecnt, isdir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
	if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
	if (dfaclcnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
		error = ln_aent_to_ace(&aclentp[dfaclstart], dfaclcnt,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
		    &dfacep, &dfacecnt, isdir);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
		if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   643
			if (acep) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
				free(acep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   645
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   646
			return (-1);
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
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   650
	if (dfacecnt != 0) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   651
		acep = realloc(acep, sizeof (ace_t) * (acecnt + dfacecnt));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   652
		if (acep == NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   653
			return (-1);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   654
		if (dfaclcnt) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   655
			(void) memcpy(acep + acecnt, dfacep,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   656
			    sizeof (ace_t) * dfacecnt);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   657
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
	if (dfaclcnt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   660
		free(dfacep);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   661
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   662
	*retacecnt = acecnt + dfacecnt;
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   663
	*retacep = acep;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   664
	return (0);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   665
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   666
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   667
static void
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   668
acevals_init(acevals_t *vals, uid_t key)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   669
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   670
	bzero(vals, sizeof (*vals));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   671
	vals->allowed = ACE_MASK_UNDEFINED;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   672
	vals->denied = ACE_MASK_UNDEFINED;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   673
	vals->mask = ACE_MASK_UNDEFINED;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   674
	vals->key = key;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   675
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   676
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   677
static void
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   678
ace_list_init(ace_list_t *al, int dfacl_flag)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   679
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   680
	acevals_init(&al->user_obj, NULL);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   681
	acevals_init(&al->group_obj, NULL);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   682
	acevals_init(&al->other_obj, NULL);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   683
	al->numusers = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   684
	al->numgroups = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   685
	al->acl_mask = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   686
	al->hasmask = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   687
	al->state = ace_unused;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   688
	al->seen = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   689
	al->dfacl_flag = dfacl_flag;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   690
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   691
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   692
/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   693
 * Find or create an acevals holder for a given id and avl tree.
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   694
 *
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   695
 * Note that only one thread will ever touch these avl trees, so
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   696
 * there is no need for locking.
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   697
 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   698
static acevals_t *
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   699
acevals_find(ace_t *ace, avl_tree_t *avl, int *num)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   700
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   701
	acevals_t key, *rc;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   702
	avl_index_t where;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   703
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   704
	key.key = ace->a_who;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   705
	rc = avl_find(avl, &key, &where);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   706
	if (rc != NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   707
		return (rc);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   708
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   709
	/* this memory is freed by ln_ace_to_aent()->ace_list_free() */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   710
	rc = calloc(1, sizeof (acevals_t));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   711
	if (rc == NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   712
		return (rc);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   713
	acevals_init(rc, ace->a_who);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   714
	avl_insert(avl, rc, where);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   715
	(*num)++;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   716
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   717
	return (rc);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   718
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   719
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   720
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   721
access_mask_check(ace_t *acep, int mask_bit, int isowner)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   722
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   723
	int set_deny, err_deny;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   724
	int set_allow, err_allow;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   725
	int acl_consume;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   726
	int haswriteperm, hasreadperm;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   727
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   728
	if (acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   729
		haswriteperm = (acep->a_access_mask & ACE_WRITE_DATA) ? 0 : 1;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   730
		hasreadperm = (acep->a_access_mask & ACE_READ_DATA) ? 0 : 1;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   731
	} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   732
		haswriteperm = (acep->a_access_mask & ACE_WRITE_DATA) ? 1 : 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   733
		hasreadperm = (acep->a_access_mask & ACE_READ_DATA) ? 1 : 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   734
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   735
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   736
	acl_consume = (ACL_SYNCHRONIZE_ERR_DENY |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   737
	    ACL_DELETE_ERR_DENY |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   738
	    ACL_WRITE_OWNER_ERR_DENY |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   739
	    ACL_WRITE_OWNER_ERR_ALLOW |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   740
	    ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   741
	    ACL_WRITE_ATTRS_OWNER_ERR_DENY |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   742
	    ACL_WRITE_ATTRS_WRITER_SET_DENY |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   743
	    ACL_WRITE_ATTRS_WRITER_ERR_ALLOW |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   744
	    ACL_WRITE_NAMED_WRITER_ERR_DENY |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   745
	    ACL_READ_NAMED_READER_ERR_DENY);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   746
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   747
	if (mask_bit == ACE_SYNCHRONIZE) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   748
		set_deny = ACL_SYNCHRONIZE_SET_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   749
		err_deny =  ACL_SYNCHRONIZE_ERR_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   750
		set_allow = ACL_SYNCHRONIZE_SET_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   751
		err_allow = ACL_SYNCHRONIZE_ERR_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   752
	} else if (mask_bit == ACE_WRITE_OWNER) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   753
		set_deny = ACL_WRITE_OWNER_SET_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   754
		err_deny =  ACL_WRITE_OWNER_ERR_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   755
		set_allow = ACL_WRITE_OWNER_SET_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   756
		err_allow = ACL_WRITE_OWNER_ERR_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   757
	} else if (mask_bit == ACE_DELETE) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   758
		set_deny = ACL_DELETE_SET_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   759
		err_deny =  ACL_DELETE_ERR_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   760
		set_allow = ACL_DELETE_SET_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   761
		err_allow = ACL_DELETE_ERR_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   762
	} else if (mask_bit == ACE_WRITE_ATTRIBUTES) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   763
		if (isowner) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   764
			set_deny = ACL_WRITE_ATTRS_OWNER_SET_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   765
			err_deny =  ACL_WRITE_ATTRS_OWNER_ERR_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   766
			set_allow = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   767
			err_allow = ACL_WRITE_ATTRS_OWNER_ERR_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   768
		} else if (haswriteperm) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   769
			set_deny = ACL_WRITE_ATTRS_WRITER_SET_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   770
			err_deny =  ACL_WRITE_ATTRS_WRITER_ERR_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   771
			set_allow = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   772
			err_allow = ACL_WRITE_ATTRS_WRITER_ERR_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   773
		} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   774
			if ((acep->a_access_mask & mask_bit) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   775
			    (acep->a_type & ACE_ACCESS_ALLOWED_ACE_TYPE)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   776
				return (ENOTSUP);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   777
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   778
			return (0);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   779
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   780
	} else if (mask_bit == ACE_READ_NAMED_ATTRS) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   781
		if (!hasreadperm)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   782
			return (0);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   783
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   784
		set_deny = ACL_READ_NAMED_READER_SET_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   785
		err_deny = ACL_READ_NAMED_READER_ERR_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   786
		set_allow = ACL_READ_NAMED_READER_SET_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   787
		err_allow = ACL_READ_NAMED_READER_ERR_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   788
	} else if (mask_bit == ACE_WRITE_NAMED_ATTRS) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   789
		if (!haswriteperm)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   790
			return (0);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   791
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   792
		set_deny = ACL_WRITE_NAMED_WRITER_SET_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   793
		err_deny = ACL_WRITE_NAMED_WRITER_ERR_DENY;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   794
		set_allow = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   795
		err_allow = ACL_WRITE_NAMED_WRITER_ERR_ALLOW;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   796
	} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   797
		return (EINVAL);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   798
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   799
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   800
	if (acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   801
		if (acl_consume & set_deny) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   802
			if (!(acep->a_access_mask & mask_bit)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   803
				return (ENOTSUP);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   804
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   805
		} else if (acl_consume & err_deny) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   806
			if (acep->a_access_mask & mask_bit) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   807
				return (ENOTSUP);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   808
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   809
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   810
	} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   811
		/* ACE_ACCESS_ALLOWED_ACE_TYPE */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   812
		if (acl_consume & set_allow) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   813
			if (!(acep->a_access_mask & mask_bit)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   814
				return (ENOTSUP);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   815
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   816
		} else if (acl_consume & err_allow) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   817
			if (acep->a_access_mask & mask_bit) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   818
				return (ENOTSUP);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   819
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   820
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   821
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   825
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   826
ace_to_aent_legal(ace_t *acep)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   827
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   828
	int error = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   829
	int isowner;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   830
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   831
	/* only ALLOW or DENY */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   832
	if ((acep->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   833
	    (acep->a_type != ACE_ACCESS_DENIED_ACE_TYPE)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   834
		error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   835
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   836
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   837
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   838
	/* check for invalid flags */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   839
	if (acep->a_flags & ~(ACE_VALID_FLAG_BITS)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   840
		error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   841
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   842
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   843
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   844
	/* some flags are illegal */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   845
	if (acep->a_flags & (ACE_SUCCESSFUL_ACCESS_ACE_FLAG |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   846
	    ACE_FAILED_ACCESS_ACE_FLAG |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   847
	    ACE_NO_PROPAGATE_INHERIT_ACE)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   848
		error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   849
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   850
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   851
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   852
	/* check for invalid masks */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   853
	if (acep->a_access_mask & ~(ACE_VALID_MASK_BITS)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   854
		error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   855
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   856
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   857
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   858
	if ((acep->a_flags & ACE_OWNER)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   859
		isowner = 1;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   860
	} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   861
		isowner = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   862
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   863
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   864
	error = access_mask_check(acep, ACE_SYNCHRONIZE, isowner);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   865
	if (error)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   866
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   867
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   868
	error = access_mask_check(acep, ACE_WRITE_OWNER, isowner);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   869
	if (error)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   870
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   871
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   872
	error = access_mask_check(acep, ACE_DELETE, isowner);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   873
	if (error)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   874
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   875
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   876
	error = access_mask_check(acep, ACE_WRITE_ATTRIBUTES, isowner);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   877
	if (error)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   878
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   879
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   880
	error = access_mask_check(acep, ACE_READ_NAMED_ATTRS, isowner);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   881
	if (error)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   882
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   883
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   884
	error = access_mask_check(acep, ACE_WRITE_NAMED_ATTRS, isowner);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   885
	if (error)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   886
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   887
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   888
	/* more detailed checking of masks */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   889
	if (acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   890
		if (! (acep->a_access_mask & ACE_READ_ATTRIBUTES)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   891
			error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   892
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   893
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   894
		if ((acep->a_access_mask & ACE_WRITE_DATA) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   895
		    (! (acep->a_access_mask & ACE_APPEND_DATA))) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   896
			error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   897
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   898
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   899
		if ((! (acep->a_access_mask & ACE_WRITE_DATA)) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   900
		    (acep->a_access_mask & ACE_APPEND_DATA)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   901
			error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   902
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   903
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   904
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   905
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   906
	/* ACL enforcement */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   907
	if ((acep->a_access_mask & ACE_READ_ACL) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   908
	    (acep->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   909
		error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   910
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   911
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   912
	if (acep->a_access_mask & ACE_WRITE_ACL) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   913
		if ((acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   914
		    (isowner)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   915
			error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   916
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   917
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   918
		if ((acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   919
		    (! isowner)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   920
			error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   921
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   922
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   923
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   924
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   925
out:
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   926
	return (error);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   927
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   928
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   929
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   930
ace_mask_to_mode(uint32_t  mask, o_mode_t *modep, int isdir)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   931
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   932
	int error = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   933
	o_mode_t mode = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   934
	uint32_t bits, wantbits;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   935
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   936
	/* read */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   937
	if (mask & ACE_READ_DATA)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   938
		mode |= 04;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   939
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   940
	/* write */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   941
	wantbits = (ACE_WRITE_DATA | ACE_APPEND_DATA);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   942
	if (isdir)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   943
		wantbits |= ACE_DELETE_CHILD;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   944
	bits = mask & wantbits;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   945
	if (bits != 0) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   946
		if (bits != wantbits) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   947
			error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   948
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   949
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   950
		mode |= 02;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   951
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   952
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   953
	/* exec */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   954
	if (mask & ACE_EXECUTE) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   955
		mode |= 01;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   956
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   957
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   958
	*modep = mode;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   959
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   960
out:
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   961
	return (error);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   962
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   963
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   964
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   965
ace_allow_to_mode(uint32_t mask, o_mode_t *modep, int isdir)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   966
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   967
	/* ACE_READ_ACL and ACE_READ_ATTRIBUTES must both be set */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   968
	if ((mask & (ACE_READ_ACL | ACE_READ_ATTRIBUTES)) !=
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   969
	    (ACE_READ_ACL | ACE_READ_ATTRIBUTES)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   970
		return (ENOTSUP);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   971
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   972
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   973
	return (ace_mask_to_mode(mask, modep, isdir));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   974
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   975
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   976
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   977
acevals_to_aent(acevals_t *vals, aclent_t *dest, ace_list_t *list,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   978
    uid_t owner, gid_t group, int isdir)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   979
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   980
	int error;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   981
	uint32_t  flips = ACE_POSIX_SUPPORTED_BITS;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   982
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   983
	if (isdir)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   984
		flips |= ACE_DELETE_CHILD;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   985
	if (vals->allowed != (vals->denied ^ flips)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   986
		error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   987
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   988
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   989
	if ((list->hasmask) && (list->acl_mask != vals->mask) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   990
	    (vals->aent_type & (USER | GROUP | GROUP_OBJ))) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   991
		error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   992
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   993
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   994
	error = ace_allow_to_mode(vals->allowed, &dest->a_perm, isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   995
	if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   996
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   997
	dest->a_type = vals->aent_type;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   998
	if (dest->a_type & (USER | GROUP)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
   999
		dest->a_id = vals->key;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1000
	} else if (dest->a_type & USER_OBJ) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1001
		dest->a_id = owner;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1002
	} else if (dest->a_type & GROUP_OBJ) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1003
		dest->a_id = group;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1004
	} else if (dest->a_type & OTHER_OBJ) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1005
		dest->a_id = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1006
	} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1007
		error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1008
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1009
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1010
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1011
out:
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1012
	return (error);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1013
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1015
static int
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1016
ace_list_to_aent(ace_list_t *list, aclent_t **aclentp, int *aclcnt,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1017
    uid_t owner, gid_t group, int isdir)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1018
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1019
	int error = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1020
	aclent_t *aent, *result = NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1021
	acevals_t *vals;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1022
	int resultcount;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1023
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1024
	if ((list->seen & (USER_OBJ | GROUP_OBJ | OTHER_OBJ)) !=
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1025
	    (USER_OBJ | GROUP_OBJ | OTHER_OBJ)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1026
		error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1027
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1028
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1029
	if ((! list->hasmask) && (list->numusers + list->numgroups > 0)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1030
		error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1031
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1032
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1033
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1034
	resultcount = 3 + list->numusers + list->numgroups;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1035
	/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1036
	 * This must be the same condition as below, when we add the CLASS_OBJ
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1037
	 * (aka ACL mask)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1038
	 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1039
	if ((list->hasmask) || (! list->dfacl_flag))
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1040
		resultcount += 1;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1041
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1042
	result = aent = calloc(1, resultcount * sizeof (aclent_t));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1043
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1044
	if (result == NULL) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1045
		error = ENOMEM;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1046
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1047
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1048
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1049
	/* USER_OBJ */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1050
	if (!(list->user_obj.aent_type & USER_OBJ)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1051
		error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1052
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1053
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1054
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1055
	error = acevals_to_aent(&list->user_obj, aent, list, owner, group,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1056
	    isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1057
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1058
	if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1059
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1060
	++aent;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1061
	/* USER */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1062
	vals = NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1063
	for (vals = avl_first(&list->user); vals != NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1064
	    vals = AVL_NEXT(&list->user, vals)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1065
		if (!(vals->aent_type & USER)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1066
			error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1067
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1068
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1069
		error = acevals_to_aent(vals, aent, list, owner, group,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1070
		    isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1071
		if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1072
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1073
		++aent;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1074
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1075
	/* GROUP_OBJ */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1076
	if (!(list->group_obj.aent_type & GROUP_OBJ)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1077
		error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1078
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1079
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1080
	error = acevals_to_aent(&list->group_obj, aent, list, owner, group,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1081
	    isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1082
	if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1083
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1084
	++aent;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1085
	/* GROUP */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1086
	vals = NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1087
	for (vals = avl_first(&list->group); vals != NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1088
	    vals = AVL_NEXT(&list->group, vals)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1089
		if (!(vals->aent_type & GROUP)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1090
			error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1091
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1092
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1093
		error = acevals_to_aent(vals, aent, list, owner, group,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1094
		    isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1095
		if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1096
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1097
		++aent;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1098
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1099
	/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1100
	 * CLASS_OBJ (aka ACL_MASK)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1101
	 *
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1102
	 * An ACL_MASK is not fabricated if the ACL is a default ACL.
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1103
	 * This is to follow UFS's behavior.
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1104
	 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1105
	if ((list->hasmask) || (! list->dfacl_flag)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1106
		if (list->hasmask) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1107
			uint32_t flips = ACE_POSIX_SUPPORTED_BITS;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1108
			if (isdir)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1109
				flips |= ACE_DELETE_CHILD;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1110
			error = ace_mask_to_mode(list->acl_mask ^ flips,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1111
			    &aent->a_perm, isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1112
			if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1113
				goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1114
		} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1115
			/* fabricate the ACL_MASK from the group permissions */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1116
			error = ace_mask_to_mode(list->group_obj.allowed,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1117
			    &aent->a_perm, isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1118
			if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1119
				goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1120
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1121
		aent->a_id = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1122
		aent->a_type = CLASS_OBJ | list->dfacl_flag;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1123
		++aent;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1124
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1125
	/* OTHER_OBJ */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1126
	if (!(list->other_obj.aent_type & OTHER_OBJ)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1127
		error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1128
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1129
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1130
	error = acevals_to_aent(&list->other_obj, aent, list, owner, group,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1131
	    isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1132
	if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1133
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1134
	++aent;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1135
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1136
	*aclentp = result;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1137
	*aclcnt = resultcount;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1138
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1139
out:
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1140
	if (error != 0) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1141
		if (result != NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1142
			free(result);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1143
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1144
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1145
	return (error);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1146
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1147
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1148
/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1149
 * free all data associated with an ace_list
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1150
 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1151
static void
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1152
ace_list_free(ace_list_t *al)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1153
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1154
	acevals_t *node;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1155
	void *cookie;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1156
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1157
	if (al == NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1158
		return;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1159
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1160
	cookie = NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1161
	while ((node = avl_destroy_nodes(&al->user, &cookie)) != NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1162
		free(node);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1163
	cookie = NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1164
	while ((node = avl_destroy_nodes(&al->group, &cookie)) != NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1165
		free(node);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1166
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1167
	avl_destroy(&al->user);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1168
	avl_destroy(&al->group);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1169
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1170
	/* free the container itself */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1171
	free(al);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1172
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1173
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1174
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1175
acevals_compare(const void *va, const void *vb)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1176
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1177
	const acevals_t *a = va, *b = vb;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1178
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1179
	if (a->key == b->key)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1180
		return (0);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1181
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1182
	if (a->key > b->key)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1183
		return (1);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1184
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1185
	else
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1186
		return (-1);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1187
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1188
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1189
/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1190
 * Convert a list of ace_t entries to equivalent regular and default
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1191
 * aclent_t lists.  Return error (ENOTSUP) when conversion is not possible.
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1192
 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1193
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1194
ln_ace_to_aent(ace_t *ace, int n, uid_t owner, gid_t group,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1195
    aclent_t **aclentp, int *aclcnt, aclent_t **dfaclentp, int *dfaclcnt,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1196
    int isdir)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1197
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1198
	int error = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1199
	ace_t *acep;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1200
	uint32_t bits;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1201
	int i;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1202
	ace_list_t *normacl = NULL, *dfacl = NULL, *acl;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1203
	acevals_t *vals;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1204
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1205
	*aclentp = NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1206
	*aclcnt = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1207
	*dfaclentp = NULL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1208
	*dfaclcnt = 0;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1209
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1210
	/* we need at least user_obj, group_obj, and other_obj */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1211
	if (n < 6) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1212
		error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1213
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1214
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1215
	if (ace == NULL) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1216
		error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1217
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1218
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1219
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1220
	normacl = calloc(1, sizeof (ace_list_t));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1221
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1222
	if (normacl == NULL) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1223
		error = errno;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1224
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1225
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1226
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1227
	avl_create(&normacl->user, acevals_compare, sizeof (acevals_t),
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1228
	    offsetof(acevals_t, avl));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1229
	avl_create(&normacl->group, acevals_compare, sizeof (acevals_t),
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1230
	    offsetof(acevals_t, avl));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1231
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1232
	ace_list_init(normacl, 0);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1233
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1234
	dfacl = calloc(1, sizeof (ace_list_t));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1235
	if (dfacl == NULL) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1236
		error = errno;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1237
		goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1238
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1239
	avl_create(&dfacl->user, acevals_compare, sizeof (acevals_t),
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1240
	    offsetof(acevals_t, avl));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1241
	avl_create(&dfacl->group, acevals_compare, sizeof (acevals_t),
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1242
	    offsetof(acevals_t, avl));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1243
	ace_list_init(dfacl, ACL_DEFAULT);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1244
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1245
	/* process every ace_t... */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1246
	for (i = 0; i < n; i++) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1247
		acep = &ace[i];
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1248
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1249
		/* rule out certain cases quickly */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1250
		error = ace_to_aent_legal(acep);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1251
		if (error != 0)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1252
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1253
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1254
		/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1255
		 * Turn off these bits in order to not have to worry about
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1256
		 * them when doing the checks for compliments.
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1257
		 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1258
		acep->a_access_mask &= ~(ACE_WRITE_OWNER | ACE_DELETE |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1259
		    ACE_SYNCHRONIZE | ACE_WRITE_ATTRIBUTES |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1260
		    ACE_READ_NAMED_ATTRS | ACE_WRITE_NAMED_ATTRS);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1261
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1262
		/* see if this should be a regular or default acl */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1263
		bits = acep->a_flags &
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1264
		    (ACE_INHERIT_ONLY_ACE |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1265
		    ACE_FILE_INHERIT_ACE |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1266
		    ACE_DIRECTORY_INHERIT_ACE);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1267
		if (bits != 0) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1268
			/* all or nothing on these inherit bits */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1269
			if (bits != (ACE_INHERIT_ONLY_ACE |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1270
			    ACE_FILE_INHERIT_ACE |
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1271
			    ACE_DIRECTORY_INHERIT_ACE)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1272
				error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1273
				goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1274
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1275
			acl = dfacl;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1276
		} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1277
			acl = normacl;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1278
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1279
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1280
		if ((acep->a_flags & ACE_OWNER)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1281
			if (acl->state > ace_user_obj) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1282
				error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1283
				goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1284
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1285
			acl->state = ace_user_obj;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1286
			acl->seen |= USER_OBJ;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1287
			vals = &acl->user_obj;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1288
			vals->aent_type = USER_OBJ | acl->dfacl_flag;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1289
		} else if ((acep->a_flags & ACE_EVERYONE)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1290
			acl->state = ace_other_obj;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1291
			acl->seen |= OTHER_OBJ;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1292
			vals = &acl->other_obj;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1293
			vals->aent_type = OTHER_OBJ | acl->dfacl_flag;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1294
		} else if (acep->a_flags & ACE_IDENTIFIER_GROUP) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1295
			if (acl->state > ace_group) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1296
				error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1297
				goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1298
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1299
			if ((acep->a_flags & ACE_GROUP)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1300
				acl->seen |= GROUP_OBJ;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1301
				vals = &acl->group_obj;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1302
				vals->aent_type = GROUP_OBJ | acl->dfacl_flag;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1303
			} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1304
				acl->seen |= GROUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1305
				vals = acevals_find(acep, &acl->group,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1306
				    &acl->numgroups);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1307
				if (vals == NULL) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1308
					error = ENOMEM;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1309
					goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1310
				}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1311
				vals->aent_type = GROUP | acl->dfacl_flag;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1312
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1313
			acl->state = ace_group;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1314
		} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1315
			if (acl->state > ace_user) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1316
				error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1317
				goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1318
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1319
			acl->state = ace_user;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1320
			acl->seen |= USER;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1321
			vals = acevals_find(acep, &acl->user,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1322
			    &acl->numusers);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1323
			if (vals == NULL) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1324
				error = ENOMEM;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1325
				goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1326
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1327
			vals->aent_type = USER | acl->dfacl_flag;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1328
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1329
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1330
		if (!(acl->state > ace_unused)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1331
			error = EINVAL;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1332
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1333
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1334
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1335
		if (acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1336
			/* no more than one allowed per aclent_t */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1337
			if (vals->allowed != ACE_MASK_UNDEFINED) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1338
				error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1339
				goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1340
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1341
			vals->allowed = acep->a_access_mask;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1342
		} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1343
			/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1344
			 * it's a DENY; if there was a previous DENY, it
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1345
			 * must have been an ACL_MASK.
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1346
			 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1347
			if (vals->denied != ACE_MASK_UNDEFINED) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1348
				/* ACL_MASK is for USER and GROUP only */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1349
				if ((acl->state != ace_user) &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1350
				    (acl->state != ace_group)) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1351
					error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1352
					goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1353
				}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1354
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1355
				if (! acl->hasmask) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1356
					acl->hasmask = 1;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1357
					acl->acl_mask = vals->denied;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1358
				/* check for mismatched ACL_MASK emulations */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1359
				} else if (acl->acl_mask != vals->denied) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1360
					error = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1361
					goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1362
				}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1363
				vals->mask = vals->denied;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1364
			}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1365
			vals->denied = acep->a_access_mask;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1366
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1367
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1368
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1369
	/* done collating; produce the aclent_t lists */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1370
	if (normacl->state != ace_unused) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1371
		error = ace_list_to_aent(normacl, aclentp, aclcnt,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1372
		    owner, group, isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1373
		if (error != 0) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1374
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1375
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1376
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1377
	if (dfacl->state != ace_unused) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1378
		error = ace_list_to_aent(dfacl, dfaclentp, dfaclcnt,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1379
		    owner, group, isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1380
		if (error != 0) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1381
			goto out;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1382
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1383
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1384
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1385
out:
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1386
	if (normacl != NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1387
		ace_list_free(normacl);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1388
	if (dfacl != NULL)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1389
		ace_list_free(dfacl);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1390
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1391
	return (error);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1392
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1393
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1394
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1395
convert_ace_to_aent(ace_t *acebufp, int acecnt, int isdir,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1396
    uid_t owner, gid_t group, aclent_t **retaclentp, int *retaclcnt)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1397
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1398
	int error;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1399
	aclent_t *aclentp, *dfaclentp;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1400
	int aclcnt, dfaclcnt;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1401
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1402
	error = ln_ace_to_aent(acebufp, acecnt, owner, group,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1403
	    &aclentp, &aclcnt, &dfaclentp, &dfaclcnt, isdir);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1404
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1405
	if (error)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1406
		return (error);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1407
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1408
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1409
	if (dfaclcnt != 0) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1410
		/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1411
		 * Slap aclentp and dfaclentp into a single array.
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1412
		 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1413
		aclentp = realloc(aclentp, (sizeof (aclent_t) * aclcnt) +
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1414
		    (sizeof (aclent_t) * dfaclcnt));
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1415
		if (aclentp != NULL) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1416
			(void) memcpy(aclentp + aclcnt,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1417
			    dfaclentp, sizeof (aclent_t) * dfaclcnt);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1418
		} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1419
			error = -1;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1420
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1421
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1422
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1423
	if (aclentp) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1424
		*retaclentp = aclentp;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1425
		*retaclcnt = aclcnt + dfaclcnt;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1426
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1427
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1428
	if (dfaclentp)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1429
		free(dfaclentp);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1430
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1431
	return (error);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1432
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1433
1477
18d318bc863e 6389529 libsec fails to compile with gcc
marks
parents: 1462
diff changeset
  1434
static int
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1435
cacl_get(acl_inp inp, int get_flag, int type, acl_t **aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1436
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1437
	const char *fname;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1438
	int fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1439
	int ace_acl = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1440
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1441
	int getcmd, cntcmd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1442
	acl_t *acl_info;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1443
	int	save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1444
	int	stat_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1445
	struct stat64 statbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1446
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1447
	*aclp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1448
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1449
		fname = inp.file;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1450
		ace_acl = pathconf(fname, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1451
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1452
		fd = inp.fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1453
		ace_acl = fpathconf(fd, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1454
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1456
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1457
	 * if acl's aren't supported then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1458
	 * send it through the old GETACL interface
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1459
	 */
1666
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1460
	if (ace_acl == 0 || ace_acl == -1) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1461
		ace_acl = _ACL_ACLENT_ENABLED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1462
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1463
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1464
	if (ace_acl & _ACL_ACE_ENABLED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1465
		cntcmd = ACE_GETACLCNT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1466
		getcmd = ACE_GETACL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1467
		acl_info = acl_alloc(ACE_T);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1468
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1469
		cntcmd = GETACLCNT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1470
		getcmd = GETACL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1471
		acl_info = acl_alloc(ACLENT_T);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1472
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1473
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1474
	if (acl_info == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1475
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1476
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1477
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1478
		acl_info->acl_cnt = acl(fname, cntcmd, 0, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1479
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1480
		acl_info->acl_cnt = facl(fd, cntcmd, 0, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1481
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1482
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1483
	save_errno = errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1484
	if (acl_info->acl_cnt < 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1485
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1486
		errno = save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1487
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1488
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1489
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1490
	if (acl_info->acl_cnt == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1491
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1492
		errno = save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1493
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1494
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1495
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1496
	acl_info->acl_aclp =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1497
	    malloc(acl_info->acl_cnt * acl_info->acl_entry_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1498
	save_errno = errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1499
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1500
	if (acl_info->acl_aclp == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1501
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1502
		errno = save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1503
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1504
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1505
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1506
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1507
		stat_error = stat64(fname, &statbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1508
		error = acl(fname, getcmd, acl_info->acl_cnt,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1509
		    acl_info->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1510
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1511
		stat_error = fstat64(fd, &statbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1512
		error = facl(fd, getcmd, acl_info->acl_cnt,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1513
		    acl_info->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1514
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1515
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1516
	save_errno = errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1517
	if (error == -1) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1518
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1519
		errno = save_errno;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1520
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1521
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1522
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1523
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1524
	if (stat_error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1525
		acl_info->acl_flags =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1526
		    (S_ISDIR(statbuf.st_mode) ? ACL_IS_DIR : 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1527
	} else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1528
		acl_info->acl_flags = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1529
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1530
	switch (acl_info->acl_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1531
	case ACLENT_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1532
		if (acl_info->acl_cnt <= MIN_ACL_ENTRIES)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1533
			acl_info->acl_flags |= ACL_IS_TRIVIAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1534
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1535
	case ACE_T:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1536
		if (ace_trivial(acl_info->acl_aclp, acl_info->acl_cnt) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1537
			acl_info->acl_flags |= ACL_IS_TRIVIAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1538
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1539
	default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1540
		errno = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1541
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1542
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1543
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1544
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1545
	if ((acl_info->acl_flags & ACL_IS_TRIVIAL) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1546
	    (get_flag & ACL_NO_TRIVIAL)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1547
		acl_free(acl_info);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1548
		errno = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1549
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1550
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1551
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1552
	*aclp = acl_info;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1553
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1554
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1555
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1556
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1557
 * return -1 on failure, otherwise the number of acl
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1558
 * entries is returned
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1559
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1560
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1561
acl_get(const char *path, int get_flag, acl_t **aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1562
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1563
	acl_inp acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1564
	acl_inp.file = path;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1565
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1566
	return (cacl_get(acl_inp, get_flag, ACL_PATH, aclp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1567
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1568
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1569
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1570
facl_get(int fd, int get_flag, acl_t **aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1571
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1572
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1573
	acl_inp acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1574
	acl_inp.fd = fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1575
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1576
	return (cacl_get(acl_inp, get_flag, ACL_FD, aclp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1577
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1578
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1579
static int
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1580
acl_translate(acl_t *aclp, int target_flavor, int isdir, uid_t owner,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1581
    gid_t group)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1582
{
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1583
	int aclcnt;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1584
	void *acldata;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1585
	int error;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1586
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1587
	/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1588
	 * See if we need to translate
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1589
	 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1590
	if ((target_flavor == _ACL_ACE_ENABLED && aclp->acl_type == ACE_T) ||
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1591
	    (target_flavor == _ACL_ACLENT_ENABLED &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1592
	    aclp->acl_type == ACLENT_T))
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1593
		return (0);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1594
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1595
	if (target_flavor == -1)
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1596
		return (-1);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1597
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1598
	if (target_flavor ==  _ACL_ACE_ENABLED &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1599
	    aclp->acl_type == ACLENT_T) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1600
		error = convert_aent_to_ace(aclp->acl_aclp,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1601
		    aclp->acl_cnt, isdir, (ace_t **)&acldata, &aclcnt);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1602
		if (error) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1603
			errno = error;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1604
			return (-1);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1605
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1606
	} else if (target_flavor == _ACL_ACLENT_ENABLED &&
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1607
	    aclp->acl_type == ACE_T) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1608
		error = convert_ace_to_aent(aclp->acl_aclp, aclp->acl_cnt,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1609
		    isdir, owner, group, (aclent_t **)&acldata, &aclcnt);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1610
		if (error) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1611
			errno = error;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1612
			return (-1);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1613
		}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1614
	} else {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1615
		errno = ENOTSUP;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1616
		return (-1);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1617
	}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1618
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1619
	/*
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1620
	 * replace old acl with newly translated acl
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1621
	 */
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1622
	free(aclp->acl_aclp);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1623
	aclp->acl_aclp = acldata;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1624
	aclp->acl_cnt = aclcnt;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1625
	aclp->acl_type = (target_flavor == _ACL_ACE_ENABLED) ? ACE_T : ACLENT_T;
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1626
	return (0);
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1627
}
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1628
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1629
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1630
 * Set an ACL, translates acl to ace_t when appropriate.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1631
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1632
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1633
cacl_set(acl_inp *acl_inp, acl_t *aclp, int type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1634
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1635
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1636
	int acl_flavor_target;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1637
	struct stat64 statbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1638
	int stat_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1639
	int isdir;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1640
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1641
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1642
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1643
		stat_error = stat64(acl_inp->file, &statbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1644
		if (stat_error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1645
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1646
		acl_flavor_target = pathconf(acl_inp->file, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1647
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1648
		stat_error = fstat64(acl_inp->fd, &statbuf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1649
		if (stat_error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1650
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1651
		acl_flavor_target = fpathconf(acl_inp->fd, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1652
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1653
1666
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1654
	/*
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1655
	 * If target returns an error or 0 from pathconf call then
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1656
	 * fall back to UFS/POSIX Draft interface.
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1657
	 * In the case of 0 we will then fail in either acl(2) or
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1658
	 * acl_translate().  We could erroneously get 0 back from
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1659
	 * a file system that is using fs_pathconf() and not answering
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1660
	 * the _PC_ACL_ENABLED question itself.
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1661
	 */
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1662
	if (acl_flavor_target == 0 || acl_flavor_target == -1)
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1663
		acl_flavor_target = _ACL_ACLENT_ENABLED;
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1664
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1665
	isdir = S_ISDIR(statbuf.st_mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1666
1462
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1667
	if ((error = acl_translate(aclp, acl_flavor_target, isdir,
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1668
	    statbuf.st_uid, statbuf.st_gid)) != 0) {
117f7ea5a828 6355341 tar cannot restore ACLs to UFS
marks
parents: 1420
diff changeset
  1669
		return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1670
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1671
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1672
	if (type == ACL_PATH) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1673
		error = acl(acl_inp->file,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1674
		    (aclp->acl_type == ACE_T) ? ACE_SETACL : SETACL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1675
		    aclp->acl_cnt, aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1676
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1677
		error = facl(acl_inp->fd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1678
		    (aclp->acl_type == ACE_T) ? ACE_SETACL : SETACL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1679
		    aclp->acl_cnt, aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1680
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1681
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1682
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1683
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1684
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1685
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1686
acl_set(const char *path, acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1687
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1688
	acl_inp acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1689
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1690
	acl_inp.file = path;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1691
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1692
	return (cacl_set(&acl_inp, aclp, ACL_PATH));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1693
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1694
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1695
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1696
facl_set(int fd, acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1697
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1698
	acl_inp acl_inp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1699
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1700
	acl_inp.fd = fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1701
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1702
	return (cacl_set(&acl_inp, aclp, ACL_FD));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1703
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1704
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1705
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1706
acl_cnt(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1707
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1708
	return (aclp->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1709
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1710
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1711
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1712
acl_type(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1713
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1714
	return (aclp->acl_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1715
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1716
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1717
acl_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1718
acl_dup(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1719
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1720
	acl_t *newaclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1721
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1722
	newaclp = acl_alloc(aclp->acl_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1723
	if (newaclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1724
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1725
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1726
	newaclp->acl_aclp = malloc(aclp->acl_entry_size * aclp->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1727
	if (newaclp->acl_aclp == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1728
		acl_free(newaclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1729
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1730
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1731
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1732
	(void) memcpy(newaclp->acl_aclp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1733
	    aclp->acl_aclp, aclp->acl_entry_size * aclp->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1734
	newaclp->acl_cnt = aclp->acl_cnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1735
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1736
	return (newaclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1737
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1738
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1739
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1740
acl_flags(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1741
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1742
	return (aclp->acl_flags);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1743
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1744
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1745
void *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1746
acl_data(acl_t *aclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1747
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1748
	return (aclp->acl_aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1749
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1750
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1751
/*
1953
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1752
 * Take an acl array and build an acl_t.
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1753
 */
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1754
acl_t *
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1755
acl_to_aclp(enum acl_type type, void *acl, int count)
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1756
{
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1757
	acl_t *aclp;
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1758
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1759
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1760
	aclp = acl_alloc(type);
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1761
	if (aclp == NULL)
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1762
		return (aclp);
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1763
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1764
	aclp->acl_aclp = acl;
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1765
	aclp->acl_cnt = count;
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1766
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1767
	return (aclp);
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1768
}
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1769
7d218c488035 6421216 ufsrestore should use acl_set() for setting ACLs
marks
parents: 1666
diff changeset
  1770
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1771
 * Remove an ACL from a file and create a trivial ACL based
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1772
 * off of the mode argument.  After acl has been set owner/group
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1773
 * are updated to match owner,group arguments
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1774
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1775
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1776
acl_strip(const char *file, uid_t owner, gid_t group, mode_t mode)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1777
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1778
	int	error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1779
	aclent_t min_acl[MIN_ACL_ENTRIES];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1780
	ace_t	min_ace_acl[6];	/* owner, group, everyone + complement denies */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1781
	int	acl_flavor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1782
	int	aclcnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1783
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1784
	acl_flavor = pathconf(file, _PC_ACL_ENABLED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1785
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1786
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1787
	 * force it through aclent flavor when file system doesn't
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1788
	 * understand question
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1789
	 */
1666
07697c578888 6401243 ZFS ACLs should not break third party filesystems
marks
parents: 1477
diff changeset
  1790
	if (acl_flavor == 0 || acl_flavor == -1)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1791
		acl_flavor = _ACL_ACLENT_ENABLED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1792
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1793
	if (acl_flavor & _ACL_ACLENT_ENABLED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1794
		min_acl[0].a_type = USER_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1795
		min_acl[0].a_id   = owner;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1796
		min_acl[0].a_perm = ((mode & 0700) >> 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1797
		min_acl[1].a_type = GROUP_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1798
		min_acl[1].a_id   = group;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1799
		min_acl[1].a_perm = ((mode & 0070) >> 3);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1800
		min_acl[2].a_type = CLASS_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1801
		min_acl[2].a_id   = (uid_t)-1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1802
		min_acl[2].a_perm = ((mode & 0070) >> 3);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1803
		min_acl[3].a_type = OTHER_OBJ;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1804
		min_acl[3].a_id   = (uid_t)-1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1805
		min_acl[3].a_perm = (mode & 0007);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1806
		aclcnt = 4;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1807
		error = acl(file, SETACL, aclcnt, min_acl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1808
	} else if (acl_flavor & _ACL_ACE_ENABLED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1809
		(void) memcpy(min_ace_acl, trivial_acl, sizeof (ace_t) * 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1810
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1811
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1812
		 * Make aces match request mode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1813
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1814
		adjust_ace_pair(&min_ace_acl[0], (mode & 0700) >> 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1815
		adjust_ace_pair(&min_ace_acl[2], (mode & 0070) >> 3);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1816
		adjust_ace_pair(&min_ace_acl[4], mode & 0007);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1817
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1818
		error = acl(file, ACE_SETACL, 6, min_ace_acl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1819
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1820
		errno = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1821
		error = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1822
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1823
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1824
	if (error == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1825
		error = chown(file, owner, group);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1826
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1827
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1828
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1829
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1830
ace_match(void *entry1, void *entry2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1831
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1832
	ace_t *p1 = (ace_t *)entry1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1833
	ace_t *p2 = (ace_t *)entry2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1834
	ace_t ace1, ace2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1835
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1836
	ace1 = *p1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1837
	ace2 = *p2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1838
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1839
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1840
	 * Need to fixup who field for abstrations for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1841
	 * accurate comparison, since field is undefined.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1842
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1843
	if (ace1.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1844
		ace1.a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1845
	if (ace2.a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1846
		ace2.a_who = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1847
	return (memcmp(&ace1, &ace2, sizeof (ace_t)));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1848
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1849
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1850
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1851
aclent_match(void *entry1, void *entry2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1852
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1853
	aclent_t *aclent1 = (aclent_t *)entry1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1854
	aclent_t *aclent2 = (aclent_t *)entry2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1855
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1856
	return (memcmp(aclent1, aclent2, sizeof (aclent_t)));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1857
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1858
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1859
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1860
 * Find acl entries in acl that correspond to removeacl.  Search
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1861
 * is started from slot.  The flag argument indicates whether to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1862
 * remove all matches or just the first match.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1863
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1864
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1865
acl_removeentries(acl_t *acl, acl_t *removeacl, int start_slot, int flag)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1866
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1867
	int i, j;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1868
	int match;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1869
	int (*acl_match)(void *acl1, void *acl2);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1870
	void *acl_entry, *remove_entry;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1871
	void *start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1872
	int found = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1873
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1874
	if (flag != ACL_REMOVE_ALL && flag != ACL_REMOVE_FIRST)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1875
		flag = ACL_REMOVE_FIRST;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1876
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1877
	if (acl == NULL || removeacl == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1878
		return (EACL_NO_ACL_ENTRY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1879
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1880
	if (acl->acl_type != removeacl->acl_type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1881
		return (EACL_DIFF_TYPE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1882
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1883
	if (acl->acl_type == ACLENT_T)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1884
		acl_match = aclent_match;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1885
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1886
		acl_match = ace_match;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1887
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1888
	for (i = 0, remove_entry = removeacl->acl_aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1889
	    i != removeacl->acl_cnt; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1890
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1891
		j = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1892
		acl_entry = (char *)acl->acl_aclp +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1893
		    (acl->acl_entry_size * start_slot);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1894
		for (;;) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1895
			match = acl_match(acl_entry, remove_entry);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1896
			if (match == 0)  {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1897
				found++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1898
				start = (char *)acl_entry +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1899
				    acl->acl_entry_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1900
				(void) memmove(acl_entry, start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1901
				    acl->acl_entry_size *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1902
				    acl->acl_cnt-- - (j + 1));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1903
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1904
				if (flag == ACL_REMOVE_FIRST)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1905
					break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1906
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1907
				 * List has changed, restart search from
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1908
				 * beginning.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1909
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1910
				acl_entry = acl->acl_aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1911
				j = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1912
				continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1913
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1914
			acl_entry = ((char *)acl_entry + acl->acl_entry_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1915
			if (++j >= acl->acl_cnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1916
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1917
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1918
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1919
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1920
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1921
	return ((found == 0) ? EACL_NO_ACL_ENTRY : 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1922
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1923
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1924
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1925
 * Replace entires entries in acl1 with the corresponding entries
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1926
 * in newentries.  The where argument specifies where to begin
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1927
 * the replacement.  If the where argument is 1 greater than the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1928
 * number of acl entries in acl1 then they are appended.  If the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1929
 * where argument is 2+ greater than the number of acl entries then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1930
 * EACL_INVALID_SLOT is returned.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1931
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1932
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1933
acl_modifyentries(acl_t *acl1, acl_t *newentries, int where)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1934
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1935
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1936
	int slot;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1937
	int slots_needed;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1938
	int slots_left;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1939
	int newsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1940
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1941
	if (acl1 == NULL || newentries == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1942
		return (EACL_NO_ACL_ENTRY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1943
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1944
	if (where < 0 || where >= acl1->acl_cnt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1945
		return (EACL_INVALID_SLOT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1946
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1947
	if (acl1->acl_type != newentries->acl_type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1948
		return (EACL_DIFF_TYPE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1949
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1950
	slot = where;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1951
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1952
	slots_left = acl1->acl_cnt - slot + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1953
	if (slots_left < newentries->acl_cnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1954
		slots_needed = newentries->acl_cnt - slots_left;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1955
		newsize = (acl1->acl_entry_size * acl1->acl_cnt) +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1956
		    (acl1->acl_entry_size * slots_needed);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1957
		acl1->acl_aclp = realloc(acl1->acl_aclp, newsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1958
		if (acl1->acl_aclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1959
			return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1960
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1961
	(void) memcpy((char *)acl1->acl_aclp + (acl1->acl_entry_size * slot),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1962
	    newentries->acl_aclp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1963
	    newentries->acl_entry_size * newentries->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1964
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1965
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1966
	 * Did ACL grow?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1967
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1968
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1969
	if ((slot + newentries->acl_cnt) > acl1->acl_cnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1970
		acl1->acl_cnt = slot + newentries->acl_cnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1971
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1972
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1973
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1974
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1975
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1976
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1977
 * Add acl2 entries into acl1.  The where argument specifies where
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1978
 * to add the entries.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1979
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1980
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1981
acl_addentries(acl_t *acl1, acl_t *acl2, int where)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1982
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1983
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1984
	int newsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1985
	int len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1986
	void *start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1987
	void *to;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1988
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1989
	if (acl1 == NULL || acl2 == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1990
		return (EACL_NO_ACL_ENTRY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1991
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1992
	if (acl1->acl_type != acl2->acl_type)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1993
		return (EACL_DIFF_TYPE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1994
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1995
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1996
	 * allow where to specify 1 past last slot for an append operation
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1997
	 * but anything greater is an error.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1998
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1999
	if (where < 0 || where > acl1->acl_cnt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2000
		return (EACL_INVALID_SLOT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2001
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2002
	newsize = (acl2->acl_entry_size * acl2->acl_cnt) +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2003
	    (acl1->acl_entry_size * acl1->acl_cnt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2004
	acl1->acl_aclp = realloc(acl1->acl_aclp, newsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2005
	if (acl1->acl_aclp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2006
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2007
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2008
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2009
	 * first push down entries where new ones will be inserted
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2010
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2011
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2012
	to = (void *)((char *)acl1->acl_aclp +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2013
	    ((where + acl2->acl_cnt) * acl1->acl_entry_size));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2014
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2015
	start = (void *)((char *)acl1->acl_aclp +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2016
	    where * acl1->acl_entry_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2017
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2018
	if (where < acl1->acl_cnt) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2019
		len = (acl1->acl_cnt - where) * acl1->acl_entry_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2020
		(void) memmove(to, start, len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2021
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2022
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2023
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2024
	 * now stick in new entries.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2025
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2026
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2027
	(void) memmove(start, acl2->acl_aclp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2028
	    acl2->acl_cnt * acl2->acl_entry_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2029
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2030
	acl1->acl_cnt += acl2->acl_cnt;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2031
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2032
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2033
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2034
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2035
 * return text for an ACL error.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2036
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2037
char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2038
acl_strerror(int errnum)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2039
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2040
	switch (errnum) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2041
	case EACL_GRP_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2042
		return (dgettext(TEXT_DOMAIN,
1420
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2043
		    "There is more than one group or default group entry"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2044
	case EACL_USER_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2045
		return (dgettext(TEXT_DOMAIN,
1420
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2046
		    "There is more than one user or default user entry"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2047
	case EACL_OTHER_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2048
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2049
		    "There is more than one other entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2050
	case EACL_CLASS_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2051
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2052
		    "There is more than one mask entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2053
	case EACL_DUPLICATE_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2054
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2055
		    "Duplicate user or group entries"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2056
	case EACL_MISS_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2057
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2058
		    "Missing user/group owner, other, mask entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2059
	case EACL_MEM_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2060
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2061
		    "Memory error"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2062
	case EACL_ENTRY_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2063
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2064
		    "Unrecognized entry type"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2065
	case EACL_INHERIT_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2066
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2067
		    "Invalid inheritance flags"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2068
	case EACL_FLAGS_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2069
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2070
		    "Unrecognized entry flags"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2071
	case EACL_PERM_MASK_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2072
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2073
		    "Invalid ACL permissions"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2074
	case EACL_COUNT_ERROR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2075
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2076
		    "Invalid ACL count"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2077
	case EACL_INVALID_SLOT:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2078
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2079
		    "Invalid ACL entry number specified"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2080
	case EACL_NO_ACL_ENTRY:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2081
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2082
		    "ACL entry doesn't exist"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2083
	case EACL_DIFF_TYPE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2084
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2085
		    "ACL type's are different"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2086
	case EACL_INVALID_USER_GROUP:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2087
		return (dgettext(TEXT_DOMAIN, "Invalid user or group"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2088
	case EACL_INVALID_STR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2089
		return (dgettext(TEXT_DOMAIN, "ACL string is invalid"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2090
	case EACL_FIELD_NOT_BLANK:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2091
		return (dgettext(TEXT_DOMAIN, "Field expected to be blank"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2092
	case EACL_INVALID_ACCESS_TYPE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2093
		return (dgettext(TEXT_DOMAIN, "Invalid access type"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2094
	case EACL_UNKNOWN_DATA:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2095
		return (dgettext(TEXT_DOMAIN, "Unrecognized entry"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2096
	case EACL_MISSING_FIELDS:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2097
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2098
		    "ACL specification missing required fields"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2099
	case EACL_INHERIT_NOTDIR:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2100
		return (dgettext(TEXT_DOMAIN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2101
		    "Inheritance flags are only allowed on directories"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2102
	case -1:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2103
		return (strerror(errno));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2104
	default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2105
		errno = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2106
		return (dgettext(TEXT_DOMAIN, "Unknown error"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2107
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2108
}
1420
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2109
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2110
extern int yyinteractive;
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2111
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2112
/* PRINTFLIKE1 */
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2113
void
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2114
acl_error(const char *fmt, ...)
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2115
{
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2116
	va_list va;
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2117
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2118
	if (yyinteractive == 0)
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2119
		return;
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2120
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2121
	va_start(va, fmt);
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2122
	(void) vfprintf(stderr, fmt, va);
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2123
	va_end(va);
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 1231
diff changeset
  2124
}