usr/src/uts/common/fs/zfs/zfs_acl.c
author marks
Thu, 21 Feb 2008 13:21:27 -0800
changeset 6056 37f30782c577
parent 5959 1e1904b8526d
child 6257 0c7475fa4852
permissions -rw-r--r--
6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
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
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
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
/*
5762
a454af064490 6646907 mismerge in zfs_mode_fuid_compute()
marks
parents: 5489
diff changeset
    22
 * Copyright 2008 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 <sys/types.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/param.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/time.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/systm.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/sysmacros.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/resource.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/vfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/vnode.h>
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    36
#include <sys/sid.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <sys/file.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/stat.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
#include <sys/kmem.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include <sys/cmn_err.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <sys/errno.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
#include <sys/unistd.h>
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
    43
#include <sys/sdt.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#include <sys/fs/zfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
#include <sys/mode.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
#include <sys/policy.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
#include <sys/zfs_znode.h>
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    48
#include <sys/zfs_fuid.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
#include <sys/zfs_acl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
#include <sys/zfs_dir.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
#include <sys/zfs_vfsops.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
#include <sys/dmu.h>
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    53
#include <sys/dnode.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
#include <sys/zap.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
#include "fs/fs_subr.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
#include <acl/acl_common.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
#define	ALLOW	ACE_ACCESS_ALLOWED_ACE_TYPE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
#define	DENY	ACE_ACCESS_DENIED_ACE_TYPE
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    60
#define	MAX_ACE_TYPE	ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
#define	OWNING_GROUP		(ACE_GROUP|ACE_IDENTIFIER_GROUP)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
#define	EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
    ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
#define	EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
    ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
#define	OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
    ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS)
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    69
#define	WRITE_MASK_DATA (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    70
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    71
#define	ZFS_CHECKED_MASKS (ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_DATA| \
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    72
    ACE_READ_NAMED_ATTRS|ACE_WRITE_DATA|ACE_WRITE_ATTRIBUTES| \
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    73
    ACE_WRITE_NAMED_ATTRS|ACE_APPEND_DATA|ACE_EXECUTE|ACE_WRITE_OWNER| \
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    74
    ACE_WRITE_ACL|ACE_DELETE|ACE_DELETE_CHILD|ACE_SYNCHRONIZE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    75
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    76
#define	WRITE_MASK (WRITE_MASK_DATA|ACE_WRITE_ATTRIBUTES|ACE_WRITE_ACL|\
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    77
    ACE_WRITE_OWNER)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
#define	OGE_CLEAR	(ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
    ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
#define	OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
    ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
#define	ALL_INHERIT	(ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    86
    ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE|ACE_INHERITED_ACE)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
    88
#define	SECURE_CLEAR	(ACE_WRITE_ACL|ACE_WRITE_OWNER)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    90
#define	V4_ACL_WIDE_FLAGS (ZFS_ACL_AUTO_INHERIT|ZFS_ACL_DEFAULTED|\
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    91
    ZFS_ACL_PROTECTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    92
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    93
#define	ZFS_ACL_WIDE_FLAGS (V4_ACL_WIDE_FLAGS|ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE|\
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    94
    ZFS_ACL_OBJ_ACE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    95
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    96
static uint16_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    97
zfs_ace_v0_get_type(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    98
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
    99
	return (((zfs_oldace_t *)acep)->z_type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   100
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   101
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   102
static uint16_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   103
zfs_ace_v0_get_flags(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   104
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   105
	return (((zfs_oldace_t *)acep)->z_flags);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   106
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   107
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   108
static uint32_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   109
zfs_ace_v0_get_mask(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   110
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   111
	return (((zfs_oldace_t *)acep)->z_access_mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   112
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   113
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   114
static uint64_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   115
zfs_ace_v0_get_who(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   116
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   117
	return (((zfs_oldace_t *)acep)->z_fuid);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   118
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   119
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   120
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   121
zfs_ace_v0_set_type(void *acep, uint16_t type)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   122
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   123
	((zfs_oldace_t *)acep)->z_type = type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   124
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   125
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   126
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   127
zfs_ace_v0_set_flags(void *acep, uint16_t flags)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   128
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   129
	((zfs_oldace_t *)acep)->z_flags = flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   130
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   131
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   132
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   133
zfs_ace_v0_set_mask(void *acep, uint32_t mask)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   134
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   135
	((zfs_oldace_t *)acep)->z_access_mask = mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   136
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   137
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   138
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   139
zfs_ace_v0_set_who(void *acep, uint64_t who)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   140
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   141
	((zfs_oldace_t *)acep)->z_fuid = who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   142
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   143
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   144
/*ARGSUSED*/
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   145
static size_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   146
zfs_ace_v0_size(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   147
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   148
	return (sizeof (zfs_oldace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   149
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   150
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   151
static size_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   152
zfs_ace_v0_abstract_size(void)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   153
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   154
	return (sizeof (zfs_oldace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   155
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   156
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   157
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   158
zfs_ace_v0_mask_off(void)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   159
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   160
	return (offsetof(zfs_oldace_t, z_access_mask));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   161
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   162
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   163
/*ARGSUSED*/
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   164
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   165
zfs_ace_v0_data(void *acep, void **datap)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   166
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   167
	*datap = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   168
	return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   169
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   170
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   171
static acl_ops_t zfs_acl_v0_ops = {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   172
	zfs_ace_v0_get_mask,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   173
	zfs_ace_v0_set_mask,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   174
	zfs_ace_v0_get_flags,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   175
	zfs_ace_v0_set_flags,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   176
	zfs_ace_v0_get_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   177
	zfs_ace_v0_set_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   178
	zfs_ace_v0_get_who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   179
	zfs_ace_v0_set_who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   180
	zfs_ace_v0_size,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   181
	zfs_ace_v0_abstract_size,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   182
	zfs_ace_v0_mask_off,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   183
	zfs_ace_v0_data
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   184
};
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   185
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   186
static uint16_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   187
zfs_ace_fuid_get_type(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   188
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   189
	return (((zfs_ace_hdr_t *)acep)->z_type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   190
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   191
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   192
static uint16_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   193
zfs_ace_fuid_get_flags(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   194
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   195
	return (((zfs_ace_hdr_t *)acep)->z_flags);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   196
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   197
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   198
static uint32_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   199
zfs_ace_fuid_get_mask(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   200
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   201
	return (((zfs_ace_hdr_t *)acep)->z_access_mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   202
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   203
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   204
static uint64_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   205
zfs_ace_fuid_get_who(void *args)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   206
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   207
	uint16_t entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   208
	zfs_ace_t *acep = args;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   209
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   210
	entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   212
	if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP ||
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   213
	    entry_type == ACE_EVERYONE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   214
		return (-1);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   215
	return (((zfs_ace_t *)acep)->z_fuid);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   216
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   217
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   218
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   219
zfs_ace_fuid_set_type(void *acep, uint16_t type)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   220
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   221
	((zfs_ace_hdr_t *)acep)->z_type = type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   222
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   223
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   224
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   225
zfs_ace_fuid_set_flags(void *acep, uint16_t flags)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   226
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   227
	((zfs_ace_hdr_t *)acep)->z_flags = flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   228
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   229
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   230
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   231
zfs_ace_fuid_set_mask(void *acep, uint32_t mask)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   232
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   233
	((zfs_ace_hdr_t *)acep)->z_access_mask = mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   234
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   235
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   236
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   237
zfs_ace_fuid_set_who(void *arg, uint64_t who)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   238
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   239
	zfs_ace_t *acep = arg;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   240
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   241
	uint16_t entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   242
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   243
	if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP ||
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   244
	    entry_type == ACE_EVERYONE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   245
		return;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   246
	acep->z_fuid = who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   247
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   248
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   249
static size_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   250
zfs_ace_fuid_size(void *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   251
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   252
	zfs_ace_hdr_t *zacep = acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   253
	uint16_t entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   254
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   255
	switch (zacep->z_type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   256
	case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   257
	case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   258
	case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   259
	case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   260
		return (sizeof (zfs_object_ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   261
	case ALLOW:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   262
	case DENY:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   263
		entry_type =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   264
		    (((zfs_ace_hdr_t *)acep)->z_flags & ACE_TYPE_FLAGS);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   265
		if (entry_type == ACE_OWNER ||
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   266
		    entry_type == (ACE_GROUP | ACE_IDENTIFIER_GROUP) ||
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   267
		    entry_type == ACE_EVERYONE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   268
			return (sizeof (zfs_ace_hdr_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   269
		/*FALLTHROUGH*/
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   270
	default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   271
		return (sizeof (zfs_ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   272
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   273
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   274
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   275
static size_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   276
zfs_ace_fuid_abstract_size(void)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   277
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   278
	return (sizeof (zfs_ace_hdr_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   279
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   280
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   281
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   282
zfs_ace_fuid_mask_off(void)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   283
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   284
	return (offsetof(zfs_ace_hdr_t, z_access_mask));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   285
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   286
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   287
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   288
zfs_ace_fuid_data(void *acep, void **datap)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   289
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   290
	zfs_ace_t *zacep = acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   291
	zfs_object_ace_t *zobjp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   292
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   293
	switch (zacep->z_hdr.z_type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   294
	case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   295
	case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   296
	case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   297
	case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   298
		zobjp = acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   299
		*datap = (caddr_t)zobjp + sizeof (zfs_ace_t);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   300
		return (sizeof (zfs_object_ace_t) - sizeof (zfs_ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   301
	default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   302
		*datap = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   303
		return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   304
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   305
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   306
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   307
static acl_ops_t zfs_acl_fuid_ops = {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   308
	zfs_ace_fuid_get_mask,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   309
	zfs_ace_fuid_set_mask,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   310
	zfs_ace_fuid_get_flags,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   311
	zfs_ace_fuid_set_flags,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   312
	zfs_ace_fuid_get_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   313
	zfs_ace_fuid_set_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   314
	zfs_ace_fuid_get_who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   315
	zfs_ace_fuid_set_who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   316
	zfs_ace_fuid_size,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   317
	zfs_ace_fuid_abstract_size,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   318
	zfs_ace_fuid_mask_off,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   319
	zfs_ace_fuid_data
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   320
};
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   321
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   322
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   323
zfs_acl_version(int version)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   324
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   325
	if (version < ZPL_VERSION_FUID)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   326
		return (ZFS_ACL_VERSION_INITIAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   327
	else
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   328
		return (ZFS_ACL_VERSION_FUID);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   329
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   330
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   331
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   332
zfs_acl_version_zp(znode_t *zp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   333
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   334
	return (zfs_acl_version(zp->z_zfsvfs->z_version));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   335
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
static zfs_acl_t *
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   338
zfs_acl_alloc(int vers)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
	zfs_acl_t *aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
	aclp = kmem_zalloc(sizeof (zfs_acl_t), KM_SLEEP);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   343
	list_create(&aclp->z_acl, sizeof (zfs_acl_node_t),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   344
	    offsetof(zfs_acl_node_t, z_next));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   345
	aclp->z_version = vers;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   346
	if (vers == ZFS_ACL_VERSION_FUID)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   347
		aclp->z_ops = zfs_acl_fuid_ops;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   348
	else
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   349
		aclp->z_ops = zfs_acl_v0_ops;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   350
	return (aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   351
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   352
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   353
static zfs_acl_node_t *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   354
zfs_acl_node_alloc(size_t bytes)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   355
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   356
	zfs_acl_node_t *aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   357
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   358
	aclnode = kmem_zalloc(sizeof (zfs_acl_node_t), KM_SLEEP);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   359
	if (bytes) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   360
		aclnode->z_acldata = kmem_alloc(bytes, KM_SLEEP);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   361
		aclnode->z_allocdata = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   362
		aclnode->z_allocsize = bytes;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   363
		aclnode->z_size = bytes;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   365
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   366
	return (aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   367
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   368
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   369
static void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   370
zfs_acl_node_free(zfs_acl_node_t *aclnode)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   371
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   372
	if (aclnode->z_allocsize)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   373
		kmem_free(aclnode->z_allocdata, aclnode->z_allocsize);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   374
	kmem_free(aclnode, sizeof (zfs_acl_node_t));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   377
static void
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   378
zfs_acl_release_nodes(zfs_acl_t *aclp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   380
	zfs_acl_node_t *aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   381
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   382
	while (aclnode = list_head(&aclp->z_acl)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   383
		list_remove(&aclp->z_acl, aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   384
		zfs_acl_node_free(aclnode);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
	}
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   386
	aclp->z_acl_count = 0;
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   387
	aclp->z_acl_bytes = 0;
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   388
}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   389
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   390
void
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   391
zfs_acl_free(zfs_acl_t *aclp)
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   392
{
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   393
	zfs_acl_release_nodes(aclp);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   394
	list_destroy(&aclp->z_acl);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
	kmem_free(aclp, sizeof (zfs_acl_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   398
static boolean_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   399
zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   401
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   402
	 * first check type of entry
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   403
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   404
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   405
	switch (iflags & ACE_TYPE_FLAGS) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   406
	case ACE_OWNER:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   407
	case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   408
	case ACE_IDENTIFIER_GROUP:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   409
	case ACE_EVERYONE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   410
	case 0:	/* User entry */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   411
		break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   412
	default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   413
		return (B_FALSE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   414
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   415
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   416
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   417
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   418
	 * next check inheritance level flags
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   419
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   420
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   421
	if (type != ALLOW && type > MAX_ACE_TYPE) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   422
		return (B_FALSE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   423
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   424
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   425
	switch (type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   426
	case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   427
	case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   428
	case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   429
	case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   430
		if (aclp->z_version < ZFS_ACL_VERSION_FUID)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   431
			return (B_FALSE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   432
		aclp->z_hints |= ZFS_ACL_OBJ_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   433
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
   435
	/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   436
	 * Only directories should have inheritance flags.
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
   437
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   438
	if (obj_type != VDIR && (iflags &
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   439
	    (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE|
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   440
	    ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE))) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   441
		return (B_FALSE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   442
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   443
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   444
	if (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   445
		aclp->z_hints |= ZFS_INHERIT_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   446
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   447
	if (iflags & (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   448
		if ((iflags & (ACE_FILE_INHERIT_ACE|
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   449
		    ACE_DIRECTORY_INHERIT_ACE)) == 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   450
			return (B_FALSE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   451
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   452
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   453
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   454
	return (B_TRUE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   455
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   456
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   457
static void *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   458
zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   459
    uint32_t *access_mask, uint16_t *iflags, uint16_t *type)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   460
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   461
	zfs_acl_node_t *aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   462
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   463
	if (start == NULL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   464
		aclnode = list_head(&aclp->z_acl);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   465
		if (aclnode == NULL)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   466
			return (NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   467
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   468
		aclp->z_next_ace = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   469
		aclp->z_curr_node = aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   470
		aclnode->z_ace_idx = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   471
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   472
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   473
	aclnode = aclp->z_curr_node;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   474
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   475
	if (aclnode == NULL)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   476
		return (NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   477
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   478
	if (aclnode->z_ace_idx >= aclnode->z_ace_count) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   479
		aclnode = list_next(&aclp->z_acl, aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   480
		if (aclnode == NULL)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   481
			return (NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   482
		else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   483
			aclp->z_curr_node = aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   484
			aclnode->z_ace_idx = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   485
			aclp->z_next_ace = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   486
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   487
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   488
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   489
	if (aclnode->z_ace_idx < aclnode->z_ace_count) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   490
		void *acep = aclp->z_next_ace;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   491
		*iflags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   492
		*type = aclp->z_ops.ace_type_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   493
		*access_mask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   494
		*who = aclp->z_ops.ace_who_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   495
		aclp->z_next_ace = (caddr_t)aclp->z_next_ace +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   496
		    aclp->z_ops.ace_size(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   497
		aclnode->z_ace_idx++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   498
		return ((void *)acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   499
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   500
	return (NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   501
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   502
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   503
/*ARGSUSED*/
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   504
static uint64_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   505
zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   506
    uint16_t *flags, uint16_t *type, uint32_t *mask)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   507
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   508
	zfs_acl_t *aclp = datap;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   509
	zfs_ace_hdr_t *acep = (zfs_ace_hdr_t *)(uintptr_t)cookie;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   510
	uint64_t who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   511
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   512
	acep = zfs_acl_next_ace(aclp, acep, &who, mask,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   513
	    flags, type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   514
	return ((uint64_t)(uintptr_t)acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   515
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   516
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   517
static zfs_acl_node_t *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   518
zfs_acl_curr_node(zfs_acl_t *aclp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   519
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   520
	ASSERT(aclp->z_curr_node);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   521
	return (aclp->z_curr_node);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   522
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   523
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   524
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   525
 * Copy ACE to internal ZFS format.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   526
 * While processing the ACL each ACE will be validated for correctness.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   527
 * ACE FUIDs will be created later.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   528
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   529
int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   530
zfs_copy_ace_2_fuid(vtype_t obj_type, zfs_acl_t *aclp, void *datap,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   531
    zfs_ace_t *z_acl, int aclcnt, size_t *size)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   532
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   533
	int i;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   534
	uint16_t entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   535
	zfs_ace_t *aceptr = z_acl;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   536
	ace_t *acep = datap;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   537
	zfs_object_ace_t *zobjacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   538
	ace_object_t *aceobjp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   539
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   540
	for (i = 0; i != aclcnt; i++) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   541
		aceptr->z_hdr.z_access_mask = acep->a_access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   542
		aceptr->z_hdr.z_flags = acep->a_flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   543
		aceptr->z_hdr.z_type = acep->a_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   544
		entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   545
		if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP &&
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
   546
		    entry_type != ACE_EVERYONE) {
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
   547
			if (!aclp->z_has_fuids)
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   548
				aclp->z_has_fuids = IS_EPHEMERAL(acep->a_who);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   549
			aceptr->z_fuid = (uint64_t)acep->a_who;
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
   550
		}
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
   551
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   552
		/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   553
		 * Make sure ACE is valid
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   554
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   555
		if (zfs_ace_valid(obj_type, aclp, aceptr->z_hdr.z_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   556
		    aceptr->z_hdr.z_flags) != B_TRUE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   557
			return (EINVAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   558
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   559
		switch (acep->a_type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   560
		case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   561
		case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   562
		case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   563
		case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   564
			zobjacep = (zfs_object_ace_t *)aceptr;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   565
			aceobjp = (ace_object_t *)acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   566
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   567
			bcopy(aceobjp->a_obj_type, zobjacep->z_object_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   568
			    sizeof (aceobjp->a_obj_type));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   569
			bcopy(aceobjp->a_inherit_obj_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   570
			    zobjacep->z_inherit_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   571
			    sizeof (aceobjp->a_inherit_obj_type));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   572
			acep = (ace_t *)((caddr_t)acep + sizeof (ace_object_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   573
			break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   574
		default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   575
			acep = (ace_t *)((caddr_t)acep + sizeof (ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   576
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   577
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   578
		aceptr = (zfs_ace_t *)((caddr_t)aceptr +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   579
		    aclp->z_ops.ace_size(aceptr));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   580
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   581
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   582
	*size = (caddr_t)aceptr - (caddr_t)z_acl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   584
	return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   585
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   586
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   587
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   588
 * Copy ZFS ACEs to fixed size ace_t layout
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   589
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   590
static void
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   591
zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr,
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   592
    void *datap, int filter)
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   593
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   594
	uint64_t who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   595
	uint32_t access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   596
	uint16_t iflags, type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   597
	zfs_ace_hdr_t *zacep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   598
	ace_t *acep = datap;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   599
	ace_object_t *objacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   600
	zfs_object_ace_t *zobjacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   601
	size_t ace_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   602
	uint16_t entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   603
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   604
	while (zacep = zfs_acl_next_ace(aclp, zacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   605
	    &who, &access_mask, &iflags, &type)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   606
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   607
		switch (type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   608
		case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   609
		case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   610
		case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   611
		case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   612
			if (filter) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   613
				continue;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   614
			}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   615
			zobjacep = (zfs_object_ace_t *)zacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   616
			objacep = (ace_object_t *)acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   617
			bcopy(zobjacep->z_object_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   618
			    objacep->a_obj_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   619
			    sizeof (zobjacep->z_object_type));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   620
			bcopy(zobjacep->z_inherit_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   621
			    objacep->a_inherit_obj_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   622
			    sizeof (zobjacep->z_inherit_type));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   623
			ace_size = sizeof (ace_object_t);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   624
			break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   625
		default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   626
			ace_size = sizeof (ace_t);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   627
			break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   628
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   629
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   630
		entry_type = (iflags & ACE_TYPE_FLAGS);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   631
		if ((entry_type != ACE_OWNER &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   632
		    entry_type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) &&
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   633
		    entry_type != ACE_EVERYONE)) {
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   634
			acep->a_who = zfs_fuid_map_id(zfsvfs, who,
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   635
			    cr, (entry_type & ACE_IDENTIFIER_GROUP) ?
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   636
			    ZFS_ACE_GROUP : ZFS_ACE_USER);
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   637
		} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   638
			acep->a_who = (uid_t)(int64_t)who;
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   639
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   640
		acep->a_access_mask = access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   641
		acep->a_flags = iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   642
		acep->a_type = type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   643
		acep = (ace_t *)((caddr_t)acep + ace_size);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   644
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   645
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   646
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   647
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   648
zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   649
    zfs_oldace_t *z_acl, int aclcnt, size_t *size)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   650
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   651
	int i;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   652
	zfs_oldace_t *aceptr = z_acl;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   653
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   654
	for (i = 0; i != aclcnt; i++, aceptr++) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   655
		aceptr->z_access_mask = acep[i].a_access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   656
		aceptr->z_type = acep[i].a_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   657
		aceptr->z_flags = acep[i].a_flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   658
		aceptr->z_fuid = acep[i].a_who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   659
		/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   660
		 * Make sure ACE is valid
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   661
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   662
		if (zfs_ace_valid(obj_type, aclp, aceptr->z_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   663
		    aceptr->z_flags) != B_TRUE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   664
			return (EINVAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   665
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   666
	*size = (caddr_t)aceptr - (caddr_t)z_acl;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   667
	return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   668
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   669
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   670
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   671
 * convert old ACL format to new
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   672
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   673
void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   674
zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   675
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   676
	zfs_oldace_t *oldaclp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   677
	int i;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   678
	uint16_t type, iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   679
	uint32_t access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   680
	uint64_t who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   681
	void *cookie = NULL;
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   682
	zfs_acl_node_t *newaclnode;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   683
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   684
	ASSERT(aclp->z_version == ZFS_ACL_VERSION_INITIAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   685
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   686
	 * First create the ACE in a contiguous piece of memory
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   687
	 * for zfs_copy_ace_2_fuid().
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   688
	 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   689
	 * We only convert an ACL once, so this won't happen
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   690
	 * everytime.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   691
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   692
	oldaclp = kmem_alloc(sizeof (zfs_oldace_t) * aclp->z_acl_count,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   693
	    KM_SLEEP);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   694
	i = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   695
	while (cookie = zfs_acl_next_ace(aclp, cookie, &who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   696
	    &access_mask, &iflags, &type)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   697
		oldaclp[i].z_flags = iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   698
		oldaclp[i].z_type = type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   699
		oldaclp[i].z_fuid = who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   700
		oldaclp[i++].z_access_mask = access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   701
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   702
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   703
	newaclnode = zfs_acl_node_alloc(aclp->z_acl_count *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   704
	    sizeof (zfs_object_ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   705
	aclp->z_ops = zfs_acl_fuid_ops;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   706
	VERIFY(zfs_copy_ace_2_fuid(ZTOV(zp)->v_type, aclp, oldaclp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   707
	    newaclnode->z_acldata, aclp->z_acl_count,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   708
	    &newaclnode->z_size) == 0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   709
	newaclnode->z_ace_count = aclp->z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   710
	aclp->z_version = ZFS_ACL_VERSION;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   711
	kmem_free(oldaclp, aclp->z_acl_count * sizeof (zfs_oldace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   712
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   713
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   714
	 * Release all previous ACL nodes
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   715
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   716
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   717
	zfs_acl_release_nodes(aclp);
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   718
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   719
	list_insert_head(&aclp->z_acl, newaclnode);
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   720
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   721
	aclp->z_acl_bytes = newaclnode->z_size;
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   722
	aclp->z_acl_count = newaclnode->z_ace_count;
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   723
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
 * Convert unix access mask to v4 access mask
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
static uint32_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
zfs_unix_to_v4(uint32_t access_mask)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
	uint32_t new_mask = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   734
	if (access_mask & S_IXOTH)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   735
		new_mask |= ACE_EXECUTE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   736
	if (access_mask & S_IWOTH)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   737
		new_mask |= ACE_WRITE_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   738
	if (access_mask & S_IROTH)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
		new_mask |= ACE_READ_DATA;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   740
	return (new_mask);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   741
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   743
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   744
zfs_set_ace(zfs_acl_t *aclp, void *acep, uint32_t access_mask,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   745
    uint16_t access_type, uint64_t fuid, uint16_t entry_type)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   746
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   747
	uint16_t type = entry_type & ACE_TYPE_FLAGS;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   748
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   749
	aclp->z_ops.ace_mask_set(acep, access_mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   750
	aclp->z_ops.ace_type_set(acep, access_type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   751
	aclp->z_ops.ace_flags_set(acep, entry_type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   752
	if ((type != ACE_OWNER && type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   753
	    type != ACE_EVERYONE))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   754
		aclp->z_ops.ace_who_set(acep, fuid);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   755
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   757
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   758
 * Determine mode of file based on ACL.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   759
 * Also, create FUIDs for any User/Group ACEs
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   760
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
static uint64_t
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   762
zfs_mode_fuid_compute(znode_t *zp, zfs_acl_t *aclp, cred_t *cr,
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   763
    zfs_fuid_info_t **fuidp, dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   765
	int		entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   766
	mode_t		mode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   767
	mode_t		seen = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   768
	zfs_ace_hdr_t 	*acep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   769
	uint64_t	who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   770
	uint16_t	iflags, type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   771
	uint32_t	access_mask;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   772
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   773
	mode = (zp->z_phys->zp_mode & (S_IFMT | S_ISUID | S_ISGID | S_ISVTX));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   774
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   775
	while (acep = zfs_acl_next_ace(aclp, acep, &who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   776
	    &access_mask, &iflags, &type)) {
4869
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   777
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   778
		/*
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   779
		 * Skip over inherit only ACEs
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   780
		 */
5762
a454af064490 6646907 mismerge in zfs_mode_fuid_compute()
marks
parents: 5489
diff changeset
   781
		if (iflags & ACE_INHERIT_ONLY_ACE)
4869
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   782
			continue;
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   783
5762
a454af064490 6646907 mismerge in zfs_mode_fuid_compute()
marks
parents: 5489
diff changeset
   784
		entry_type = (iflags & ACE_TYPE_FLAGS);
a454af064490 6646907 mismerge in zfs_mode_fuid_compute()
marks
parents: 5489
diff changeset
   785
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
		if (entry_type == ACE_OWNER) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   787
			if ((access_mask & ACE_READ_DATA) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
			    (!(seen & S_IRUSR))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
				seen |= S_IRUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   790
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
					mode |= S_IRUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   794
			if ((access_mask & ACE_WRITE_DATA) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
			    (!(seen & S_IWUSR))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   796
				seen |= S_IWUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   797
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
					mode |= S_IWUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   801
			if ((access_mask & ACE_EXECUTE) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
			    (!(seen & S_IXUSR))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   803
				seen |= S_IXUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   804
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
					mode |= S_IXUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   806
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
		} else if (entry_type == OWNING_GROUP) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   809
			if ((access_mask & ACE_READ_DATA) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
			    (!(seen & S_IRGRP))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
				seen |= S_IRGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   812
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
					mode |= S_IRGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   816
			if ((access_mask & ACE_WRITE_DATA) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
			    (!(seen & S_IWGRP))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
				seen |= S_IWGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   819
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
					mode |= S_IWGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   821
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   823
			if ((access_mask & ACE_EXECUTE) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
			    (!(seen & S_IXGRP))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
				seen |= S_IXGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   826
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
					mode |= S_IXGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
		} else if (entry_type == ACE_EVERYONE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   831
			if ((access_mask & ACE_READ_DATA)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
				if (!(seen & S_IRUSR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
					seen |= S_IRUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   834
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
						mode |= S_IRUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
				if (!(seen & S_IRGRP)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
					seen |= S_IRGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   840
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
						mode |= S_IRGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
				if (!(seen & S_IROTH)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
					seen |= S_IROTH;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   846
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
						mode |= S_IROTH;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   851
			if ((access_mask & ACE_WRITE_DATA)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
				if (!(seen & S_IWUSR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
					seen |= S_IWUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   854
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
						mode |= S_IWUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
				if (!(seen & S_IWGRP)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
					seen |= S_IWGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   860
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
						mode |= S_IWGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
				if (!(seen & S_IWOTH)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
					seen |= S_IWOTH;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   866
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
						mode |= S_IWOTH;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   871
			if ((access_mask & ACE_EXECUTE)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
				if (!(seen & S_IXUSR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   873
					seen |= S_IXUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   874
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
						mode |= S_IXUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
				if (!(seen & S_IXGRP)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
					seen |= S_IXGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   880
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
						mode |= S_IXGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
				if (!(seen & S_IXOTH)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
					seen |= S_IXOTH;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   886
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   887
						mode |= S_IXOTH;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   892
		/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   893
		 * Now handle FUID create for user/group ACEs
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   894
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   895
		if (entry_type == 0 || entry_type == ACE_IDENTIFIER_GROUP) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   896
			aclp->z_ops.ace_who_set(acep,
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   897
			    zfs_fuid_create(zp->z_zfsvfs, who, cr,
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   898
			    (entry_type == 0) ? ZFS_ACE_USER : ZFS_ACE_GROUP,
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
   899
			    tx, fuidp));
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   900
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   901
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
	return (mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
static zfs_acl_t *
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   906
zfs_acl_node_read_internal(znode_t *zp, boolean_t will_modify)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   907
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   908
	zfs_acl_t	*aclp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   909
	zfs_acl_node_t	*aclnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   911
	aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_version);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   912
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   913
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   914
	 * Version 0 to 1 znode_acl_phys has the size/count fields swapped.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   915
	 * Version 0 didn't have a size field, only a count.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   916
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   917
	if (zp->z_phys->zp_acl.z_acl_version == ZFS_ACL_VERSION_INITIAL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   918
		aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   919
		aclp->z_acl_bytes = ZFS_ACL_SIZE(aclp->z_acl_count);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   920
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   921
		aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   922
		aclp->z_acl_bytes = zp->z_phys->zp_acl.z_acl_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   923
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   924
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   925
	aclnode = zfs_acl_node_alloc(will_modify ? aclp->z_acl_bytes : 0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   926
	aclnode->z_ace_count = aclp->z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   927
	if (will_modify) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   928
		bcopy(zp->z_phys->zp_acl.z_ace_data, aclnode->z_acldata,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   929
		    aclp->z_acl_bytes);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   930
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   931
		aclnode->z_size = aclp->z_acl_bytes;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   932
		aclnode->z_acldata = &zp->z_phys->zp_acl.z_ace_data[0];
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   933
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   934
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   935
	list_insert_head(&aclp->z_acl, aclnode);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
	return (aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
 * Read an external acl object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   943
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   944
zfs_acl_node_read(znode_t *zp, zfs_acl_t **aclpp, boolean_t will_modify)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   945
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   946
	uint64_t extacl = zp->z_phys->zp_acl.z_acl_extern_obj;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   947
	zfs_acl_t	*aclp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   948
	size_t		aclsize;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   949
	size_t		acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   950
	zfs_acl_node_t	*aclnode;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   951
	int error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   952
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   953
	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   954
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   955
	if (zp->z_phys->zp_acl.z_acl_extern_obj == 0) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   956
		*aclpp = zfs_acl_node_read_internal(zp, will_modify);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   957
		return (0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   958
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   959
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   960
	aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_version);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   961
	if (zp->z_phys->zp_acl.z_acl_version == ZFS_ACL_VERSION_INITIAL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   962
		zfs_acl_phys_v0_t *zacl0 =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   963
		    (zfs_acl_phys_v0_t *)&zp->z_phys->zp_acl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   964
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   965
		aclsize = ZFS_ACL_SIZE(zacl0->z_acl_count);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   966
		acl_count = zacl0->z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   967
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   968
		aclsize = zp->z_phys->zp_acl.z_acl_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   969
		acl_count = zp->z_phys->zp_acl.z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   970
		if (aclsize == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   971
			aclsize = acl_count * sizeof (zfs_ace_t);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   972
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   973
	aclnode = zfs_acl_node_alloc(aclsize);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   974
	list_insert_head(&aclp->z_acl, aclnode);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   975
	error = dmu_read(zp->z_zfsvfs->z_os, extacl, 0,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   976
	    aclsize, aclnode->z_acldata);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   977
	aclnode->z_ace_count = acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   978
	aclp->z_acl_count = acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   979
	aclp->z_acl_bytes = aclsize;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   980
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   981
	if (error != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   982
		zfs_acl_free(aclp);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   983
		return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   984
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   985
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   986
	*aclpp = aclp;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   987
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   988
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   989
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   991
 * common code for setting ACLs.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   993
 * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
 * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
 * already checked the acl and knows whether to inherit.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
int
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   998
zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr,
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   999
    zfs_fuid_info_t **fuidp, dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1000
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1001
	int		error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
	znode_phys_t	*zphys = zp->z_phys;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1003
	zfs_acl_phys_t	*zacl = &zphys->zp_acl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1005
	uint64_t	aoid = zphys->zp_acl.z_acl_extern_obj;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1006
	uint64_t	off = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1007
	dmu_object_type_t otype;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1008
	zfs_acl_node_t	*aclnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1009
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1010
	ASSERT(MUTEX_HELD(&zp->z_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1013
	dmu_buf_will_dirty(zp->z_dbuf, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1015
	zphys->zp_mode = zfs_mode_fuid_compute(zp, aclp, cr, fuidp, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
	/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1018
	 * Decide which opbject type to use.  If we are forced to
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1019
	 * use old ACL format than transform ACL into zfs_oldace_t
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1020
	 * layout.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1022
	if (!zfsvfs->z_use_fuids) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1023
		otype = DMU_OT_OLDACL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1024
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1025
		if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1026
		    (zfsvfs->z_version >= ZPL_VERSION_FUID))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1027
			zfs_acl_xform(zp, aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1028
		ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1029
		otype = DMU_OT_ACL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1030
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1031
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1032
	if (aclp->z_acl_bytes > ZFS_ACE_SPACE) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1033
		/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1034
		 * If ACL was previously external and we are now
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1035
		 * converting to new ACL format then release old
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1036
		 * ACL object and create a new one.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1037
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1038
		if (aoid && aclp->z_version != zacl->z_acl_version) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1039
			error = dmu_object_free(zfsvfs->z_os,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1040
			    zp->z_phys->zp_acl.z_acl_extern_obj, tx);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1041
			if (error)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1042
				return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1043
			aoid = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1044
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1045
		if (aoid == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1046
			aoid = dmu_object_alloc(zfsvfs->z_os,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1047
			    otype, aclp->z_acl_bytes,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1048
			    otype == DMU_OT_ACL ? DMU_OT_SYSACL : DMU_OT_NONE,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1049
			    otype == DMU_OT_ACL ? DN_MAX_BONUSLEN : 0, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1050
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
			(void) dmu_object_set_blocksize(zfsvfs->z_os, aoid,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1052
			    aclp->z_acl_bytes, 0, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1053
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1054
		zphys->zp_acl.z_acl_extern_obj = aoid;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1055
		for (aclnode = list_head(&aclp->z_acl); aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1056
		    aclnode = list_next(&aclp->z_acl, aclnode)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1057
			if (aclnode->z_ace_count == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1058
				continue;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1059
			dmu_write(zfsvfs->z_os, aoid, off,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1060
			    aclnode->z_size, aclnode->z_acldata, tx);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1061
			off += aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1062
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1063
	} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1064
		void *start = zacl->z_ace_data;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1065
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1066
		 * Migrating back embedded?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1067
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1068
		if (zphys->zp_acl.z_acl_extern_obj) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1069
			error = dmu_object_free(zfsvfs->z_os,
4300
d74de773d6e6 6528189 cp -p invalid argument issue on Redhat linux AS 3.0 NFS client against ZFS NFS directory
marks
parents: 2676
diff changeset
  1070
			    zp->z_phys->zp_acl.z_acl_extern_obj, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1071
			if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1072
				return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1073
			zphys->zp_acl.z_acl_extern_obj = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1074
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1075
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1076
		for (aclnode = list_head(&aclp->z_acl); aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1077
		    aclnode = list_next(&aclp->z_acl, aclnode)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1078
			if (aclnode->z_ace_count == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1079
				continue;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1080
			bcopy(aclnode->z_acldata, start, aclnode->z_size);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1081
			start = (caddr_t)start + aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1082
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1083
	}
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1084
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1085
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1086
	 * If Old version then swap count/bytes to match old
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1087
	 * layout of znode_acl_phys_t.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1088
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1089
	if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1090
		zphys->zp_acl.z_acl_size = aclp->z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1091
		zphys->zp_acl.z_acl_count = aclp->z_acl_bytes;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1092
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1093
		zphys->zp_acl.z_acl_size = aclp->z_acl_bytes;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1094
		zphys->zp_acl.z_acl_count = aclp->z_acl_count;
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1095
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1096
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1097
	zphys->zp_acl.z_acl_version = aclp->z_version;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1098
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1099
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1100
	 * Replace ACL wide bits, but first clear them.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1101
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1102
	zp->z_phys->zp_flags &= ~ZFS_ACL_WIDE_FLAGS;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1103
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1104
	zp->z_phys->zp_flags |= aclp->z_hints;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1105
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1106
	if (ace_trivial_common(aclp, 0, zfs_ace_walk) == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1107
		zp->z_phys->zp_flags |= ZFS_ACL_TRIVIAL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1108
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
	zfs_time_stamper_locked(zp, STATE_CHANGED, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1110
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1112
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
 * Update access mask for prepended ACE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
 * This applies the "groupmask" value for aclmode property.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1118
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1119
zfs_acl_prepend_fixup(zfs_acl_t *aclp, void  *acep, void  *origacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1120
    mode_t mode, uint64_t owner)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1121
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1122
	int	rmask, wmask, xmask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
	int	user_ace;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1124
	uint16_t aceflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1125
	uint32_t origmask, acepmask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1126
	uint64_t fuid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1128
	aceflags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1129
	fuid = aclp->z_ops.ace_who_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1130
	origmask = aclp->z_ops.ace_mask_get(origacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1131
	acepmask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1132
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1133
	user_ace = (!(aceflags &
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1134
	    (ACE_OWNER|ACE_GROUP|ACE_IDENTIFIER_GROUP)));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1136
	if (user_ace && (fuid == owner)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
		rmask = S_IRUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1138
		wmask = S_IWUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1139
		xmask = S_IXUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1141
		rmask = S_IRGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
		wmask = S_IWGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
		xmask = S_IXGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1144
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1146
	if (origmask & ACE_READ_DATA) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1147
		if (mode & rmask) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1148
			acepmask &= ~ACE_READ_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1149
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1150
			acepmask |= ACE_READ_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1151
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1153
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1154
	if (origmask & ACE_WRITE_DATA) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1155
		if (mode & wmask) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1156
			acepmask &= ~ACE_WRITE_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1157
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1158
			acepmask |= ACE_WRITE_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1159
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1162
	if (origmask & ACE_APPEND_DATA) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1163
		if (mode & wmask) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1164
			acepmask &= ~ACE_APPEND_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1165
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1166
			acepmask |= ACE_APPEND_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1167
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1168
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1169
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1170
	if (origmask & ACE_EXECUTE) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1171
		if (mode & xmask) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1172
			acepmask &= ~ACE_EXECUTE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1173
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1174
			acepmask |= ACE_EXECUTE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1175
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1176
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1177
	aclp->z_ops.ace_mask_set(acep, acepmask);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1178
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1179
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1180
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
 * Apply mode to canonical six ACEs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1182
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
zfs_acl_fixup_canonical_six(zfs_acl_t *aclp, mode_t mode)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1186
	zfs_acl_node_t *aclnode = list_tail(&aclp->z_acl);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1187
	void	*acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1188
	int	maskoff = aclp->z_ops.ace_mask_off();
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1189
	size_t abstract_size = aclp->z_ops.ace_abstract_size();
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1190
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1191
	ASSERT(aclnode != NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1192
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1193
	acep = (void *)((caddr_t)aclnode->z_acldata +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1194
	    aclnode->z_size - (abstract_size * 6));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1195
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1196
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
	 * Fixup final ACEs to match the mode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1200
	adjust_ace_pair_common(acep, maskoff, abstract_size,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1201
	    (mode & 0700) >> 6);	/* owner@ */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1202
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1203
	acep = (caddr_t)acep + (abstract_size * 2);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1204
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1205
	adjust_ace_pair_common(acep, maskoff, abstract_size,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1206
	    (mode & 0070) >> 3);	/* group@ */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1207
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1208
	acep = (caddr_t)acep + (abstract_size * 2);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1209
	adjust_ace_pair_common(acep, maskoff,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1210
	    abstract_size, mode);	/* everyone@ */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1211
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1213
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1214
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1215
zfs_acl_ace_match(zfs_acl_t *aclp, void *acep, int allow_deny,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1216
    int entry_type, int accessmask)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1217
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1218
	uint32_t mask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1219
	uint16_t type = aclp->z_ops.ace_type_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1220
	uint16_t flags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1221
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1222
	return (mask == accessmask && type == allow_deny &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1223
	    ((flags & ACE_TYPE_FLAGS) == entry_type));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1224
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1225
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1226
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1227
 * Can prepended ACE be reused?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1228
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1229
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1230
zfs_reuse_deny(zfs_acl_t *aclp, void *acep, void *prevacep)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1231
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1232
	int okay_masks;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1233
	uint16_t prevtype;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1234
	uint16_t prevflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1235
	uint16_t flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1236
	uint32_t mask, prevmask;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1237
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1238
	if (prevacep == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1239
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1240
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1241
	prevtype = aclp->z_ops.ace_type_get(prevacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1242
	prevflags = aclp->z_ops.ace_flags_get(prevacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1243
	flags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1244
	mask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1245
	prevmask = aclp->z_ops.ace_mask_get(prevacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1246
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1247
	if (prevtype != DENY)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1248
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1249
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1250
	if (prevflags != (flags & ACE_IDENTIFIER_GROUP))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1251
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1252
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1253
	okay_masks = (mask & OKAY_MASK_BITS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1254
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1255
	if (prevmask & ~okay_masks)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1256
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
	return (B_TRUE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1262
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1263
 * Insert new ACL node into chain of zfs_acl_node_t's
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1264
 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1265
 * This will result in two possible results.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1266
 * 1. If the ACL is currently just a single zfs_acl_node and
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1267
 *    we are prepending the entry then current acl node will have
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1268
 *    a new node inserted above it.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1269
 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1270
 * 2. If we are inserting in the middle of current acl node then
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1271
 *    the current node will be split in two and new node will be inserted
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1272
 *    in between the two split nodes.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1273
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1274
static zfs_acl_node_t *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1275
zfs_acl_ace_insert(zfs_acl_t *aclp, void  *acep)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1276
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1277
	zfs_acl_node_t 	*newnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1278
	zfs_acl_node_t 	*trailernode = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1279
	zfs_acl_node_t 	*currnode = zfs_acl_curr_node(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1280
	int		curr_idx = aclp->z_curr_node->z_ace_idx;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1281
	int		trailer_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1282
	size_t		oldsize;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1283
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1284
	newnode = zfs_acl_node_alloc(aclp->z_ops.ace_size(acep));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1285
	newnode->z_ace_count = 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1286
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1287
	oldsize = currnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1288
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1289
	if (curr_idx != 1) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1290
		trailernode = zfs_acl_node_alloc(0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1291
		trailernode->z_acldata = acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1292
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1293
		trailer_count = currnode->z_ace_count - curr_idx + 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1294
		currnode->z_ace_count = curr_idx - 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1295
		currnode->z_size = (caddr_t)acep - (caddr_t)currnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1296
		trailernode->z_size = oldsize - currnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1297
		trailernode->z_ace_count = trailer_count;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1298
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1299
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1300
	aclp->z_acl_count += 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1301
	aclp->z_acl_bytes += aclp->z_ops.ace_size(acep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1302
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1303
	if (curr_idx == 1)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1304
		list_insert_before(&aclp->z_acl, currnode, newnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1305
	else
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1306
		list_insert_after(&aclp->z_acl, currnode, newnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1307
	if (trailernode) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1308
		list_insert_after(&aclp->z_acl, newnode, trailernode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1309
		aclp->z_curr_node = trailernode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1310
		trailernode->z_ace_idx = 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1311
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1312
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1313
	return (newnode);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1314
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1315
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1316
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1317
 * Prepend deny ACE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1318
 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1319
static void *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1320
zfs_acl_prepend_deny(znode_t *zp, zfs_acl_t *aclp, void *acep,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1321
    mode_t mode)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1322
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1323
	zfs_acl_node_t *aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1324
	void  *newacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1325
	uint64_t fuid;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1326
	uint16_t flags;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1327
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1328
	aclnode = zfs_acl_ace_insert(aclp, acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1329
	newacep = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1330
	fuid = aclp->z_ops.ace_who_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1331
	flags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1332
	zfs_set_ace(aclp, newacep, 0, DENY, fuid, (flags & ACE_TYPE_FLAGS));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1333
	zfs_acl_prepend_fixup(aclp, newacep, acep, mode, zp->z_phys->zp_uid);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1334
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1335
	return (newacep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1336
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1337
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1338
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1339
 * Split an inherited ACE into inherit_only ACE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1340
 * and original ACE with inheritance flags stripped off.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1341
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1342
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1343
zfs_acl_split_ace(zfs_acl_t *aclp, zfs_ace_hdr_t *acep)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1344
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1345
	zfs_acl_node_t *aclnode;
5435
1be0be66916d 6624956 zfs_log_fuid_ids can cause panic on sparc
marks
parents: 5331
diff changeset
  1346
	zfs_acl_node_t *currnode;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1347
	void  *newacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1348
	uint16_t type, flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1349
	uint32_t mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1350
	uint64_t fuid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1351
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1352
	type = aclp->z_ops.ace_type_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1353
	flags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1354
	mask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1355
	fuid = aclp->z_ops.ace_who_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1356
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1357
	aclnode = zfs_acl_ace_insert(aclp, acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1358
	newacep = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1359
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1360
	aclp->z_ops.ace_type_set(newacep, type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1361
	aclp->z_ops.ace_flags_set(newacep, flags | ACE_INHERIT_ONLY_ACE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1362
	aclp->z_ops.ace_mask_set(newacep, mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1363
	aclp->z_ops.ace_type_set(newacep, type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1364
	aclp->z_ops.ace_who_set(newacep, fuid);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1365
	aclp->z_next_ace = acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1366
	flags &= ~ALL_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1367
	aclp->z_ops.ace_flags_set(acep, flags);
5435
1be0be66916d 6624956 zfs_log_fuid_ids can cause panic on sparc
marks
parents: 5331
diff changeset
  1368
	currnode = zfs_acl_curr_node(aclp);
1be0be66916d 6624956 zfs_log_fuid_ids can cause panic on sparc
marks
parents: 5331
diff changeset
  1369
	ASSERT(currnode->z_ace_idx >= 1);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1370
	currnode->z_ace_idx -= 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1371
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1372
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1373
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1374
 * Are ACES started at index i, the canonical six ACES?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1375
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1376
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1377
zfs_have_canonical_six(zfs_acl_t *aclp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1378
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1379
	void *acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1380
	zfs_acl_node_t *aclnode = list_tail(&aclp->z_acl);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1381
	int		i = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1382
	size_t abstract_size = aclp->z_ops.ace_abstract_size();
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1383
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1384
	ASSERT(aclnode != NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1385
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1386
	if (aclnode->z_ace_count < 6)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1387
		return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1388
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1389
	acep = (void *)((caddr_t)aclnode->z_acldata +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1390
	    aclnode->z_size - (aclp->z_ops.ace_abstract_size() * 6));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1391
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1392
	if ((zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1393
	    DENY, ACE_OWNER, 0) &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1394
	    zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1395
	    ALLOW, ACE_OWNER, OWNER_ALLOW_MASK) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1396
	    zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++), DENY,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1397
	    OWNING_GROUP, 0) && zfs_acl_ace_match(aclp, (caddr_t)acep +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1398
	    (abstract_size * i++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1399
	    ALLOW, OWNING_GROUP, 0) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1400
	    zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1401
	    DENY, ACE_EVERYONE, EVERYONE_DENY_MASK) &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1402
	    zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1403
	    ALLOW, ACE_EVERYONE, EVERYONE_ALLOW_MASK))) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1404
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1405
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1406
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1407
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1408
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1409
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1410
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1411
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1412
 * Apply step 1g, to group entries
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1413
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1414
 * Need to deal with corner case where group may have
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1415
 * greater permissions than owner.  If so then limit
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1416
 * group permissions, based on what extra permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1417
 * group has.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1418
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1419
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1420
zfs_fixup_group_entries(zfs_acl_t *aclp, void *acep, void *prevacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1421
    mode_t mode)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1422
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1423
	uint32_t prevmask = aclp->z_ops.ace_mask_get(prevacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1424
	uint32_t mask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1425
	uint16_t prevflags = aclp->z_ops.ace_flags_get(prevacep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1426
	mode_t extramode = (mode >> 3) & 07;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1427
	mode_t ownermode = (mode >> 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1428
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1429
	if (prevflags & ACE_IDENTIFIER_GROUP) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1430
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1431
		extramode &= ~ownermode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1432
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1433
		if (extramode) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1434
			if (extramode & S_IROTH) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1435
				prevmask &= ~ACE_READ_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1436
				mask &= ~ACE_READ_DATA;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1437
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1438
			if (extramode & S_IWOTH) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1439
				prevmask &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1440
				mask &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1441
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1442
			if (extramode & S_IXOTH) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1443
				prevmask  &= ~ACE_EXECUTE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1444
				mask &= ~ACE_EXECUTE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1445
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1446
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1447
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1448
	aclp->z_ops.ace_mask_set(acep, mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1449
	aclp->z_ops.ace_mask_set(prevacep, prevmask);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1450
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1451
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1452
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1453
 * Apply the chmod algorithm as described
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1454
 * in PSARC/2002/240
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
 */
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1456
static void
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1457
zfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1458
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1459
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1460
	void		*acep = NULL, *prevacep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1461
	uint64_t	who;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1462
	int 		i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1463
	int 		entry_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1464
	int 		reuse_deny;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1465
	int 		need_canonical_six = 1;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1466
	uint16_t	iflags, type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1467
	uint32_t	access_mask;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1468
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1469
	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1470
	ASSERT(MUTEX_HELD(&zp->z_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1471
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1472
	aclp->z_hints = (zp->z_phys->zp_flags & V4_ACL_WIDE_FLAGS);
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1473
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1474
	/*
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1475
	 * If discard then just discard all ACL nodes which
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1476
	 * represent the ACEs.
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1477
	 *
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1478
	 * New owner@/group@/everone@ ACEs will be added
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1479
	 * later.
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1480
	 */
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1481
	if (zfsvfs->z_acl_mode == ZFS_ACL_DISCARD)
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1482
		zfs_acl_release_nodes(aclp);
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1483
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1484
	while (acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1485
	    &iflags, &type)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1486
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1487
		entry_type = (iflags & ACE_TYPE_FLAGS);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1488
		iflags = (iflags & ALL_INHERIT);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1489
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1490
		if ((type != ALLOW && type != DENY) ||
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1491
		    (iflags & ACE_INHERIT_ONLY_ACE)) {
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1492
			if (iflags)
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1493
				aclp->z_hints |= ZFS_INHERIT_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1494
			switch (type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1495
			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1496
			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1497
			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1498
			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1499
				aclp->z_hints |= ZFS_ACL_OBJ_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1500
				break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1501
			}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1502
			goto nextace;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1503
		}
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
		 * Need to split ace into two?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1507
		 */
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1508
		if ((iflags & (ACE_FILE_INHERIT_ACE|
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1509
		    ACE_DIRECTORY_INHERIT_ACE)) &&
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1510
		    (!(iflags & ACE_INHERIT_ONLY_ACE))) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1511
			zfs_acl_split_ace(aclp, acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1512
			aclp->z_hints |= ZFS_INHERIT_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1513
			goto nextace;
789
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
		if (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1517
		    (entry_type == OWNING_GROUP)) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1518
			access_mask &= ~OGE_CLEAR;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1519
			aclp->z_ops.ace_mask_set(acep, access_mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1520
			goto nextace;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1521
		} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1522
			reuse_deny = B_TRUE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1523
			if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1524
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1525
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1526
				 * Check preceding ACE if any, to see
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1527
				 * if we need to prepend a DENY ACE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1528
				 * This is only applicable when the acl_mode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1529
				 * property == groupmask.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1530
				 */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
  1531
				if (zfsvfs->z_acl_mode == ZFS_ACL_GROUPMASK) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1532
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1533
					reuse_deny = zfs_reuse_deny(aclp, acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1534
					    prevacep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1535
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1536
					if (!reuse_deny) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1537
						prevacep =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1538
						    zfs_acl_prepend_deny(zp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1539
						    aclp, acep, mode);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1540
					} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1541
						zfs_acl_prepend_fixup(
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1542
						    aclp, prevacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1543
						    acep, mode,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1544
						    zp->z_phys->zp_uid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1545
					}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1546
					zfs_fixup_group_entries(aclp, acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1547
					    prevacep, mode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1548
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1549
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1550
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1551
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1552
nextace:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1553
		prevacep = acep;
789
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
	 * Check out last six aces, if we have six.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1558
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1559
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1560
	if (aclp->z_acl_count >= 6) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1561
		if (zfs_have_canonical_six(aclp)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1562
			need_canonical_six = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1563
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1564
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1565
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1566
	if (need_canonical_six) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1567
		size_t abstract_size = aclp->z_ops.ace_abstract_size();
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1568
		void *zacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1569
		zfs_acl_node_t *aclnode =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1570
		    zfs_acl_node_alloc(abstract_size * 6);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1571
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1572
		aclnode->z_size = abstract_size * 6;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1573
		aclnode->z_ace_count = 6;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1574
		aclp->z_acl_bytes += aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1575
		list_insert_tail(&aclp->z_acl, aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1576
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1577
		zacep = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1578
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1579
		i = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1580
		zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1581
		    0, DENY, -1, ACE_OWNER);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1582
		zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1583
		    OWNER_ALLOW_MASK, ALLOW, -1, ACE_OWNER);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1584
		zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++), 0,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1585
		    DENY, -1, OWNING_GROUP);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1586
		zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++), 0,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1587
		    ALLOW, -1, OWNING_GROUP);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1588
		zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1589
		    EVERYONE_DENY_MASK, DENY, -1, ACE_EVERYONE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1590
		zfs_set_ace(aclp, (caddr_t)zacep + (abstract_size * i++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1591
		    EVERYONE_ALLOW_MASK, ALLOW, -1, ACE_EVERYONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1592
		aclp->z_acl_count += 6;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1593
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1594
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1595
	zfs_acl_fixup_canonical_six(aclp, mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1596
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1597
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1598
int
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1599
zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1600
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1601
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1602
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1603
	mutex_enter(&zp->z_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1604
	mutex_enter(&zp->z_acl_lock);
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1605
	*aclp = NULL;
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1606
	error = zfs_acl_node_read(zp, aclp, B_TRUE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1607
	if (error == 0)
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1608
		zfs_acl_chmod(zp, mode, *aclp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1609
	mutex_exit(&zp->z_acl_lock);
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1610
	mutex_exit(&zp->z_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1611
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1612
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1613
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1614
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1615
 * strip off write_owner and write_acl
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1616
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1617
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1618
zfs_securemode_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1619
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1620
	uint32_t mask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1621
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
  1622
	if ((zfsvfs->z_acl_inherit == ZFS_ACL_SECURE) &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1623
	    (aclp->z_ops.ace_type_get(acep) == ALLOW)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1624
		mask &= ~SECURE_CLEAR;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1625
		aclp->z_ops.ace_mask_set(acep, mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1626
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1627
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1628
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1629
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1630
 * Should ACE be inherited?
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1631
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1632
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1633
zfs_ace_can_use(znode_t *zp, uint16_t acep_flags)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1634
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1635
	int vtype = ZTOV(zp)->v_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1636
	int	iflags = (acep_flags & 0xf);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1637
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1638
	if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1639
		return (1);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1640
	else if (iflags & ACE_FILE_INHERIT_ACE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1641
		return (!((vtype == VDIR) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1642
		    (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1643
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1644
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1645
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1646
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1647
 * inherit inheritable ACEs from parent
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1648
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1649
static zfs_acl_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1650
zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1651
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1652
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1653
	void		*pacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1654
	void		*acep, *acep2;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1655
	zfs_acl_node_t  *aclnode, *aclnode2;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1656
	zfs_acl_t	*aclp = NULL;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1657
	uint64_t	who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1658
	uint32_t	access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1659
	uint16_t	iflags, newflags, type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1660
	size_t		ace_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1661
	void		*data1, *data2;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1662
	size_t		data1sz, data2sz;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1663
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1664
	pacep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1665
	aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
  1666
	if (zfsvfs->z_acl_inherit != ZFS_ACL_DISCARD) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1667
		while (pacep = zfs_acl_next_ace(paclp, pacep, &who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1668
		    &access_mask, &iflags, &type)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1669
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
  1670
			if (zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1671
			    type == ALLOW)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1672
				continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1673
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1674
			ace_size = aclp->z_ops.ace_size(pacep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1675
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1676
			if (zfs_ace_can_use(zp, iflags)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1677
				aclnode =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1678
				    zfs_acl_node_alloc(ace_size);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1679
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1680
				list_insert_tail(&aclp->z_acl, aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1681
				acep = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1682
				zfs_set_ace(aclp, acep, access_mask, type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1683
				    who, iflags|ACE_INHERITED_ACE);
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  1684
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1685
				/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1686
				 * Copy special opaque data if any
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1687
				 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1688
				if ((data1sz = paclp->z_ops.ace_data(pacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1689
				    &data1)) != 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1690
					VERIFY((data2sz =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1691
					    aclp->z_ops.ace_data(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1692
					    &data2)) == data1sz);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1693
					bcopy(data1, data2, data2sz);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1694
				}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1695
				aclp->z_acl_count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1696
				aclnode->z_ace_count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1697
				aclp->z_acl_bytes += aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1698
				newflags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1699
				if ((iflags &
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  1700
				    ACE_NO_PROPAGATE_INHERIT_ACE) ||
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  1701
				    (ZTOV(zp)->v_type != VDIR)) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1702
					newflags &= ~ALL_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1703
					aclp->z_ops.ace_flags_set(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1704
					    newflags|ACE_INHERITED_ACE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1705
					zfs_securemode_update(zfsvfs,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1706
					    aclp, acep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1707
					continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1708
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1709
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1710
				ASSERT(ZTOV(zp)->v_type == VDIR);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1711
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1712
				newflags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1713
				if ((iflags & (ACE_FILE_INHERIT_ACE |
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  1714
				    ACE_DIRECTORY_INHERIT_ACE)) !=
865
4223fbdac5f3 6344681 chmod file_inherit should not added the specified ACE to new create subdirectores.
marks
parents: 789
diff changeset
  1715
				    ACE_FILE_INHERIT_ACE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1716
					aclnode2 = zfs_acl_node_alloc(ace_size);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1717
					list_insert_tail(&aclp->z_acl,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1718
					    aclnode2);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1719
					acep2 = aclnode2->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1720
					zfs_set_ace(aclp, acep2,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1721
					    access_mask, type, who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1722
					    iflags|ACE_INHERITED_ACE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1723
					newflags |= ACE_INHERIT_ONLY_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1724
					aclp->z_ops.ace_flags_set(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1725
					    newflags);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1726
					newflags &= ~ALL_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1727
					aclp->z_ops.ace_flags_set(acep2,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1728
					    newflags|ACE_INHERITED_ACE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1729
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1730
					/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1731
					 * Copy special opaque data if any
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1732
					 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1733
					if ((data1sz =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1734
					    aclp->z_ops.ace_data(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1735
					    &data1)) != 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1736
						VERIFY((data2sz =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1737
						    aclp->z_ops.ace_data(acep2,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1738
						    &data2)) == data1sz);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1739
						bcopy(data1, data2, data1sz);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1740
					}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1741
					aclp->z_acl_count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1742
					aclnode2->z_ace_count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1743
					aclp->z_acl_bytes += aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1744
					zfs_securemode_update(zfsvfs,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1745
					    aclp, acep2);
865
4223fbdac5f3 6344681 chmod file_inherit should not added the specified ACE to new create subdirectores.
marks
parents: 789
diff changeset
  1746
				} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1747
					newflags |= ACE_INHERIT_ONLY_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1748
					aclp->z_ops.ace_flags_set(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1749
					    newflags|ACE_INHERITED_ACE);
865
4223fbdac5f3 6344681 chmod file_inherit should not added the specified ACE to new create subdirectores.
marks
parents: 789
diff changeset
  1750
				}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1751
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1752
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1753
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1754
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1755
	return (aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1756
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1757
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1758
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1759
 * Create file system object initial permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1760
 * including inheritable ACEs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1761
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1762
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1763
zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1764
    vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1765
    zfs_acl_t *setaclp, zfs_fuid_info_t **fuidp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1766
{
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1767
	uint64_t	mode, fuid, fgid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1768
	int		error;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1769
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1770
	zfs_acl_t	*aclp = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1771
	zfs_acl_t	*paclp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1772
	xvattr_t	*xvap = (xvattr_t *)vap;
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1773
	gid_t		gid;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1774
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1775
	if (setaclp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1776
		aclp = setaclp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1777
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1778
	mode = MAKEIMODE(vap->va_type, vap->va_mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1779
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1780
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1781
	 * Determine uid and gid.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1782
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1783
	if ((flag & (IS_ROOT_NODE | IS_REPLAY)) ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1784
	    ((flag & IS_XATTR) && (vap->va_type == VDIR))) {
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1785
		fuid = zfs_fuid_create(zfsvfs, vap->va_uid, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1786
		    ZFS_OWNER, tx, fuidp);
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1787
		fgid = zfs_fuid_create(zfsvfs, vap->va_gid, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1788
		    ZFS_GROUP, tx, fuidp);
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1789
		gid = vap->va_gid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1790
	} else {
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1791
		fuid = zfs_fuid_create_cred(zfsvfs, ZFS_OWNER, tx, cr, fuidp);
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1792
		fgid = 0;
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1793
		if (vap->va_mask & AT_GID)  {
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1794
			fgid = zfs_fuid_create(zfsvfs, vap->va_gid, cr,
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1795
			    ZFS_GROUP, tx, fuidp);
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1796
			gid = vap->va_gid;
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1797
			if (fgid != parent->z_phys->zp_gid &&
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1798
			    !groupmember(vap->va_gid, cr) &&
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1799
			    secpolicy_vnode_create_gid(cr) != 0)
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1800
				fgid = 0;
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1801
		}
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1802
		if (fgid == 0) {
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1803
			if (parent->z_phys->zp_mode & S_ISGID) {
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1804
				fgid = parent->z_phys->zp_gid;
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1805
				gid = zfs_fuid_map_id(zfsvfs, fgid,
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1806
				    cr, ZFS_GROUP);
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1807
			} else {
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1808
				fgid = zfs_fuid_create_cred(zfsvfs,
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1809
				    ZFS_GROUP, tx, cr, fuidp);
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1810
				gid = crgetgid(cr);
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1811
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1812
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1813
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1814
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1815
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1816
	 * If we're creating a directory, and the parent directory has the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1817
	 * set-GID bit set, set in on the new directory.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1818
	 * Otherwise, if the user is neither privileged nor a member of the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1819
	 * file's new group, clear the file's set-GID bit.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1820
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1821
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1822
	if ((parent->z_phys->zp_mode & S_ISGID) && (vap->va_type == VDIR)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1823
		mode |= S_ISGID;
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1824
	} else {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1825
		if ((mode & S_ISGID) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1826
		    secpolicy_vnode_setids_setgids(cr, gid) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1827
			mode &= ~S_ISGID;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1828
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1829
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1830
	zp->z_phys->zp_uid = fuid;
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1831
	zp->z_phys->zp_gid = fgid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1832
	zp->z_phys->zp_mode = mode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1833
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1834
	if (aclp == NULL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1835
		mutex_enter(&parent->z_lock);
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1836
		if (parent->z_phys->zp_flags & ZFS_INHERIT_ACE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1837
			mutex_enter(&parent->z_acl_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1838
			VERIFY(0 == zfs_acl_node_read(parent, &paclp, B_FALSE));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1839
			mutex_exit(&parent->z_acl_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1840
			aclp = zfs_acl_inherit(zp, paclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1841
			zfs_acl_free(paclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1842
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1843
			aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1844
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1845
		mutex_exit(&parent->z_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1846
		mutex_enter(&zp->z_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1847
		mutex_enter(&zp->z_acl_lock);
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1848
		zfs_acl_chmod(zp, mode, aclp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1849
	} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1850
		mutex_enter(&zp->z_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1851
		mutex_enter(&zp->z_acl_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1852
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1853
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1854
	/* Force auto_inherit on all new directory objects */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1855
	if (vap->va_type == VDIR)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1856
		aclp->z_hints |= ZFS_ACL_AUTO_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1857
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1858
	error = zfs_aclset_common(zp, aclp, cr, fuidp, tx);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1859
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1860
	/* Set optional attributes if any */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1861
	if (vap->va_mask & AT_XVATTR)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1862
		zfs_xvattr_set(zp, xvap);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1863
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1864
	mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1865
	mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1866
	ASSERT3U(error, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1867
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  1868
	if (aclp != setaclp)
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1869
		zfs_acl_free(aclp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1870
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1871
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1872
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1873
 * Retrieve a files ACL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1874
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1875
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1876
zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1877
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1878
	zfs_acl_t	*aclp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1879
	ulong_t		mask;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1880
	int		error;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1881
	int 		count = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1882
	int		largeace = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1883
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1884
	mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT |
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1885
	    VSA_ACE_ACLFLAGS | VSA_ACE_ALLTYPES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1886
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1887
	if (error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1888
		return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1889
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1890
	if (mask == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1891
		return (ENOSYS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1892
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1893
	mutex_enter(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1894
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1895
	error = zfs_acl_node_read(zp, &aclp, B_FALSE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1896
	if (error != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1897
		mutex_exit(&zp->z_acl_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1898
		return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1899
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1900
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1901
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1902
	 * Scan ACL to determine number of ACEs
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1903
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1904
	if ((zp->z_phys->zp_flags & ZFS_ACL_OBJ_ACE) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1905
	    !(mask & VSA_ACE_ALLTYPES)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1906
		void *zacep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1907
		uint64_t who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1908
		uint32_t access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1909
		uint16_t type, iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1910
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1911
		while (zacep = zfs_acl_next_ace(aclp, zacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1912
		    &who, &access_mask, &iflags, &type)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1913
			switch (type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1914
			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1915
			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1916
			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1917
			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1918
				largeace++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1919
				continue;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1920
			default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1921
				count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1922
			}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1923
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1924
		vsecp->vsa_aclcnt = count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1925
	} else
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1926
		count = aclp->z_acl_count;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1927
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1928
	if (mask & VSA_ACECNT) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1929
		vsecp->vsa_aclcnt = count;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1930
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1931
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1932
	if (mask & VSA_ACE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1933
		size_t aclsz;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1934
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1935
		zfs_acl_node_t *aclnode = list_head(&aclp->z_acl);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1936
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1937
		aclsz = count * sizeof (ace_t) +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1938
		    sizeof (ace_object_t) * largeace;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1939
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1940
		vsecp->vsa_aclentp = kmem_alloc(aclsz, KM_SLEEP);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1941
		vsecp->vsa_aclentsz = aclsz;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1942
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1943
		if (aclp->z_version == ZFS_ACL_VERSION_FUID)
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1944
			zfs_copy_fuid_2_ace(zp->z_zfsvfs, aclp, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1945
			    vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1946
		else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1947
			bcopy(aclnode->z_acldata, vsecp->vsa_aclentp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1948
			    count * sizeof (ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1949
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1950
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1951
	if (mask & VSA_ACE_ACLFLAGS) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1952
		vsecp->vsa_aclflags = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1953
		if (zp->z_phys->zp_flags & ZFS_ACL_DEFAULTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1954
			vsecp->vsa_aclflags |= ACL_DEFAULTED;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1955
		if (zp->z_phys->zp_flags & ZFS_ACL_PROTECTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1956
			vsecp->vsa_aclflags |= ACL_PROTECTED;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1957
		if (zp->z_phys->zp_flags & ZFS_ACL_AUTO_INHERIT)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1958
			vsecp->vsa_aclflags |= ACL_AUTO_INHERIT;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1959
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1960
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1961
	mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1962
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1963
	zfs_acl_free(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1964
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1965
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1966
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1967
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1968
int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1969
zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1970
    vsecattr_t *vsecp, zfs_acl_t **zaclp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1971
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1972
	zfs_acl_t *aclp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1973
	zfs_acl_node_t *aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1974
	int aclcnt = vsecp->vsa_aclcnt;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1975
	int error;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1976
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1977
	if (vsecp->vsa_aclcnt > MAX_ACL_ENTRIES || vsecp->vsa_aclcnt <= 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1978
		return (EINVAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1979
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1980
	aclp = zfs_acl_alloc(zfs_acl_version(zfsvfs->z_version));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1981
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1982
	aclp->z_hints = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1983
	aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1984
	if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1985
		if ((error = zfs_copy_ace_2_oldace(obj_type, aclp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1986
		    (ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1987
		    aclcnt, &aclnode->z_size)) != 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1988
			zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1989
			zfs_acl_node_free(aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1990
			return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1991
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1992
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1993
		if ((error = zfs_copy_ace_2_fuid(obj_type, aclp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1994
		    vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1995
		    &aclnode->z_size)) != 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1996
			zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1997
			zfs_acl_node_free(aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1998
			return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1999
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2000
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2001
	aclp->z_acl_bytes = aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2002
	aclnode->z_ace_count = aclcnt;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2003
	aclp->z_acl_count = aclcnt;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2004
	list_insert_head(&aclp->z_acl, aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2005
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2006
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2007
	 * If flags are being set then add them to z_hints
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2008
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2009
	if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2010
		if (vsecp->vsa_aclflags & ACL_PROTECTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2011
			aclp->z_hints |= ZFS_ACL_PROTECTED;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2012
		if (vsecp->vsa_aclflags & ACL_DEFAULTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2013
			aclp->z_hints |= ZFS_ACL_DEFAULTED;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2014
		if (vsecp->vsa_aclflags & ACL_AUTO_INHERIT)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2015
			aclp->z_hints |= ZFS_ACL_AUTO_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2016
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2017
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2018
	*zaclp = aclp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2019
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2020
	return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2021
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2022
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2023
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2024
 * Set a files ACL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2025
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2026
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2027
zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2028
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2029
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2030
	zilog_t		*zilog = zfsvfs->z_log;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2031
	ulong_t		mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2032
	dmu_tx_t	*tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2033
	int		error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2034
	zfs_acl_t	*aclp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2035
	zfs_fuid_info_t	*fuidp = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2036
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2037
	if (mask == 0)
4300
d74de773d6e6 6528189 cp -p invalid argument issue on Redhat linux AS 3.0 NFS client against ZFS NFS directory
marks
parents: 2676
diff changeset
  2038
		return (ENOSYS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2039
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2040
	if (zp->z_phys->zp_flags & ZFS_IMMUTABLE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2041
		return (EPERM);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2042
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2043
	if (error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2044
		return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2045
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2046
	error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, &aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2047
	if (error)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2048
		return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2049
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2050
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2051
	 * If ACL wide flags aren't being set then preserve any
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2052
	 * existing flags.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2053
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2054
	if (!(vsecp->vsa_mask & VSA_ACE_ACLFLAGS)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2055
		aclp->z_hints |= (zp->z_phys->zp_flags & V4_ACL_WIDE_FLAGS);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2056
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2057
top:
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2058
	if (error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2059
		zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2060
		return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2061
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2062
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2063
	mutex_enter(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2064
	mutex_enter(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2065
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2066
	tx = dmu_tx_create(zfsvfs->z_os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2067
	dmu_tx_hold_bonus(tx, zp->z_id);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2068
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2069
	if (zp->z_phys->zp_acl.z_acl_extern_obj) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2070
		/* Are we upgrading ACL? */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2071
		if (zfsvfs->z_version <= ZPL_VERSION_FUID &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2072
		    zp->z_phys->zp_acl.z_acl_version ==
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2073
		    ZFS_ACL_VERSION_INITIAL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2074
			dmu_tx_hold_free(tx,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2075
			    zp->z_phys->zp_acl.z_acl_extern_obj,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2076
			    0, DMU_OBJECT_END);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2077
			dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2078
			    0, aclp->z_acl_bytes);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2079
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2080
			dmu_tx_hold_write(tx,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2081
			    zp->z_phys->zp_acl.z_acl_extern_obj,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2082
			    0, aclp->z_acl_bytes);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2083
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2084
	} else if (aclp->z_acl_bytes > ZFS_ACE_SPACE) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2085
		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, aclp->z_acl_bytes);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2086
	}
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2087
	if (aclp->z_has_fuids) {
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2088
		if (zfsvfs->z_fuid_obj == 0) {
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2089
			dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2090
			dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2091
			    FUID_SIZE_ESTIMATE(zfsvfs));
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2092
			dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL);
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2093
		} else {
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2094
			dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj);
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2095
			dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0,
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2096
			    FUID_SIZE_ESTIMATE(zfsvfs));
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2097
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2098
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2099
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2100
	error = dmu_tx_assign(tx, zfsvfs->z_assign);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2101
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2102
		mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2103
		mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2104
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2105
		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2058
diff changeset
  2106
			dmu_tx_wait(tx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2058
diff changeset
  2107
			dmu_tx_abort(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2108
			goto top;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2109
		}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2058
diff changeset
  2110
		dmu_tx_abort(tx);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2111
		zfs_acl_free(aclp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2112
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2113
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2114
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  2115
	error = zfs_aclset_common(zp, aclp, cr, &fuidp, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2116
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2117
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2118
	zfs_log_acl(zilog, tx, zp, vsecp, fuidp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2119
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2120
	if (fuidp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2121
		zfs_fuid_info_free(fuidp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2122
	zfs_acl_free(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2123
	dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2124
done:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2125
	mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2126
	mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2127
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2128
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2129
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2130
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2131
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2132
 * working_mode returns the permissions that were not granted
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2133
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2134
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2135
zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2136
    boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2137
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2138
	zfs_acl_t	*aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2139
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2140
	int		error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2141
	uid_t		uid = crgetuid(cr);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2142
	uint64_t 	who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2143
	uint16_t	type, iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2144
	uint16_t	entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2145
	uint32_t	access_mask;
6056
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2146
	uint32_t	deny_mask = 0;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2147
	zfs_ace_hdr_t	*acep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2148
	boolean_t	checkit;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2149
	uid_t		fowner;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2150
	uid_t		gowner;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2151
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2152
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2153
	 * Short circuit empty requests
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2154
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2155
	if (v4_mode == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2156
		return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2157
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2158
	*check_privs = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2159
2638
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2604
diff changeset
  2160
	if (zfsvfs->z_assign >= TXG_INITIAL) {		/* ZIL replay */
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2604
diff changeset
  2161
		*working_mode = 0;
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2604
diff changeset
  2162
		return (0);
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2604
diff changeset
  2163
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2164
2638
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2604
diff changeset
  2165
	*working_mode = v4_mode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2166
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2167
	if ((v4_mode & WRITE_MASK) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2168
	    (zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2169
	    (!IS_DEVVP(ZTOV(zp)))) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2170
		*check_privs = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2171
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2172
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2173
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2174
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2175
	 * Only check for READONLY on non-directories.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2176
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2177
	if ((v4_mode & WRITE_MASK_DATA) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2178
	    (((ZTOV(zp)->v_type != VDIR) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2179
	    (zp->z_phys->zp_flags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2180
	    (ZTOV(zp)->v_type == VDIR &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2181
	    (zp->z_phys->zp_flags & ZFS_IMMUTABLE)))) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2182
		*check_privs = B_FALSE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2183
		return (EPERM);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2184
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2185
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2186
	if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2187
	    (zp->z_phys->zp_flags & ZFS_NOUNLINK)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2188
		*check_privs = B_FALSE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2189
		return (EPERM);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2190
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2191
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2192
	if (((v4_mode & (ACE_READ_DATA|ACE_EXECUTE)) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2193
	    (zp->z_phys->zp_flags & ZFS_AV_QUARANTINED))) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2194
		*check_privs = B_FALSE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2195
		return (EACCES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2196
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2197
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2198
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2199
	 * The caller requested that the ACL check be skipped.  This
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2200
	 * would only happen if the caller checked VOP_ACCESS() with a
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2201
	 * 32 bit ACE mask and already had the appropriate permissions.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2202
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2203
	if (skipaclchk) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2204
		*working_mode = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2205
		return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2206
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2207
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  2208
	zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2209
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2210
	mutex_enter(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2211
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2212
	error = zfs_acl_node_read(zp, &aclp, B_FALSE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2213
	if (error != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2214
		mutex_exit(&zp->z_acl_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2215
		return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2216
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2217
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2218
	while (acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2219
	    &iflags, &type)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2220
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2221
		if (iflags & ACE_INHERIT_ONLY_ACE)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2222
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2223
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2224
		entry_type = (iflags & ACE_TYPE_FLAGS);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2225
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2226
		checkit = B_FALSE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2227
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2228
		switch (entry_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2229
		case ACE_OWNER:
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2230
			if (uid == fowner)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2231
				checkit = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2232
			break;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2233
		case OWNING_GROUP:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2234
			who = gowner;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2235
			/*FALLTHROUGH*/
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2236
		case ACE_IDENTIFIER_GROUP:
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2237
			checkit = zfs_groupmember(zfsvfs, who, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2238
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2239
		case ACE_EVERYONE:
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2240
			checkit = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2241
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2242
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2243
		/* USER Entry */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2244
		default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2245
			if (entry_type == 0) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2246
				uid_t newid;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2247
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  2248
				newid = zfs_fuid_map_id(zfsvfs, who, cr,
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  2249
				    ZFS_ACE_USER);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2250
				if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2251
				    uid == newid)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2252
					checkit = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2253
				break;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2254
			} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2255
				zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2256
				mutex_exit(&zp->z_acl_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2257
				return (EIO);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2258
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2259
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2260
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2261
		if (checkit) {
6056
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2262
			uint32_t mask_matched = (access_mask & *working_mode);
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2263
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2264
			if (mask_matched) {
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2265
				if (type == DENY)
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2266
					deny_mask |= mask_matched;
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2267
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2268
				*working_mode &= ~mask_matched;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2269
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2270
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2271
6056
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2272
		/* Are we done? */
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2273
		if (*working_mode == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2274
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2275
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2276
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2277
	mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2278
	zfs_acl_free(aclp);
6056
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2279
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2280
	/* Put the found 'denies' back on the working mode */
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2281
	if (deny_mask) {
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2282
		*working_mode |= deny_mask;
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2283
		return (EACCES);
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2284
	} else if (*working_mode) {
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2285
		return (ACCESS_UNDETERMINED);
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2286
	}
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2287
37f30782c577 6664536 zfs O_RDWR access check more stringent than tmpfs or ufs
marks
parents: 5959
diff changeset
  2288
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2289
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2290
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2291
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2292
zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2293
    cred_t *cr)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2294
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2295
	if (*working_mode != ACE_WRITE_DATA)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2296
		return (EACCES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2297
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2298
	return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2299
	    check_privs, B_FALSE, cr));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2300
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2301
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2302
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2303
 * Determine whether Access should be granted/denied, invoking least
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2304
 * priv subsytem when a deny is determined.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2305
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2306
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2307
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2308
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2309
	uint32_t	working_mode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2310
	int		error;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2311
	int		is_attr;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2312
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2313
	boolean_t 	check_privs;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2314
	znode_t		*xzp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2315
	znode_t 	*check_zp = zp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2316
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2317
	is_attr = ((zp->z_phys->zp_flags & ZFS_XATTR) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2318
	    (ZTOV(zp)->v_type == VDIR));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2319
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2320
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2321
	 * If attribute then validate against base file
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2322
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2323
	if (is_attr) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2324
		if ((error = zfs_zget(zp->z_zfsvfs,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2325
		    zp->z_phys->zp_parent, &xzp)) != 0)	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2326
			return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2327
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2328
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2329
		check_zp = xzp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2330
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2331
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2332
		 * fixup mode to map to xattr perms
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2333
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2334
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2335
		if (mode & (ACE_WRITE_DATA|ACE_APPEND_DATA)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2336
			mode &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2337
			mode |= ACE_WRITE_NAMED_ATTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2338
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2339
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2340
		if (mode & (ACE_READ_DATA|ACE_EXECUTE)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2341
			mode &= ~(ACE_READ_DATA|ACE_EXECUTE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2342
			mode |= ACE_READ_NAMED_ATTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2343
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2344
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2345
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2346
	if ((error = zfs_zaccess_common(check_zp, mode, &working_mode,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2347
	    &check_privs, skipaclchk, cr)) == 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2348
		if (is_attr)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2349
			VN_RELE(ZTOV(xzp));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2350
		return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2351
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2352
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  2353
	if (error && !check_privs) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2354
		if (is_attr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2355
			VN_RELE(ZTOV(xzp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2356
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2357
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2358
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2359
	if (error && (flags & V_APPEND)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2360
		error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2361
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2362
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2363
	if (error && check_privs) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2364
		uid_t		owner;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2365
		mode_t		checkmode = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2366
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  2367
		owner = zfs_fuid_map_id(zfsvfs, check_zp->z_phys->zp_uid, cr,
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  2368
		    ZFS_OWNER);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2369
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2370
		/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2371
		 * First check for implicit owner permission on
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2372
		 * read_acl/read_attributes
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2373
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2374
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2375
		error = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2376
		ASSERT(working_mode != 0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2377
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2378
		if ((working_mode & (ACE_READ_ACL|ACE_READ_ATTRIBUTES) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2379
		    owner == crgetuid(cr)))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2380
			working_mode &= ~(ACE_READ_ACL|ACE_READ_ATTRIBUTES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2381
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2382
		if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2383
		    ACE_READ_ACL|ACE_READ_ATTRIBUTES))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2384
			checkmode |= VREAD;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2385
		if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2386
		    ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2387
			checkmode |= VWRITE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2388
		if (working_mode & ACE_EXECUTE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2389
			checkmode |= VEXEC;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2390
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2391
		if (checkmode)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2392
			error = secpolicy_vnode_access(cr, ZTOV(check_zp),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2393
			    owner, checkmode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2394
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2395
		if (error == 0 && (working_mode & ACE_WRITE_OWNER))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2396
			error = secpolicy_vnode_create_gid(cr);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2397
		if (error == 0 && (working_mode & ACE_WRITE_ACL))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2398
			error = secpolicy_vnode_setdac(cr, owner);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2399
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2400
		if (error == 0 && (working_mode &
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2401
		    (ACE_DELETE|ACE_DELETE_CHILD)))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2402
			error = secpolicy_vnode_remove(cr);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2403
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2404
		if (error == 0 && (working_mode & ACE_SYNCHRONIZE))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2405
			error = secpolicy_vnode_owner(cr, owner);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2406
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2407
		if (error == 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2408
			/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2409
			 * See if any bits other than those already checked
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2410
			 * for are still present.  If so then return EACCES
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2411
			 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2412
			if (working_mode & ~(ZFS_CHECKED_MASKS)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2413
				error = EACCES;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2414
			}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2415
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2416
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2417
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2418
	if (is_attr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2419
		VN_RELE(ZTOV(xzp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2420
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2421
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2422
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2423
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2424
/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2425
 * Translate traditional unix VREAD/VWRITE/VEXEC mode into
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2426
 * native ACL format and call zfs_zaccess()
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2427
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2428
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2429
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2430
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2431
	return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2432
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2433
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2434
/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2435
 * Access function for secpolicy_vnode_setattr
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2436
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2437
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2438
zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2439
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2440
	int v4_mode = zfs_unix_to_v4(mode >> 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2441
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2442
	return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2443
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2444
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2445
static int
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2446
zfs_delete_final_check(znode_t *zp, znode_t *dzp, cred_t *cr)
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2447
{
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2448
	int error;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2449
	uid_t downer;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2450
	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2451
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  2452
	downer = zfs_fuid_map_id(zfsvfs, dzp->z_phys->zp_uid, cr, ZFS_OWNER);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2453
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2454
	error = secpolicy_vnode_access(cr, ZTOV(zp), downer, S_IWRITE|S_IEXEC);
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2455
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2456
	if (error == 0)
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2457
		error = zfs_sticky_remove_access(dzp, zp, cr);
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2458
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2459
	return (error);
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2460
}
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2461
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2462
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2463
 * Determine whether Access should be granted/deny, without
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2464
 * consulting least priv subsystem.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2465
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2466
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2467
 * The following chart is the recommended NFSv4 enforcement for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2468
 * ability to delete an object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2469
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2470
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2471
 *      |   Parent Dir  |           Target Object Permissions |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2472
 *      |  permissions  |                                     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2473
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2474
 *      |               | ACL Allows | ACL Denies| Delete     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2475
 *      |               |  Delete    |  Delete   | unspecified|
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2476
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2477
 *      |  ACL Allows   | Permit     | Permit    | Permit     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2478
 *      |  DELETE_CHILD |                                     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2479
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2480
 *      |  ACL Denies   | Permit     | Deny      | Deny       |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2481
 *      |  DELETE_CHILD |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2482
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2483
 *      | ACL specifies |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2484
 *      | only allow    | Permit     | Permit    | Permit     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2485
 *      | write and     |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2486
 *      | execute       |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2487
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2488
 *      | ACL denies    |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2489
 *      | write and     | Permit     | Deny      | Deny       |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2490
 *      | execute       |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2491
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2492
 *         ^
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2493
 *         |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2494
 *         No search privilege, can't even look up file?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2495
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2496
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2497
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2498
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2499
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2500
	uint32_t dzp_working_mode = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2501
	uint32_t zp_working_mode = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2502
	int dzp_error, zp_error;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2503
	boolean_t dzpcheck_privs = B_TRUE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2504
	boolean_t zpcheck_privs = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2505
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2506
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2507
	 * Arghh, this check is going to require a couple of questions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2508
	 * to be asked.  We want specific DELETE permissions to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2509
	 * take precedence over WRITE/EXECUTE.  We don't
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2510
	 * want an ACL such as this to mess us up.
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2511
	 * user:joe:write_data:deny,user:joe:delete:allow
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2512
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2513
	 * However, deny permissions may ultimately be overridden
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2514
	 * by secpolicy_vnode_access().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2515
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2516
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2517
	if (zp->z_phys->zp_flags & (ZFS_IMMUTABLE | ZFS_NOUNLINK))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2518
		return (EPERM);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2519
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2520
	dzp_error = zfs_zaccess_common(dzp, ACE_DELETE_CHILD,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2521
	    &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2522
	zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2523
	    &zpcheck_privs, B_FALSE, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2524
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  2525
	if ((dzp_error && !dzpcheck_privs) || (zp_error && !zpcheck_privs))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2526
		return (dzp_error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2527
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2528
	/*
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2529
	 * First check the first row.
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2530
	 * We only need to see if parent Allows delete_child
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2531
	 */
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2532
	if ((dzp_working_mode & ACE_DELETE_CHILD) == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2533
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2534
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2535
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2536
	 * Second row
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2537
	 * we already have the necessary information in
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2538
	 * zp_working_mode, zp_error and dzp_error.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2539
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2540
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2541
	if ((zp_working_mode & ACE_DELETE) == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2542
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2543
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2544
	/*
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2545
	 * Now zp_error should either be EACCES which indicates
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2546
	 * a "deny" delete entry or ACCESS_UNDETERMINED if the "delete"
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2547
	 * entry exists on the target.
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2548
	 *
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2549
	 * dzp_error should be either EACCES which indicates a "deny"
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2550
	 * entry for delete_child or ACCESS_UNDETERMINED if no delete_child
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2551
	 * entry exists.  If value is EACCES then we are done
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2552
	 * and zfs_delete_final_check() will make the final decision
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2553
	 * regarding to allow the delete.
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2554
	 */
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2555
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2556
	ASSERT(zp_error != 0 && dzp_error != 0);
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2557
	if (dzp_error == EACCES)
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2558
		return (zfs_delete_final_check(zp, dzp, cr));
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2559
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2560
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2561
	 * Third Row
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2562
	 * Only need to check for write/execute on parent
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2563
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2564
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2565
	dzp_error = zfs_zaccess_common(dzp, ACE_WRITE_DATA|ACE_EXECUTE,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2566
	    &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2567
5959
1e1904b8526d 6650192 zfs ACL/fuid code could use some minor cleanup
marks
parents: 5824
diff changeset
  2568
	if (dzp_error && !dzpcheck_privs)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2569
		return (dzp_error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2570
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2571
	if ((dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) == 0)
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2572
		return (zfs_sticky_remove_access(dzp, zp, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2573
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2574
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2575
	 * Fourth Row
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2576
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2577
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2578
	if (((dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) != 0) &&
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2579
	    ((zp_working_mode & ACE_DELETE) == 0))
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2580
		return (zfs_sticky_remove_access(dzp, zp, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2581
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2582
	return (zfs_delete_final_check(zp, dzp, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2583
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2584
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2585
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2586
zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2587
    znode_t *tzp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2588
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2589
	int add_perm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2590
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2591
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2592
	if (szp->z_phys->zp_flags & ZFS_AV_QUARANTINED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2593
		return (EACCES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2594
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2595
	add_perm = (ZTOV(szp)->v_type == VDIR) ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2596
	    ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2597
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2598
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2599
	 * Rename permissions are combination of delete permission +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2600
	 * add file/subdir permission.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2601
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2602
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2603
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2604
	 * first make sure we do the delete portion.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2605
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2606
	 * If that succeeds then check for add_file/add_subdir permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2607
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2608
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2609
	if (error = zfs_zaccess_delete(sdzp, szp, cr))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2610
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2611
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2612
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2613
	 * If we have a tzp, see if we can delete it?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2614
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2615
	if (tzp) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2616
		if (error = zfs_zaccess_delete(tdzp, tzp, cr))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2617
			return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2618
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2619
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2620
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2621
	 * Now check for add permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2622
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2623
	error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2624
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2625
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2626
}