zfs_acl.c revision f1696b231bb1209e1cea95b7ff29b8c60493daa0
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License (the "License").
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You may not use this file except in compliance with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MAX_ACE_TYPE ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define ZFS_CHECKED_MASKS (ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_DATA| \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ACE_READ_NAMED_ATTRS|ACE_WRITE_DATA|ACE_WRITE_ATTRIBUTES| \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ACE_WRITE_NAMED_ATTRS|ACE_APPEND_DATA|ACE_EXECUTE|ACE_WRITE_OWNER| \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ACE_WRITE_ACL|ACE_DELETE|ACE_DELETE_CHILD|ACE_SYNCHRONIZE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define WRITE_MASK_DATA (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define WRITE_MASK_ATTRS (ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES| \
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define OGE_CLEAR (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define ALL_INHERIT (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE|ACE_INHERITED_ACE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define RESTRICTED_CLEAR (ACE_WRITE_ACL|ACE_WRITE_OWNER)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define V4_ACL_WIDE_FLAGS (ZFS_ACL_AUTO_INHERIT|ZFS_ACL_DEFAULTED|\
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define ZFS_ACL_WIDE_FLAGS (V4_ACL_WIDE_FLAGS|ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE|\
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (sizeof (zfs_oldace_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (sizeof (zfs_oldace_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED*/
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
static uint16_t
static uint32_t
static uint64_t
static size_t
return (sizeof (zfs_object_ace_t));
case ALLOW:
case DENY:
return (sizeof (zfs_ace_hdr_t));
return (sizeof (zfs_ace_t));
static size_t
return (sizeof (zfs_ace_hdr_t));
zfs_ace_fuid_mask_off(void)
int error;
int size;
int error;
&size)) != 0)
return (error);
return (error);
return (error);
return (ZFS_ACL_VERSION_FUID);
int error;
return (ZFS_ACL_VERSION_FUID);
return (ZFS_ACL_VERSION_INITIAL);
return (ZFS_ACL_VERSION_FUID);
return (aclp);
if (bytes) {
return (aclnode);
static boolean_t
switch (type) {
case ALLOW:
case DENY:
return (B_TRUE);
return (B_FALSE);
static boolean_t
return (B_FALSE);
switch (type) {
return (B_FALSE);
ACE_DIRECTORY_INHERIT_ACE)) == 0) {
return (B_FALSE);
return (B_TRUE);
return (NULL);
return (NULL);
return (NULL);
return (NULL);
return ((void *)acep);
return (NULL);
static uint64_t
static zfs_acl_node_t *
for (i = 0; i != aclcnt; i++) {
return (EINVAL);
switch (type) {
if (filter) {
return (EINVAL);
KM_SLEEP);
sizeof (zfs_object_ace_t));
static uint32_t
return (new_mask);
int entry_type;
if (!an_exec_denied &&
if (an_exec_denied)
return (mode);
int aclsize;
int acl_count;
int version;
int error;
goto done;
if (error != 0) {
goto done;
if (!will_modify)
done:
if (drop_lock)
return (error);
if (start) {
int error;
return (error);
int error;
int count = 0;
return (error);
if (aoid &&
if (error)
return (error);
aoid = 0;
if (aoid == 0) {
if (error)
return (error);
int user_ace;
int ace_size;
int entry_type;
void *zacep;
if (allow0) {
new_count++;
} if (deny1) {
new_count++;
if (deny2) {
new_count++;
if (inherit_flags)
switch (type) {
access_mask &=
access_mask &=
new_count++;
static zfs_acl_t *
void *pacep;
void *acep;
noallow =
return (aclp);
if (passthrough &&
if (vdir)
return (aclp);
int error;
if (vsecp)
return (error);
char *domain;
if (need_chmod) {
ZFS_ACL_AUTO_INHERIT : 0;
int error;
int count = 0;
int largeace = 0;
if (mask == 0)
return (ENOSYS);
return (error);
if (error != 0) {
return (error);
switch (type) {
largeace++;
count++;
int error;
return (EINVAL);
return (error);
return (error);
int error;
if (mask == 0)
return (ENOSYS);
return (EPERM);
return (error);
&aclp);
if (error)
return (error);
top:
if (fuid_dirtied)
if (error) {
goto top;
return (error);
if (fuid_dirtied)
if (fuidp)
done:
return (error);
return (EROFS);
return (EPERM);
return (EPERM);
return (EACCES);
int error;
if (error != 0) {
return (error);
if (!mask_matched)
switch (entry_type) {
case ACE_OWNER:
case OWNING_GROUP:
case ACE_IDENTIFIER_GROUP:
case ACE_EVERYONE:
if (entry_type == 0) {
return (EIO);
if (checkit) {
if (anyaccess) {
if (*working_mode == 0)
if (deny_mask) {
return (EACCES);
} else if (*working_mode) {
return (B_TRUE);
int err;
*working_mode = 0;
return (err);
if (skipaclchk) {
*working_mode = 0;
return (EACCES);
int error;
return (EACCES);
if (is_attr)
goto slow;
goto slow;
goto slow;
goto slow;
slow:
return (error);
int error;
int is_attr;
if (is_attr) {
sizeof (parent))) != 0)
return (error);
return (error);
needed_bits = 0;
if (is_attr)
if (is_attr)
return (error);
error = 0;
if (error == 0) {
} else if (error == 0) {
if (is_attr)
return (error);
int error;
if (error == 0)
return (error);
return (EPERM);
if (!dzpcheck_privs)
return (dzp_error);
if (!zpcheck_privs)
return (zp_error);
return (dzp_error);
int add_perm;
int error;
return (EACCES);
* If that succeeds then check for add_file/add_subdir permissions
return (error);
if (tzp) {
return (error);
return (error);