usr/src/uts/common/fs/zfs/zfs_acl.c
author marks
Mon, 14 Jan 2008 08:49:26 -0800
changeset 5824 1d2d522d19b5
parent 5771 7ba3a2c57d6a
child 5959 1e1904b8526d
permissions -rw-r--r--
6603908 can't change mode if FS/dir is out of quota
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)
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
   548
				aclp->z_has_fuids = IS_EPHEMERAL(acep->a_who) ?
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
   549
				    B_TRUE : B_FALSE;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   550
			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
   551
		}
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
   552
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   553
		/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   554
		 * Make sure ACE is valid
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   555
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   556
		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
   557
		    aceptr->z_hdr.z_flags) != B_TRUE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   558
			return (EINVAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   559
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   560
		switch (acep->a_type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   561
		case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   562
		case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   563
		case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   564
		case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   565
			zobjacep = (zfs_object_ace_t *)aceptr;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   566
			aceobjp = (ace_object_t *)acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   567
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   568
			bcopy(aceobjp->a_obj_type, zobjacep->z_object_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   569
			    sizeof (aceobjp->a_obj_type));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   570
			bcopy(aceobjp->a_inherit_obj_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   571
			    zobjacep->z_inherit_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   572
			    sizeof (aceobjp->a_inherit_obj_type));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   573
			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
   574
			break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   575
		default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   576
			acep = (ace_t *)((caddr_t)acep + sizeof (ace_t));
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
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   579
		aceptr = (zfs_ace_t *)((caddr_t)aceptr +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   580
		    aclp->z_ops.ace_size(aceptr));
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
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   583
	*size = (caddr_t)aceptr - (caddr_t)z_acl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   585
	return (0);
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
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   589
 * Copy ZFS ACEs to fixed size ace_t layout
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   590
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   591
static void
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   592
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
   593
    void *datap, int filter)
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   594
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   595
	uint64_t who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   596
	uint32_t access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   597
	uint16_t iflags, type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   598
	zfs_ace_hdr_t *zacep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   599
	ace_t *acep = datap;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   600
	ace_object_t *objacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   601
	zfs_object_ace_t *zobjacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   602
	zfs_fuid_hdl_t hdl = { 0 };
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   603
	size_t ace_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   604
	uint16_t entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   605
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   606
	while (zacep = zfs_acl_next_ace(aclp, zacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   607
	    &who, &access_mask, &iflags, &type)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   608
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   609
		switch (type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   610
		case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   611
		case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   612
		case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   613
		case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   614
			if (filter) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   615
				continue;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   616
			}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   617
			zobjacep = (zfs_object_ace_t *)zacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   618
			objacep = (ace_object_t *)acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   619
			bcopy(zobjacep->z_object_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   620
			    objacep->a_obj_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   621
			    sizeof (zobjacep->z_object_type));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   622
			bcopy(zobjacep->z_inherit_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   623
			    objacep->a_inherit_obj_type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   624
			    sizeof (zobjacep->z_inherit_type));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   625
			ace_size = sizeof (ace_object_t);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   626
			break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   627
		default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   628
			ace_size = sizeof (ace_t);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   629
			break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   630
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   631
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   632
		entry_type = (iflags & ACE_TYPE_FLAGS);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   633
		if ((entry_type != ACE_OWNER &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   634
		    entry_type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   635
		    entry_type != ACE_EVERYONE))
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   636
			zfs_fuid_queue_map_id(zfsvfs, &hdl, who, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   637
			    (entry_type & ACE_IDENTIFIER_GROUP) ?
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   638
			    ZFS_ACE_GROUP : ZFS_ACE_USER, &acep->a_who);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   639
		else
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   640
			acep->a_who = (uid_t)(int64_t)who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   641
		acep->a_access_mask = access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   642
		acep->a_flags = iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   643
		acep->a_type = type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   644
		acep = (ace_t *)((caddr_t)acep + ace_size);
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
	zfs_fuid_get_mappings(&hdl);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   647
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   648
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   649
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   650
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
   651
    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
   652
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   653
	int i;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   654
	zfs_oldace_t *aceptr = z_acl;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   655
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   656
	for (i = 0; i != aclcnt; i++, aceptr++) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   657
		aceptr->z_access_mask = acep[i].a_access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   658
		aceptr->z_type = acep[i].a_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   659
		aceptr->z_flags = acep[i].a_flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   660
		aceptr->z_fuid = acep[i].a_who;
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
		 * Make sure ACE is valid
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   663
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   664
		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
   665
		    aceptr->z_flags) != B_TRUE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   666
			return (EINVAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   667
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   668
	*size = (caddr_t)aceptr - (caddr_t)z_acl;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   669
	return (0);
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
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
 * convert old ACL format to new
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   674
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   675
void
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   676
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
   677
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   678
	zfs_oldace_t *oldaclp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   679
	int i;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   680
	uint16_t type, iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   681
	uint32_t access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   682
	uint64_t who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   683
	void *cookie = NULL;
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   684
	zfs_acl_node_t *newaclnode;
5331
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
	ASSERT(aclp->z_version == ZFS_ACL_VERSION_INITIAL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   687
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   688
	 * 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
   689
	 * for zfs_copy_ace_2_fuid().
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   690
	 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   691
	 * 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
   692
	 * everytime.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   693
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   694
	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
   695
	    KM_SLEEP);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   696
	i = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   697
	while (cookie = zfs_acl_next_ace(aclp, cookie, &who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   698
	    &access_mask, &iflags, &type)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   699
		oldaclp[i].z_flags = iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   700
		oldaclp[i].z_type = type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   701
		oldaclp[i].z_fuid = who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   702
		oldaclp[i++].z_access_mask = access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   703
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   704
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   705
	newaclnode = zfs_acl_node_alloc(aclp->z_acl_count *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   706
	    sizeof (zfs_object_ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   707
	aclp->z_ops = zfs_acl_fuid_ops;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   708
	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
   709
	    newaclnode->z_acldata, aclp->z_acl_count,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   710
	    &newaclnode->z_size) == 0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   711
	newaclnode->z_ace_count = aclp->z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   712
	aclp->z_version = ZFS_ACL_VERSION;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   713
	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
   714
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
	 * Release all previous ACL nodes
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   717
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   718
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   719
	zfs_acl_release_nodes(aclp);
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   720
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   721
	list_insert_head(&aclp->z_acl, newaclnode);
5489
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   722
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   723
	aclp->z_acl_bytes = newaclnode->z_size;
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   724
	aclp->z_acl_count = newaclnode->z_ace_count;
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
   725
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
 * Convert unix access mask to v4 access mask
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
static uint32_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
zfs_unix_to_v4(uint32_t access_mask)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
	uint32_t new_mask = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   736
	if (access_mask & S_IXOTH)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   737
		new_mask |= ACE_EXECUTE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   738
	if (access_mask & S_IWOTH)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   739
		new_mask |= ACE_WRITE_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   740
	if (access_mask & S_IROTH)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   741
		new_mask |= ACE_READ_DATA;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
	return (new_mask);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   743
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   744
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   746
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
   747
    uint16_t access_type, uint64_t fuid, uint16_t entry_type)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   749
	uint16_t type = entry_type & ACE_TYPE_FLAGS;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   750
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   751
	aclp->z_ops.ace_mask_set(acep, access_mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   752
	aclp->z_ops.ace_type_set(acep, access_type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   753
	aclp->z_ops.ace_flags_set(acep, entry_type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   754
	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
   755
	    type != ACE_EVERYONE))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   756
		aclp->z_ops.ace_who_set(acep, fuid);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   759
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   760
 * Determine mode of file based on ACL.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   761
 * Also, create FUIDs for any User/Group ACEs
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   762
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
static uint64_t
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   764
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
   765
    zfs_fuid_info_t **fuidp, dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   767
	int		entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   768
	mode_t		mode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   769
	mode_t		seen = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   770
	zfs_ace_hdr_t 	*acep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   771
	uint64_t	who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   772
	uint16_t	iflags, type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   773
	uint32_t	access_mask;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   775
	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
   776
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   777
	while (acep = zfs_acl_next_ace(aclp, acep, &who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   778
	    &access_mask, &iflags, &type)) {
4869
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   779
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   780
		/*
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   781
		 * Skip over inherit only ACEs
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   782
		 */
5762
a454af064490 6646907 mismerge in zfs_mode_fuid_compute()
marks
parents: 5489
diff changeset
   783
		if (iflags & ACE_INHERIT_ONLY_ACE)
4869
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   784
			continue;
f123f22fc641 6590376 Fails to chmod on a zfs volume with windows ACL
marks
parents: 4321
diff changeset
   785
5762
a454af064490 6646907 mismerge in zfs_mode_fuid_compute()
marks
parents: 5489
diff changeset
   786
		entry_type = (iflags & ACE_TYPE_FLAGS);
a454af064490 6646907 mismerge in zfs_mode_fuid_compute()
marks
parents: 5489
diff changeset
   787
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
		if (entry_type == ACE_OWNER) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   789
			if ((access_mask & ACE_READ_DATA) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
			    (!(seen & S_IRUSR))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
				seen |= S_IRUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   792
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
					mode |= S_IRUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   795
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   796
			if ((access_mask & ACE_WRITE_DATA) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
			    (!(seen & S_IWUSR))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   798
				seen |= S_IWUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   799
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
					mode |= S_IWUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   802
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   803
			if ((access_mask & ACE_EXECUTE) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   804
			    (!(seen & S_IXUSR))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   805
				seen |= S_IXUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   806
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   807
					mode |= S_IXUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   808
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
		} else if (entry_type == OWNING_GROUP) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   811
			if ((access_mask & ACE_READ_DATA) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
			    (!(seen & S_IRGRP))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
				seen |= S_IRGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   814
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
					mode |= S_IRGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   818
			if ((access_mask & ACE_WRITE_DATA) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
			    (!(seen & S_IWGRP))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   820
				seen |= S_IWGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   821
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   822
					mode |= S_IWGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   825
			if ((access_mask & ACE_EXECUTE) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
			    (!(seen & S_IXGRP))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
				seen |= S_IXGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   828
				if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
					mode |= S_IXGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   831
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
		} else if (entry_type == ACE_EVERYONE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   833
			if ((access_mask & ACE_READ_DATA)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
				if (!(seen & S_IRUSR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
					seen |= S_IRUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   836
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
						mode |= S_IRUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
				if (!(seen & S_IRGRP)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
					seen |= S_IRGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   842
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
						mode |= S_IRGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
				if (!(seen & S_IROTH)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
					seen |= S_IROTH;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   848
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
						mode |= S_IROTH;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   853
			if ((access_mask & ACE_WRITE_DATA)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
				if (!(seen & S_IWUSR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
					seen |= S_IWUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   856
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
						mode |= S_IWUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
				if (!(seen & S_IWGRP)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
					seen |= S_IWGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   862
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
						mode |= S_IWGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
				if (!(seen & S_IWOTH)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   867
					seen |= S_IWOTH;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   868
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
						mode |= S_IWOTH;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   871
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   872
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   873
			if ((access_mask & ACE_EXECUTE)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   874
				if (!(seen & S_IXUSR)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
					seen |= S_IXUSR;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   876
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
						mode |= S_IXUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
				if (!(seen & S_IXGRP)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
					seen |= S_IXGRP;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   882
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
						mode |= S_IXGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   886
				if (!(seen & S_IXOTH)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   887
					seen |= S_IXOTH;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   888
					if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
						mode |= S_IXOTH;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
					}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   893
		}
5331
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
		 * Now handle FUID create for user/group ACEs
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   896
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   897
		if (entry_type == 0 || entry_type == ACE_IDENTIFIER_GROUP) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   898
			aclp->z_ops.ace_who_set(acep,
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
   899
			    zfs_fuid_create(zp->z_zfsvfs, who, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   900
			    entry_type == 0 ? ZFS_ACE_USER : ZFS_ACE_GROUP, tx,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   901
			    fuidp));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   902
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
	return (mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   906
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   907
static zfs_acl_t *
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   908
zfs_acl_node_read_internal(znode_t *zp, boolean_t will_modify)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
	zfs_acl_t	*aclp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   911
	zfs_acl_node_t	*aclnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   913
	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
   914
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   915
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   916
	 * 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
   917
	 * 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
   918
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   919
	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
   920
		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
   921
		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
   922
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   923
		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
   924
		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
   925
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   926
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   927
	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
   928
	aclnode->z_ace_count = aclp->z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   929
	if (will_modify) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   930
		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
   931
		    aclp->z_acl_bytes);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   932
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   933
		aclnode->z_size = aclp->z_acl_bytes;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   934
		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
   935
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   936
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   937
	list_insert_head(&aclp->z_acl, aclnode);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
	return (aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   942
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   943
 * Read an external acl object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   944
 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   945
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   946
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
   947
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   948
	uint64_t extacl = zp->z_phys->zp_acl.z_acl_extern_obj;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
	zfs_acl_t	*aclp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   950
	size_t		aclsize;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   951
	size_t		acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   952
	zfs_acl_node_t	*aclnode;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   953
	int error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   954
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   955
	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   956
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   957
	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
   958
		*aclpp = zfs_acl_node_read_internal(zp, will_modify);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   959
		return (0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   960
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   961
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   962
	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
   963
	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
   964
		zfs_acl_phys_v0_t *zacl0 =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   965
		    (zfs_acl_phys_v0_t *)&zp->z_phys->zp_acl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   966
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   967
		aclsize = ZFS_ACL_SIZE(zacl0->z_acl_count);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   968
		acl_count = zacl0->z_acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   969
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   970
		aclsize = zp->z_phys->zp_acl.z_acl_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   971
		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
   972
		if (aclsize == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   973
			aclsize = acl_count * sizeof (zfs_ace_t);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   974
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   975
	aclnode = zfs_acl_node_alloc(aclsize);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   976
	list_insert_head(&aclp->z_acl, aclnode);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   977
	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
   978
	    aclsize, aclnode->z_acldata);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   979
	aclnode->z_ace_count = acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   980
	aclp->z_acl_count = acl_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   981
	aclp->z_acl_bytes = aclsize;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   982
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   983
	if (error != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   984
		zfs_acl_free(aclp);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   985
		return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   986
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   987
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   988
	*aclpp = aclp;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
   989
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   990
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   991
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   992
/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
   993
 * common code for setting ACLs.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   994
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   995
 * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   996
 * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   997
 * already checked the acl and knows whether to inherit.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   998
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   999
int
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1000
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
  1001
    zfs_fuid_info_t **fuidp, dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1002
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1003
	int		error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1004
	znode_phys_t	*zphys = zp->z_phys;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1005
	zfs_acl_phys_t	*zacl = &zphys->zp_acl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1006
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1007
	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
  1008
	uint64_t	off = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1009
	dmu_object_type_t otype;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1010
	zfs_acl_node_t	*aclnode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1011
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1012
	ASSERT(MUTEX_HELD(&zp->z_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1013
	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1014
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1015
	dmu_buf_will_dirty(zp->z_dbuf, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1017
	zphys->zp_mode = zfs_mode_fuid_compute(zp, aclp, cr, fuidp, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
	/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1020
	 * 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
  1021
	 * 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
  1022
	 * layout.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1023
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1024
	if (!zfsvfs->z_use_fuids) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1025
		otype = DMU_OT_OLDACL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1026
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1027
		if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1028
		    (zfsvfs->z_version >= ZPL_VERSION_FUID))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1029
			zfs_acl_xform(zp, aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1030
		ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1031
		otype = DMU_OT_ACL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1032
	}
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 (aclp->z_acl_bytes > ZFS_ACE_SPACE) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1035
		/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1036
		 * If ACL was previously external and we are now
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1037
		 * converting to new ACL format then release old
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1038
		 * ACL object and create a new one.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1039
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1040
		if (aoid && aclp->z_version != zacl->z_acl_version) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1041
			error = dmu_object_free(zfsvfs->z_os,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1042
			    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
  1043
			if (error)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1044
				return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1045
			aoid = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1046
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1047
		if (aoid == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1048
			aoid = dmu_object_alloc(zfsvfs->z_os,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1049
			    otype, aclp->z_acl_bytes,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1050
			    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
  1051
			    otype == DMU_OT_ACL ? DN_MAX_BONUSLEN : 0, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1052
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1053
			(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
  1054
			    aclp->z_acl_bytes, 0, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1055
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1056
		zphys->zp_acl.z_acl_extern_obj = aoid;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1057
		for (aclnode = list_head(&aclp->z_acl); aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1058
		    aclnode = list_next(&aclp->z_acl, aclnode)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1059
			if (aclnode->z_ace_count == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1060
				continue;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1061
			dmu_write(zfsvfs->z_os, aoid, off,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1062
			    aclnode->z_size, aclnode->z_acldata, tx);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1063
			off += aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1064
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1065
	} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1066
		void *start = zacl->z_ace_data;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1067
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1068
		 * Migrating back embedded?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1069
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1070
		if (zphys->zp_acl.z_acl_extern_obj) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1071
			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
  1072
			    zp->z_phys->zp_acl.z_acl_extern_obj, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1073
			if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1074
				return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1075
			zphys->zp_acl.z_acl_extern_obj = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1076
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1077
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1078
		for (aclnode = list_head(&aclp->z_acl); aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1079
		    aclnode = list_next(&aclp->z_acl, aclnode)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1080
			if (aclnode->z_ace_count == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1081
				continue;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1082
			bcopy(aclnode->z_acldata, start, aclnode->z_size);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1083
			start = (caddr_t)start + aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1084
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1085
	}
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1086
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1087
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1088
	 * 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
  1089
	 * layout of znode_acl_phys_t.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1090
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1091
	if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1092
		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
  1093
		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
  1094
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1095
		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
  1096
		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
  1097
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1099
	zphys->zp_acl.z_acl_version = aclp->z_version;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1100
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
	 * Replace ACL wide bits, but first clear them.
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 &= ~ZFS_ACL_WIDE_FLAGS;
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
	zp->z_phys->zp_flags |= aclp->z_hints;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1107
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1108
	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
  1109
		zp->z_phys->zp_flags |= ZFS_ACL_TRIVIAL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1110
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
	zfs_time_stamper_locked(zp, STATE_CHANGED, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1112
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1115
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1116
 * Update access mask for prepended ACE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1117
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1118
 * This applies the "groupmask" value for aclmode property.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1119
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1120
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1121
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
  1122
    mode_t mode, uint64_t owner)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1123
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1124
	int	rmask, wmask, xmask;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1125
	int	user_ace;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1126
	uint16_t aceflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1127
	uint32_t origmask, acepmask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1128
	uint64_t fuid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1130
	aceflags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1131
	fuid = aclp->z_ops.ace_who_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1132
	origmask = aclp->z_ops.ace_mask_get(origacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1133
	acepmask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1134
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1135
	user_ace = (!(aceflags &
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1136
	    (ACE_OWNER|ACE_GROUP|ACE_IDENTIFIER_GROUP)));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1138
	if (user_ace && (fuid == owner)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1139
		rmask = S_IRUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
		wmask = S_IWUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1141
		xmask = S_IXUSR;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
		rmask = S_IRGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1144
		wmask = S_IWGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
		xmask = S_IXGRP;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1146
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1147
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1148
	if (origmask & ACE_READ_DATA) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1149
		if (mode & rmask) {
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
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1152
			acepmask |= ACE_READ_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1153
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1156
	if (origmask & ACE_WRITE_DATA) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1157
		if (mode & wmask) {
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
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1160
			acepmask |= ACE_WRITE_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1161
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1162
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1163
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1164
	if (origmask & ACE_APPEND_DATA) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1165
		if (mode & wmask) {
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
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1168
			acepmask |= ACE_APPEND_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1169
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1171
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1172
	if (origmask & ACE_EXECUTE) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1173
		if (mode & xmask) {
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
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1176
			acepmask |= ACE_EXECUTE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1177
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1178
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1179
	aclp->z_ops.ace_mask_set(acep, acepmask);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1180
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1182
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
 * Apply mode to canonical six ACEs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1186
zfs_acl_fixup_canonical_six(zfs_acl_t *aclp, mode_t mode)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1187
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1188
	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
  1189
	void	*acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1190
	int	maskoff = aclp->z_ops.ace_mask_off();
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1191
	size_t abstract_size = aclp->z_ops.ace_abstract_size();
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1192
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1193
	ASSERT(aclnode != NULL);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1194
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1195
	acep = (void *)((caddr_t)aclnode->z_acldata +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1196
	    aclnode->z_size - (abstract_size * 6));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
	 * Fixup final ACEs to match the mode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1200
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1201
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1202
	adjust_ace_pair_common(acep, maskoff, abstract_size,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1203
	    (mode & 0700) >> 6);	/* owner@ */
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
	acep = (caddr_t)acep + (abstract_size * 2);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1206
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1207
	adjust_ace_pair_common(acep, maskoff, abstract_size,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1208
	    (mode & 0070) >> 3);	/* group@ */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1209
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1210
	acep = (caddr_t)acep + (abstract_size * 2);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1211
	adjust_ace_pair_common(acep, maskoff,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1212
	    abstract_size, mode);	/* everyone@ */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1213
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1214
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1215
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1216
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1217
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
  1218
    int entry_type, int accessmask)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1219
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1220
	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
  1221
	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
  1222
	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
  1223
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1224
	return (mask == accessmask && type == allow_deny &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1225
	    ((flags & ACE_TYPE_FLAGS) == entry_type));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1226
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1227
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1228
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1229
 * Can prepended ACE be reused?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1230
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1231
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1232
zfs_reuse_deny(zfs_acl_t *aclp, void *acep, void *prevacep)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1233
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1234
	int okay_masks;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1235
	uint16_t prevtype;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1236
	uint16_t prevflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1237
	uint16_t flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1238
	uint32_t mask, prevmask;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1239
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1240
	if (prevacep == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1241
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1242
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1243
	prevtype = aclp->z_ops.ace_type_get(prevacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1244
	prevflags = aclp->z_ops.ace_flags_get(prevacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1245
	flags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1246
	mask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1247
	prevmask = aclp->z_ops.ace_mask_get(prevacep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1248
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1249
	if (prevtype != DENY)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1250
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1251
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1252
	if (prevflags != (flags & ACE_IDENTIFIER_GROUP))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1253
		return (B_FALSE);
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
	okay_masks = (mask & OKAY_MASK_BITS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1256
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1257
	if (prevmask & ~okay_masks)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
	return (B_TRUE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1263
5331
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
 * 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
  1266
 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1267
 * This will result in two possible results.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1268
 * 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
  1269
 *    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
  1270
 *    a new node inserted above it.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1271
 *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1272
 * 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
  1273
 *    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
  1274
 *    in between the two split nodes.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1275
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1276
static zfs_acl_node_t *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1277
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
  1278
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1279
	zfs_acl_node_t 	*newnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1280
	zfs_acl_node_t 	*trailernode = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1281
	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
  1282
	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
  1283
	int		trailer_count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1284
	size_t		oldsize;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1285
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1286
	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
  1287
	newnode->z_ace_count = 1;
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
	oldsize = currnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1290
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1291
	if (curr_idx != 1) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1292
		trailernode = zfs_acl_node_alloc(0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1293
		trailernode->z_acldata = acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1294
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1295
		trailer_count = currnode->z_ace_count - curr_idx + 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1296
		currnode->z_ace_count = curr_idx - 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1297
		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
  1298
		trailernode->z_size = oldsize - currnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1299
		trailernode->z_ace_count = trailer_count;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1300
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1301
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1302
	aclp->z_acl_count += 1;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1303
	aclp->z_acl_bytes += aclp->z_ops.ace_size(acep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1304
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1305
	if (curr_idx == 1)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1306
		list_insert_before(&aclp->z_acl, currnode, newnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1307
	else
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1308
		list_insert_after(&aclp->z_acl, currnode, newnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1309
	if (trailernode) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1310
		list_insert_after(&aclp->z_acl, newnode, trailernode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1311
		aclp->z_curr_node = trailernode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1312
		trailernode->z_ace_idx = 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1313
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1314
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1315
	return (newnode);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1316
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1317
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1318
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1319
 * Prepend deny ACE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1320
 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1321
static void *
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1322
zfs_acl_prepend_deny(znode_t *zp, zfs_acl_t *aclp, void *acep,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1323
    mode_t mode)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1324
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1325
	zfs_acl_node_t *aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1326
	void  *newacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1327
	uint64_t fuid;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1328
	uint16_t flags;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1329
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1330
	aclnode = zfs_acl_ace_insert(aclp, acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1331
	newacep = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1332
	fuid = aclp->z_ops.ace_who_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1333
	flags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1334
	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
  1335
	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
  1336
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1337
	return (newacep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1338
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1339
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1340
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1341
 * Split an inherited ACE into inherit_only ACE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1342
 * and original ACE with inheritance flags stripped off.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1343
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1344
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1345
zfs_acl_split_ace(zfs_acl_t *aclp, zfs_ace_hdr_t *acep)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1346
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1347
	zfs_acl_node_t *aclnode;
5435
1be0be66916d 6624956 zfs_log_fuid_ids can cause panic on sparc
marks
parents: 5331
diff changeset
  1348
	zfs_acl_node_t *currnode;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1349
	void  *newacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1350
	uint16_t type, flags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1351
	uint32_t mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1352
	uint64_t fuid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1353
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1354
	type = aclp->z_ops.ace_type_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1355
	flags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1356
	mask = aclp->z_ops.ace_mask_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1357
	fuid = aclp->z_ops.ace_who_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1358
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1359
	aclnode = zfs_acl_ace_insert(aclp, acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1360
	newacep = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1361
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1362
	aclp->z_ops.ace_type_set(newacep, type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1363
	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
  1364
	aclp->z_ops.ace_mask_set(newacep, mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1365
	aclp->z_ops.ace_type_set(newacep, type);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1366
	aclp->z_ops.ace_who_set(newacep, fuid);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1367
	aclp->z_next_ace = acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1368
	flags &= ~ALL_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1369
	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
  1370
	currnode = zfs_acl_curr_node(aclp);
1be0be66916d 6624956 zfs_log_fuid_ids can cause panic on sparc
marks
parents: 5331
diff changeset
  1371
	ASSERT(currnode->z_ace_idx >= 1);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1372
	currnode->z_ace_idx -= 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1373
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1374
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1375
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1376
 * Are ACES started at index i, the canonical six ACES?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1377
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1378
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1379
zfs_have_canonical_six(zfs_acl_t *aclp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1380
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1381
	void *acep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1382
	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
  1383
	int		i = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1384
	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
  1385
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1386
	ASSERT(aclnode != NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1387
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1388
	if (aclnode->z_ace_count < 6)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1389
		return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1390
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1391
	acep = (void *)((caddr_t)aclnode->z_acldata +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1392
	    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
  1393
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1394
	if ((zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1395
	    DENY, ACE_OWNER, 0) &&
5331
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++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1397
	    ALLOW, ACE_OWNER, OWNER_ALLOW_MASK) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1398
	    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
  1399
	    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
  1400
	    (abstract_size * i++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1401
	    ALLOW, OWNING_GROUP, 0) &&
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++),
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1403
	    DENY, ACE_EVERYONE, EVERYONE_DENY_MASK) &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1404
	    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
  1405
	    ALLOW, ACE_EVERYONE, EVERYONE_ALLOW_MASK))) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1406
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1407
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1408
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1409
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1410
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1411
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1412
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1413
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1414
 * Apply step 1g, to group entries
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1415
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1416
 * Need to deal with corner case where group may have
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1417
 * greater permissions than owner.  If so then limit
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1418
 * group permissions, based on what extra permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1419
 * group has.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1420
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1421
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1422
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
  1423
    mode_t mode)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1424
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1425
	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
  1426
	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
  1427
	uint16_t prevflags = aclp->z_ops.ace_flags_get(prevacep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1428
	mode_t extramode = (mode >> 3) & 07;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1429
	mode_t ownermode = (mode >> 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1430
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1431
	if (prevflags & ACE_IDENTIFIER_GROUP) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1432
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1433
		extramode &= ~ownermode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1434
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1435
		if (extramode) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1436
			if (extramode & S_IROTH) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1437
				prevmask &= ~ACE_READ_DATA;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1438
				mask &= ~ACE_READ_DATA;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1439
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1440
			if (extramode & S_IWOTH) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1441
				prevmask &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1442
				mask &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1443
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1444
			if (extramode & S_IXOTH) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1445
				prevmask  &= ~ACE_EXECUTE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1446
				mask &= ~ACE_EXECUTE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1447
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1448
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1449
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1450
	aclp->z_ops.ace_mask_set(acep, mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1451
	aclp->z_ops.ace_mask_set(prevacep, prevmask);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1452
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1453
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1454
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
 * Apply the chmod algorithm as described
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1456
 * in PSARC/2002/240
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1457
 */
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1458
static void
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1459
zfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1460
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1461
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1462
	void		*acep = NULL, *prevacep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1463
	uint64_t	who;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1464
	int 		i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1465
	int 		entry_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1466
	int 		reuse_deny;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1467
	int 		need_canonical_six = 1;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1468
	uint16_t	iflags, type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1469
	uint32_t	access_mask;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1470
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1471
	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1472
	ASSERT(MUTEX_HELD(&zp->z_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1473
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1474
	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
  1475
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1476
	/*
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1477
	 * If discard then just discard all ACL nodes which
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1478
	 * represent the ACEs.
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1479
	 *
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1480
	 * New owner@/group@/everone@ ACEs will be added
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1481
	 * later.
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1482
	 */
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1483
	if (zfsvfs->z_acl_mode == ZFS_ACL_DISCARD)
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1484
		zfs_acl_release_nodes(aclp);
25bfaf065197 6601830 mismatch between zfs_mount() behavior and comment
marks
parents: 5435
diff changeset
  1485
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1486
	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
  1487
	    &iflags, &type)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1488
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1489
		entry_type = (iflags & ACE_TYPE_FLAGS);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1490
		iflags = (iflags & ALL_INHERIT);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1491
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1492
		if ((type != ALLOW && type != DENY) ||
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1493
		    (iflags & ACE_INHERIT_ONLY_ACE)) {
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1494
			if (iflags)
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1495
				aclp->z_hints |= ZFS_INHERIT_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1496
			switch (type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1497
			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1498
			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1499
			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1500
			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1501
				aclp->z_hints |= ZFS_ACL_OBJ_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1502
				break;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1503
			}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1504
			goto nextace;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1505
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1506
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1507
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1508
		 * Need to split ace into two?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1509
		 */
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1510
		if ((iflags & (ACE_FILE_INHERIT_ACE|
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1511
		    ACE_DIRECTORY_INHERIT_ACE)) &&
905
920e9b2e0899 6347134 zfs_zaccess() is killing ZFS stat() performance
marks
parents: 865
diff changeset
  1512
		    (!(iflags & ACE_INHERIT_ONLY_ACE))) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1513
			zfs_acl_split_ace(aclp, acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1514
			aclp->z_hints |= ZFS_INHERIT_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1515
			goto nextace;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1516
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1517
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1518
		if (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1519
		    (entry_type == OWNING_GROUP)) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1520
			access_mask &= ~OGE_CLEAR;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1521
			aclp->z_ops.ace_mask_set(acep, access_mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1522
			goto nextace;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1523
		} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1524
			reuse_deny = B_TRUE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1525
			if (type == ALLOW) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1526
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1527
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1528
				 * Check preceding ACE if any, to see
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1529
				 * if we need to prepend a DENY ACE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1530
				 * This is only applicable when the acl_mode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1531
				 * property == groupmask.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1532
				 */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
  1533
				if (zfsvfs->z_acl_mode == ZFS_ACL_GROUPMASK) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1534
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1535
					reuse_deny = zfs_reuse_deny(aclp, acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1536
					    prevacep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1537
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1538
					if (reuse_deny == B_FALSE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1539
						prevacep =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1540
						    zfs_acl_prepend_deny(zp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1541
						    aclp, acep, mode);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1542
					} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1543
						zfs_acl_prepend_fixup(
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1544
						    aclp, prevacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1545
						    acep, mode,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1546
						    zp->z_phys->zp_uid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1547
					}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1548
					zfs_fixup_group_entries(aclp, acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1549
					    prevacep, mode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1550
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1551
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1552
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1553
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1554
nextace:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1555
		prevacep = acep;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1556
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1557
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1558
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1559
	 * Check out last six aces, if we have six.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1560
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1561
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1562
	if (aclp->z_acl_count >= 6) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1563
		if (zfs_have_canonical_six(aclp)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1564
			need_canonical_six = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1565
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1566
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1567
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1568
	if (need_canonical_six) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1569
		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
  1570
		void *zacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1571
		zfs_acl_node_t *aclnode =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1572
		    zfs_acl_node_alloc(abstract_size * 6);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1573
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1574
		aclnode->z_size = abstract_size * 6;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1575
		aclnode->z_ace_count = 6;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1576
		aclp->z_acl_bytes += aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1577
		list_insert_tail(&aclp->z_acl, aclnode);
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
		zacep = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1580
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1581
		i = 0;
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
		    0, DENY, -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++),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1585
		    OWNER_ALLOW_MASK, ALLOW, -1, ACE_OWNER);
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
		    DENY, -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++), 0,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1589
		    ALLOW, -1, OWNING_GROUP);
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_DENY_MASK, DENY, -1, ACE_EVERYONE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1592
		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
  1593
		    EVERYONE_ALLOW_MASK, ALLOW, -1, ACE_EVERYONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1594
		aclp->z_acl_count += 6;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1595
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1596
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1597
	zfs_acl_fixup_canonical_six(aclp, mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1598
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1599
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1600
int
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1601
zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1602
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1603
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1604
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1605
	mutex_enter(&zp->z_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1606
	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
  1607
	*aclp = NULL;
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1608
	error = zfs_acl_node_read(zp, aclp, B_TRUE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1609
	if (error == 0)
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  1610
		zfs_acl_chmod(zp, mode, *aclp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1611
	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
  1612
	mutex_exit(&zp->z_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1613
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1614
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1615
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1616
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1617
 * strip off write_owner and write_acl
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1618
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1619
static void
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1620
zfs_securemode_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1621
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1622
	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
  1623
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
  1624
	if ((zfsvfs->z_acl_inherit == ZFS_ACL_SECURE) &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1625
	    (aclp->z_ops.ace_type_get(acep) == ALLOW)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1626
		mask &= ~SECURE_CLEAR;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1627
		aclp->z_ops.ace_mask_set(acep, mask);
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
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
 * Should ACE be inherited?
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1633
 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1634
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1635
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
  1636
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1637
	int vtype = ZTOV(zp)->v_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1638
	int	iflags = (acep_flags & 0xf);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1639
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1640
	if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1641
		return (1);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1642
	else if (iflags & ACE_FILE_INHERIT_ACE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1643
		return (!((vtype == VDIR) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1644
		    (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1645
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1646
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1647
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1648
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1649
 * inherit inheritable ACEs from parent
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1650
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1651
static zfs_acl_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1652
zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1653
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1654
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1655
	void		*pacep;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1656
	void		*acep, *acep2;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1657
	zfs_acl_node_t  *aclnode, *aclnode2;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1658
	zfs_acl_t	*aclp = NULL;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1659
	uint64_t	who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1660
	uint32_t	access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1661
	uint16_t	iflags, newflags, type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1662
	size_t		ace_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1663
	void		*data1, *data2;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1664
	size_t		data1sz, data2sz;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1665
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1666
	pacep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1667
	aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
  1668
	if (zfsvfs->z_acl_inherit != ZFS_ACL_DISCARD) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1669
		while (pacep = zfs_acl_next_ace(paclp, pacep, &who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1670
		    &access_mask, &iflags, &type)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1671
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2638
diff changeset
  1672
			if (zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW &&
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1673
			    type == ALLOW)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1674
				continue;
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
			ace_size = aclp->z_ops.ace_size(pacep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1677
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1678
			if (zfs_ace_can_use(zp, iflags)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1679
				aclnode =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1680
				    zfs_acl_node_alloc(ace_size);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1681
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1682
				list_insert_tail(&aclp->z_acl, aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1683
				acep = aclnode->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1684
				zfs_set_ace(aclp, acep, access_mask, type,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1685
				    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
  1686
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
				 * Copy special opaque data if any
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1689
				 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1690
				if ((data1sz = paclp->z_ops.ace_data(pacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1691
				    &data1)) != 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1692
					VERIFY((data2sz =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1693
					    aclp->z_ops.ace_data(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1694
					    &data2)) == data1sz);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1695
					bcopy(data1, data2, data2sz);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1696
				}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1697
				aclp->z_acl_count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1698
				aclnode->z_ace_count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1699
				aclp->z_acl_bytes += aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1700
				newflags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1701
				if ((iflags &
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  1702
				    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
  1703
				    (ZTOV(zp)->v_type != VDIR)) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1704
					newflags &= ~ALL_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1705
					aclp->z_ops.ace_flags_set(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1706
					    newflags|ACE_INHERITED_ACE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1707
					zfs_securemode_update(zfsvfs,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1708
					    aclp, acep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1709
					continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1710
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1711
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1712
				ASSERT(ZTOV(zp)->v_type == VDIR);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1713
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1714
				newflags = aclp->z_ops.ace_flags_get(acep);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1715
				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
  1716
				    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
  1717
				    ACE_FILE_INHERIT_ACE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1718
					aclnode2 = zfs_acl_node_alloc(ace_size);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1719
					list_insert_tail(&aclp->z_acl,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1720
					    aclnode2);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1721
					acep2 = aclnode2->z_acldata;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1722
					zfs_set_ace(aclp, acep2,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1723
					    access_mask, type, who,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1724
					    iflags|ACE_INHERITED_ACE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1725
					newflags |= ACE_INHERIT_ONLY_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1726
					aclp->z_ops.ace_flags_set(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1727
					    newflags);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1728
					newflags &= ~ALL_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1729
					aclp->z_ops.ace_flags_set(acep2,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1730
					    newflags|ACE_INHERITED_ACE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1731
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
					 * Copy special opaque data if any
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1734
					 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1735
					if ((data1sz =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1736
					    aclp->z_ops.ace_data(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1737
					    &data1)) != 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1738
						VERIFY((data2sz =
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1739
						    aclp->z_ops.ace_data(acep2,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1740
						    &data2)) == data1sz);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1741
						bcopy(data1, data2, data1sz);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1742
					}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1743
					aclp->z_acl_count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1744
					aclnode2->z_ace_count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1745
					aclp->z_acl_bytes += aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1746
					zfs_securemode_update(zfsvfs,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1747
					    aclp, acep2);
865
4223fbdac5f3 6344681 chmod file_inherit should not added the specified ACE to new create subdirectores.
marks
parents: 789
diff changeset
  1748
				} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1749
					newflags |= ACE_INHERIT_ONLY_ACE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1750
					aclp->z_ops.ace_flags_set(acep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1751
					    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
  1752
				}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1753
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1754
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1755
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1756
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1757
	return (aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1758
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1759
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1760
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1761
 * Create file system object initial permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1762
 * including inheritable ACEs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1763
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1764
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1765
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
  1766
    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
  1767
    zfs_acl_t *setaclp, zfs_fuid_info_t **fuidp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1768
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1769
	uint64_t	mode;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1770
	uint64_t	uid;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1771
	uint64_t	gid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1772
	int		error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1773
	int		pull_down;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1774
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1775
	zfs_acl_t	*aclp = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1776
	zfs_acl_t	*paclp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1777
	xvattr_t	*xvap = (xvattr_t *)vap;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1778
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1779
	if (setaclp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1780
		aclp = setaclp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1781
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1782
	mode = MAKEIMODE(vap->va_type, vap->va_mode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1783
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1784
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1785
	 * Determine uid and gid.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1786
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1787
	if ((flag & (IS_ROOT_NODE | IS_REPLAY)) ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1788
	    ((flag & IS_XATTR) && (vap->va_type == VDIR))) {
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1789
		uid = zfs_fuid_create(zfsvfs, vap->va_uid, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1790
		    ZFS_OWNER, tx, fuidp);
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1791
		gid = zfs_fuid_create(zfsvfs, vap->va_gid, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1792
		    ZFS_GROUP, tx, fuidp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1793
	} else {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1794
		uid = zfs_fuid_create_cred(zfsvfs, crgetuid(cr),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1795
		    ZFS_OWNER, tx, cr, fuidp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1796
		if ((vap->va_mask & AT_GID) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1797
		    ((vap->va_gid == parent->z_phys->zp_gid) ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1798
		    groupmember(vap->va_gid, cr) ||
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1799
		    secpolicy_vnode_create_gid(cr) == 0)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1800
			gid = zfs_fuid_create_cred(zfsvfs, vap->va_gid,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1801
			    ZFS_GROUP, tx, cr, fuidp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1802
		} else {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1803
			gid = (parent->z_phys->zp_mode & S_ISGID) ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1804
			    parent->z_phys->zp_gid : crgetgid(cr);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1805
			gid = zfs_fuid_create_cred(zfsvfs, gid,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1806
			    ZFS_GROUP, tx, cr, fuidp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1807
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1808
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1809
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1810
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1811
	 * If we're creating a directory, and the parent directory has the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1812
	 * set-GID bit set, set in on the new directory.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1813
	 * Otherwise, if the user is neither privileged nor a member of the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1814
	 * file's new group, clear the file's set-GID bit.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1815
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1816
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1817
	if ((parent->z_phys->zp_mode & S_ISGID) && (vap->va_type == VDIR))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1818
		mode |= S_ISGID;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1819
	else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1820
		if ((mode & S_ISGID) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1821
		    secpolicy_vnode_setids_setgids(cr, gid) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1822
			mode &= ~S_ISGID;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1823
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1824
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1825
	zp->z_phys->zp_uid = uid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1826
	zp->z_phys->zp_gid = gid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1827
	zp->z_phys->zp_mode = mode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1828
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1829
	if (aclp == NULL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1830
		mutex_enter(&parent->z_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1831
		pull_down = (parent->z_phys->zp_flags & ZFS_INHERIT_ACE);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1832
		if (pull_down) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1833
			mutex_enter(&parent->z_acl_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1834
			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
  1835
			mutex_exit(&parent->z_acl_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1836
			aclp = zfs_acl_inherit(zp, paclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1837
			zfs_acl_free(paclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1838
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1839
			aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1840
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1841
		mutex_exit(&parent->z_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1842
		mutex_enter(&zp->z_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1843
		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
  1844
		zfs_acl_chmod(zp, mode, aclp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1845
	} else {
5331
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);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1848
	}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1849
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1850
	/* Force auto_inherit on all new directory objects */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1851
	if (vap->va_type == VDIR)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1852
		aclp->z_hints |= ZFS_ACL_AUTO_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1853
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1854
	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
  1855
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1856
	/* Set optional attributes if any */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1857
	if (vap->va_mask & AT_XVATTR)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1858
		zfs_xvattr_set(zp, xvap);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1859
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1860
	mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1861
	mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1862
	ASSERT3U(error, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1863
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1864
	if (aclp != setaclp) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1865
		zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1866
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1867
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1868
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1869
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1870
 * Retrieve a files ACL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1871
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1872
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1873
zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1874
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1875
	zfs_acl_t	*aclp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1876
	ulong_t		mask;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1877
	int		error;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1878
	int 		count = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1879
	int		largeace = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1880
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1881
	mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT |
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1882
	    VSA_ACE_ACLFLAGS | VSA_ACE_ALLTYPES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1883
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1884
	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
  1885
		return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1886
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1887
	if (mask == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1888
		return (ENOSYS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1889
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1890
	mutex_enter(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1891
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1892
	error = zfs_acl_node_read(zp, &aclp, B_FALSE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1893
	if (error != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1894
		mutex_exit(&zp->z_acl_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1895
		return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1896
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  1897
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1898
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1899
	 * Scan ACL to determine number of ACEs
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1900
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1901
	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
  1902
	    !(mask & VSA_ACE_ALLTYPES)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1903
		void *zacep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1904
		uint64_t who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1905
		uint32_t access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1906
		uint16_t type, iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1907
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1908
		while (zacep = zfs_acl_next_ace(aclp, zacep,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1909
		    &who, &access_mask, &iflags, &type)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1910
			switch (type) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1911
			case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1912
			case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1913
			case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1914
			case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1915
				largeace++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1916
				continue;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1917
			default:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1918
				count++;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1919
			}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1920
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1921
		vsecp->vsa_aclcnt = count;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1922
	} else
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1923
		count = aclp->z_acl_count;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1924
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1925
	if (mask & VSA_ACECNT) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1926
		vsecp->vsa_aclcnt = count;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1927
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1928
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1929
	if (mask & VSA_ACE) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1930
		size_t aclsz;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1931
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1932
		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
  1933
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1934
		aclsz = count * sizeof (ace_t) +
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1935
		    sizeof (ace_object_t) * largeace;
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
		vsecp->vsa_aclentp = kmem_alloc(aclsz, KM_SLEEP);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1938
		vsecp->vsa_aclentsz = aclsz;
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
		if (aclp->z_version == ZFS_ACL_VERSION_FUID)
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  1941
			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
  1942
			    vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1943
		else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1944
			bcopy(aclnode->z_acldata, vsecp->vsa_aclentp,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1945
			    count * sizeof (ace_t));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1946
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1947
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1948
	if (mask & VSA_ACE_ACLFLAGS) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1949
		vsecp->vsa_aclflags = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1950
		if (zp->z_phys->zp_flags & ZFS_ACL_DEFAULTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1951
			vsecp->vsa_aclflags |= ACL_DEFAULTED;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1952
		if (zp->z_phys->zp_flags & ZFS_ACL_PROTECTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1953
			vsecp->vsa_aclflags |= ACL_PROTECTED;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1954
		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
  1955
			vsecp->vsa_aclflags |= ACL_AUTO_INHERIT;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1956
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1957
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1958
	mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1959
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1960
	zfs_acl_free(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1961
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1962
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1963
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1964
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1965
int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1966
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
  1967
    vsecattr_t *vsecp, zfs_acl_t **zaclp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1968
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1969
	zfs_acl_t *aclp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1970
	zfs_acl_node_t *aclnode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1971
	int aclcnt = vsecp->vsa_aclcnt;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1972
	int error;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1973
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1974
	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
  1975
		return (EINVAL);
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
	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
  1978
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1979
	aclp->z_hints = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1980
	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
  1981
	if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1982
		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
  1983
		    (ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1984
		    aclcnt, &aclnode->z_size)) != 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1985
			zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1986
			zfs_acl_node_free(aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1987
			return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1988
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1989
	} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1990
		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
  1991
		    vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1992
		    &aclnode->z_size)) != 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1993
			zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1994
			zfs_acl_node_free(aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1995
			return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1996
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1997
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1998
	aclp->z_acl_bytes = aclnode->z_size;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  1999
	aclnode->z_ace_count = aclcnt;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2000
	aclp->z_acl_count = aclcnt;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2001
	list_insert_head(&aclp->z_acl, aclnode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2002
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2003
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2004
	 * 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
  2005
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2006
	if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2007
		if (vsecp->vsa_aclflags & ACL_PROTECTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2008
			aclp->z_hints |= ZFS_ACL_PROTECTED;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2009
		if (vsecp->vsa_aclflags & ACL_DEFAULTED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2010
			aclp->z_hints |= ZFS_ACL_DEFAULTED;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2011
		if (vsecp->vsa_aclflags & ACL_AUTO_INHERIT)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2012
			aclp->z_hints |= ZFS_ACL_AUTO_INHERIT;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2013
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2014
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2015
	*zaclp = aclp;
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
	return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2018
}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2019
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2020
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2021
 * Set a files ACL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2022
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2023
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2024
zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2025
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2026
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2027
	zilog_t		*zilog = zfsvfs->z_log;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2028
	ulong_t		mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2029
	dmu_tx_t	*tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2030
	int		error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2031
	zfs_acl_t	*aclp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2032
	zfs_fuid_info_t	*fuidp = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2033
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2034
	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
  2035
		return (ENOSYS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2036
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2037
	if (zp->z_phys->zp_flags & ZFS_IMMUTABLE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2038
		return (EPERM);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2039
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2040
	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
  2041
		return (error);
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
	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
  2044
	if (error)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2045
		return (error);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2046
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2047
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2048
	 * 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
  2049
	 * existing flags.
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 (!(vsecp->vsa_mask & VSA_ACE_ACLFLAGS)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2052
		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
  2053
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2054
top:
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2055
	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
  2056
		zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2057
		return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2058
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2059
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2060
	mutex_enter(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2061
	mutex_enter(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2062
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2063
	tx = dmu_tx_create(zfsvfs->z_os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2064
	dmu_tx_hold_bonus(tx, zp->z_id);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2065
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2066
	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
  2067
		/* Are we upgrading ACL? */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2068
		if (zfsvfs->z_version <= ZPL_VERSION_FUID &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2069
		    zp->z_phys->zp_acl.z_acl_version ==
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2070
		    ZFS_ACL_VERSION_INITIAL) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2071
			dmu_tx_hold_free(tx,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2072
			    zp->z_phys->zp_acl.z_acl_extern_obj,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2073
			    0, DMU_OBJECT_END);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2074
			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
  2075
			    0, aclp->z_acl_bytes);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2076
		} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2077
			dmu_tx_hold_write(tx,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2078
			    zp->z_phys->zp_acl.z_acl_extern_obj,
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2079
			    0, aclp->z_acl_bytes);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2080
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2081
	} else if (aclp->z_acl_bytes > ZFS_ACE_SPACE) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2082
		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
  2083
	}
5824
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2084
	if (aclp->z_has_fuids) {
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2085
		if (zfsvfs->z_fuid_obj == 0) {
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2086
			dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2087
			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
  2088
			    FUID_SIZE_ESTIMATE(zfsvfs));
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2089
			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
  2090
		} else {
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2091
			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
  2092
			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
  2093
			    FUID_SIZE_ESTIMATE(zfsvfs));
1d2d522d19b5 6603908 can't change mode if FS/dir is out of quota
marks
parents: 5771
diff changeset
  2094
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2095
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2096
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2097
	error = dmu_tx_assign(tx, zfsvfs->z_assign);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2098
	if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2099
		mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2100
		mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2101
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2102
		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2058
diff changeset
  2103
			dmu_tx_wait(tx);
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2058
diff changeset
  2104
			dmu_tx_abort(tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2105
			goto top;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2106
		}
2113
0510bb40c993 6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents: 2058
diff changeset
  2107
		dmu_tx_abort(tx);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2108
		zfs_acl_free(aclp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2109
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2110
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2111
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  2112
	error = zfs_aclset_common(zp, aclp, cr, &fuidp, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2113
	ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2114
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2115
	zfs_log_acl(zilog, tx, zp, vsecp, fuidp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2116
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2117
	if (fuidp)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2118
		zfs_fuid_info_free(fuidp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2119
	zfs_acl_free(aclp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2120
	dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2121
done:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2122
	mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2123
	mutex_exit(&zp->z_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2124
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2125
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2126
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2127
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2128
/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2129
 * working_mode returns the permissions that were not granted
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2130
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2131
static int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2132
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
  2133
    boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2134
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2135
	zfs_acl_t	*aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2136
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2137
	int		error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2138
	int		access_deny = ACCESS_UNDETERMINED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2139
	uid_t		uid = crgetuid(cr);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2140
	uint64_t 	who;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2141
	uint16_t	type, iflags;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2142
	uint16_t	entry_type;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2143
	uint32_t	access_mask;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2144
	zfs_ace_hdr_t	*acep = NULL;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2145
	boolean_t	checkit;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2146
	uid_t		fowner;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2147
	uid_t		gowner;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2148
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2149
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2150
	 * Short circuit empty requests
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
	if (v4_mode == 0)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2153
		return (0);
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
	*check_privs = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2156
2638
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2604
diff changeset
  2157
	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
  2158
		*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
  2159
		return (0);
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2604
diff changeset
  2160
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2161
2638
4f583dfeae92 6413510 zfs: writing to ZFS filesystem slows down fsync() on other files in the same FS
perrin
parents: 2604
diff changeset
  2162
	*working_mode = v4_mode;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2164
	if ((v4_mode & WRITE_MASK) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2165
	    (zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2166
	    (!IS_DEVVP(ZTOV(zp)))) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2167
		*check_privs = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2168
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2169
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2170
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2171
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2172
	 * Only check for READONLY on non-directories.
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2173
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2174
	if ((v4_mode & WRITE_MASK_DATA) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2175
	    (((ZTOV(zp)->v_type != VDIR) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2176
	    (zp->z_phys->zp_flags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2177
	    (ZTOV(zp)->v_type == VDIR &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2178
	    (zp->z_phys->zp_flags & ZFS_IMMUTABLE)))) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2179
		*check_privs = B_FALSE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2180
		return (EPERM);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2181
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2182
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2183
	if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2184
	    (zp->z_phys->zp_flags & ZFS_NOUNLINK)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2185
		*check_privs = B_FALSE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2186
		return (EPERM);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2187
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2188
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2189
	if (((v4_mode & (ACE_READ_DATA|ACE_EXECUTE)) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2190
	    (zp->z_phys->zp_flags & ZFS_AV_QUARANTINED))) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2191
		*check_privs = B_FALSE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2192
		return (EACCES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2193
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2194
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2195
	/*
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2196
	 * 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
  2197
	 * 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
  2198
	 * 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
  2199
	 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2200
	if (skipaclchk) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2201
		*working_mode = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2202
		return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2203
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2204
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  2205
	zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2206
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2207
	mutex_enter(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2208
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2209
	error = zfs_acl_node_read(zp, &aclp, B_FALSE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2210
	if (error != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2211
		mutex_exit(&zp->z_acl_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2212
		return (error);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2213
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1308
diff changeset
  2214
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2215
	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
  2216
	    &iflags, &type)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2217
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2218
		if (iflags & ACE_INHERIT_ONLY_ACE)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2219
			continue;
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
		entry_type = (iflags & ACE_TYPE_FLAGS);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2222
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2223
		checkit = B_FALSE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2224
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2225
		switch (entry_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2226
		case ACE_OWNER:
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2227
			if (uid == fowner)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2228
				checkit = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2229
			break;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2230
		case OWNING_GROUP:
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2231
			who = gowner;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2232
			/*FALLTHROUGH*/
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2233
		case ACE_IDENTIFIER_GROUP:
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2234
			checkit = zfs_groupmember(zfsvfs, who, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2235
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2236
		case ACE_EVERYONE:
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2237
			checkit = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2238
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2239
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2240
		/* USER Entry */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2241
		default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2242
			if (entry_type == 0) {
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2243
				uid_t newid;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2244
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  2245
				zfs_fuid_map_id(zfsvfs, who, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2246
				    ZFS_ACE_USER, &newid);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2247
				if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2248
				    uid == newid)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2249
					checkit = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2250
				break;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2251
			} else {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2252
				zfs_acl_free(aclp);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2253
				mutex_exit(&zp->z_acl_lock);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2254
				return (EIO);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2255
			}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2256
		}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2257
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2258
		if (checkit) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2259
			if (access_mask & *working_mode) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2260
				if (type == ALLOW) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2261
					*working_mode &=
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2262
					    ~(*working_mode & access_mask);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2263
					if (*working_mode == 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2264
						access_deny = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2265
					}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2266
				} else if (type == DENY) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2267
					access_deny = EACCES;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2268
				}
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
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2272
		if (access_deny != ACCESS_UNDETERMINED)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2273
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2274
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2275
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2276
	mutex_exit(&zp->z_acl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2277
	zfs_acl_free(aclp);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2278
out:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2279
	return (access_deny);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2280
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2281
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2282
static int
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2283
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
  2284
    cred_t *cr)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2285
{
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2286
	if (*working_mode != ACE_WRITE_DATA)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2287
		return (EACCES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2288
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2289
	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
  2290
	    check_privs, B_FALSE, cr));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2291
}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2292
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2293
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2294
 * Determine whether Access should be granted/denied, invoking least
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2295
 * priv subsytem when a deny is determined.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2296
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2297
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2298
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
  2299
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2300
	uint32_t	working_mode;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2301
	int		error;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2302
	int		is_attr;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2303
	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2304
	boolean_t 	check_privs;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2305
	znode_t		*xzp;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2306
	znode_t 	*check_zp = zp;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2307
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2308
	is_attr = ((zp->z_phys->zp_flags & ZFS_XATTR) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2309
	    (ZTOV(zp)->v_type == VDIR));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2310
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2311
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2312
	 * If attribute then validate against base file
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2313
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2314
	if (is_attr) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2315
		if ((error = zfs_zget(zp->z_zfsvfs,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2316
		    zp->z_phys->zp_parent, &xzp)) != 0)	{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2317
			return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2318
		}
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2319
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2320
		check_zp = xzp;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2321
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2322
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2323
		 * fixup mode to map to xattr perms
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2324
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2325
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2326
		if (mode & (ACE_WRITE_DATA|ACE_APPEND_DATA)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2327
			mode &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2328
			mode |= ACE_WRITE_NAMED_ATTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2329
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2330
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2331
		if (mode & (ACE_READ_DATA|ACE_EXECUTE)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2332
			mode &= ~(ACE_READ_DATA|ACE_EXECUTE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2333
			mode |= ACE_READ_NAMED_ATTRS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2334
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2335
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2336
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2337
	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
  2338
	    &check_privs, skipaclchk, cr)) == 0) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2339
		if (is_attr)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2340
			VN_RELE(ZTOV(xzp));
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2341
		return (0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2342
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2343
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2344
	if (error && check_privs == B_FALSE) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2345
		if (is_attr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2346
			VN_RELE(ZTOV(xzp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2347
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2348
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2349
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2350
	if (error && (flags & V_APPEND)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2351
		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
  2352
	}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2353
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2354
	if (error && check_privs) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2355
		uid_t		owner;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2356
		mode_t		checkmode = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2357
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  2358
		zfs_fuid_map_id(zfsvfs, check_zp->z_phys->zp_uid, cr,
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2359
		    ZFS_OWNER, &owner);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2360
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
		 * First check for implicit owner permission on
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2363
		 * read_acl/read_attributes
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2364
		 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2365
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2366
		error = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2367
		ASSERT(working_mode != 0);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2368
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2369
		if ((working_mode & (ACE_READ_ACL|ACE_READ_ATTRIBUTES) &&
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2370
		    owner == crgetuid(cr)))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2371
			working_mode &= ~(ACE_READ_ACL|ACE_READ_ATTRIBUTES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2372
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2373
		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
  2374
		    ACE_READ_ACL|ACE_READ_ATTRIBUTES))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2375
			checkmode |= VREAD;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2376
		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
  2377
		    ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2378
			checkmode |= VWRITE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2379
		if (working_mode & ACE_EXECUTE)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2380
			checkmode |= VEXEC;
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 (checkmode)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2383
			error = secpolicy_vnode_access(cr, ZTOV(check_zp),
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2384
			    owner, checkmode);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2385
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2386
		if (error == 0 && (working_mode & ACE_WRITE_OWNER))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2387
			error = secpolicy_vnode_create_gid(cr);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2388
		if (error == 0 && (working_mode & ACE_WRITE_ACL))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2389
			error = secpolicy_vnode_setdac(cr, owner);
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 (error == 0 && (working_mode &
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2392
		    (ACE_DELETE|ACE_DELETE_CHILD)))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2393
			error = secpolicy_vnode_remove(cr);
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_SYNCHRONIZE))
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2396
			error = secpolicy_vnode_owner(cr, owner);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2397
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2398
		if (error == 0) {
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
			 * See if any bits other than those already checked
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2401
			 * for are still present.  If so then return EACCES
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2402
			 */
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2403
			if (working_mode & ~(ZFS_CHECKED_MASKS)) {
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2404
				error = EACCES;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2405
			}
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2406
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2407
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2408
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2409
	if (is_attr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2410
		VN_RELE(ZTOV(xzp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2411
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2412
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2413
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2414
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2415
/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2416
 * Translate traditional unix VREAD/VWRITE/VEXEC mode into
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2417
 * native ACL format and call zfs_zaccess()
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2418
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2419
int
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2420
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2421
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2422
	return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2423
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2424
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2425
/*
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2426
 * Access function for secpolicy_vnode_setattr
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_unix(znode_t *zp, mode_t mode, cred_t *cr)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2430
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2431
	int v4_mode = zfs_unix_to_v4(mode >> 6);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2432
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2433
	return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2434
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2435
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2436
static int
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2437
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
  2438
{
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2439
	int error;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2440
	uid_t downer;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2441
	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2442
5771
7ba3a2c57d6a 6552639 Each zone should have it's own idmapd
jp151216
parents: 5762
diff changeset
  2443
	zfs_fuid_map_id(zfsvfs, dzp->z_phys->zp_uid, cr, ZFS_OWNER, &downer);
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2444
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2445
	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
  2446
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2447
	if (error == 0)
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2448
		error = zfs_sticky_remove_access(dzp, zp, cr);
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2449
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2450
	return (error);
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2451
}
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2452
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2453
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2454
 * Determine whether Access should be granted/deny, without
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2455
 * consulting least priv subsystem.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2456
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2457
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2458
 * The following chart is the recommended NFSv4 enforcement for
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2459
 * ability to delete an object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2460
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2461
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2462
 *      |   Parent Dir  |           Target Object Permissions |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2463
 *      |  permissions  |                                     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2464
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2465
 *      |               | ACL Allows | ACL Denies| Delete     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2466
 *      |               |  Delete    |  Delete   | unspecified|
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2467
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2468
 *      |  ACL Allows   | Permit     | Permit    | Permit     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2469
 *      |  DELETE_CHILD |                                     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2470
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2471
 *      |  ACL Denies   | Permit     | Deny      | Deny       |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2472
 *      |  DELETE_CHILD |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2473
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2474
 *      | ACL specifies |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2475
 *      | only allow    | Permit     | Permit    | Permit     |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2476
 *      | write and     |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2477
 *      | execute       |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2478
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2479
 *      | ACL denies    |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2480
 *      | write and     | Permit     | Deny      | Deny       |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2481
 *      | execute       |            |           |            |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2482
 *      -------------------------------------------------------
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2483
 *         ^
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2484
 *         |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2485
 *         No search privilege, can't even look up file?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2486
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2487
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2488
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2489
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2490
{
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2491
	uint32_t dzp_working_mode = 0;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2492
	uint32_t zp_working_mode = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2493
	int dzp_error, zp_error;
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2494
	boolean_t dzpcheck_privs = B_TRUE;
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2495
	boolean_t zpcheck_privs = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2496
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2497
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2498
	 * Arghh, this check is going to require a couple of questions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2499
	 * to be asked.  We want specific DELETE permissions to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2500
	 * take precedence over WRITE/EXECUTE.  We don't
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2501
	 * 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
  2502
	 * user:joe:write_data:deny,user:joe:delete:allow
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2503
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2504
	 * However, deny permissions may ultimately be overridden
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2505
	 * by secpolicy_vnode_access().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2506
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2507
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2508
	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
  2509
		return (EPERM);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2510
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2511
	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
  2512
	    &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2513
	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
  2514
	    &zpcheck_privs, B_FALSE, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2515
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2516
	if ((dzp_error && dzpcheck_privs == B_FALSE) ||
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2517
	    (zp_error && zpcheck_privs == B_FALSE))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2518
		return (dzp_error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2519
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2520
	/*
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2521
	 * First check the first row.
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2522
	 * We only need to see if parent Allows delete_child
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2523
	 */
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2524
	if ((dzp_working_mode & ACE_DELETE_CHILD) == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2525
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2526
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2527
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2528
	 * Second row
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2529
	 * we already have the necessary information in
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2530
	 * zp_working_mode, zp_error and dzp_error.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2531
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2532
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2533
	if ((zp_working_mode & ACE_DELETE) == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2534
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2535
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2536
	/*
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2537
	 * Now zp_error should either be EACCES which indicates
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2538
	 * a "deny" delete entry or ACCESS_UNDETERMINED if the "delete"
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2539
	 * entry exists on the target.
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2540
	 *
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2541
	 * dzp_error should be either EACCES which indicates a "deny"
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2542
	 * 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
  2543
	 * entry exists.  If value is EACCES then we are done
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2544
	 * and zfs_delete_final_check() will make the final decision
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2545
	 * regarding to allow the delete.
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2546
	 */
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2547
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2548
	ASSERT(zp_error != 0 && dzp_error != 0);
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2549
	if (dzp_error == EACCES)
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2550
		return (zfs_delete_final_check(zp, dzp, cr));
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2551
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2552
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2553
	 * Third Row
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2554
	 * Only need to check for write/execute on parent
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2555
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2556
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2557
	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
  2558
	    &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2559
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2560
	if (dzp_error && dzpcheck_privs == B_FALSE)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2561
		return (dzp_error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2562
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2563
	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
  2564
		return (zfs_sticky_remove_access(dzp, zp, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2565
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2566
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2567
	 * Fourth Row
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2568
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2569
1576
0364d1928a7f 6380036 zfs does not clear S_ISUID and S_ISGID bits on successful writes
marks
parents: 1544
diff changeset
  2570
	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
  2571
	    ((zp_working_mode & ACE_DELETE) == 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
2604
b2fb13f56fe7 6461609 zfs delete permissions are not working correctly
marks
parents: 2113
diff changeset
  2574
	return (zfs_delete_final_check(zp, dzp, cr));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2575
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2576
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2577
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2578
zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2579
    znode_t *tzp, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2580
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2581
	int add_perm;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2582
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2583
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2584
	if (szp->z_phys->zp_flags & ZFS_AV_QUARANTINED)
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2585
		return (EACCES);
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2586
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2587
	add_perm = (ZTOV(szp)->v_type == VDIR) ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2588
	    ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2589
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2590
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2591
	 * Rename permissions are combination of delete permission +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2592
	 * add file/subdir permission.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2593
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2594
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2595
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2596
	 * first make sure we do the delete portion.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2597
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2598
	 * If that succeeds then check for add_file/add_subdir permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2599
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2600
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2601
	if (error = zfs_zaccess_delete(sdzp, szp, cr))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2602
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2603
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2604
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2605
	 * If we have a tzp, see if we can delete it?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2606
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2607
	if (tzp) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2608
		if (error = zfs_zaccess_delete(tdzp, tzp, cr))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2609
			return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2610
	}
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
	 * Now check for add permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2614
	 */
5331
3047ad28a67b PSARC/2007/218 caller_context_t in all VOPs
amw
parents: 4869
diff changeset
  2615
	error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2616
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2617
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2618
}