svn commit: r237927 - in vendor/illumos/dist: common/acl
common/atomic common/atomic/amd64 common/atomic/i386
common/atomic/sparc common/nvpair common/unicode common/zfs
uts uts/common uts/common/c...
Martin Matuska
mm at FreeBSD.org
Sun Jul 1 14:55:36 UTC 2012
Author: mm
Date: Sun Jul 1 14:55:35 2012
New Revision: 237927
URL: http://svn.freebsd.org/changeset/base/237927
Log:
Add kernel part (uts) with ZFS to vendor/illumos
illumos-gate revision 13742:b6bbdd77139c
Added:
vendor/illumos/dist/common/acl/
vendor/illumos/dist/common/acl/acl_common.c
vendor/illumos/dist/common/acl/acl_common.h
vendor/illumos/dist/common/atomic/
vendor/illumos/dist/common/atomic/amd64/
vendor/illumos/dist/common/atomic/amd64/atomic.s
vendor/illumos/dist/common/atomic/i386/
vendor/illumos/dist/common/atomic/i386/atomic.s
vendor/illumos/dist/common/atomic/sparc/
vendor/illumos/dist/common/atomic/sparc/atomic.s
vendor/illumos/dist/common/nvpair/
vendor/illumos/dist/common/nvpair/fnvpair.c
vendor/illumos/dist/common/nvpair/nvpair.c
vendor/illumos/dist/common/nvpair/nvpair_alloc_fixed.c
vendor/illumos/dist/common/unicode/
vendor/illumos/dist/common/unicode/u8_textprep.c
vendor/illumos/dist/common/zfs/
vendor/illumos/dist/common/zfs/zfeature_common.c
vendor/illumos/dist/common/zfs/zfeature_common.h
vendor/illumos/dist/common/zfs/zfs_comutil.c
vendor/illumos/dist/common/zfs/zfs_comutil.h
vendor/illumos/dist/common/zfs/zfs_deleg.c
vendor/illumos/dist/common/zfs/zfs_deleg.h
vendor/illumos/dist/common/zfs/zfs_fletcher.c
vendor/illumos/dist/common/zfs/zfs_fletcher.h
vendor/illumos/dist/common/zfs/zfs_namecheck.c
vendor/illumos/dist/common/zfs/zfs_namecheck.h
vendor/illumos/dist/common/zfs/zfs_prop.c
vendor/illumos/dist/common/zfs/zfs_prop.h
vendor/illumos/dist/common/zfs/zpool_prop.c
vendor/illumos/dist/common/zfs/zprop_common.c
vendor/illumos/dist/uts/
vendor/illumos/dist/uts/common/
vendor/illumos/dist/uts/common/Makefile.files
vendor/illumos/dist/uts/common/ctf/
vendor/illumos/dist/uts/common/ctf/ctf_mod.c
vendor/illumos/dist/uts/common/ctf/ctf_subr.c
vendor/illumos/dist/uts/common/dtrace/
vendor/illumos/dist/uts/common/dtrace/dcpc.c
vendor/illumos/dist/uts/common/dtrace/dtrace.c
vendor/illumos/dist/uts/common/dtrace/fasttrap.c
vendor/illumos/dist/uts/common/dtrace/lockstat.c
vendor/illumos/dist/uts/common/dtrace/profile.c
vendor/illumos/dist/uts/common/dtrace/sdt_subr.c
vendor/illumos/dist/uts/common/dtrace/systrace.c
vendor/illumos/dist/uts/common/fs/
vendor/illumos/dist/uts/common/fs/gfs.c
vendor/illumos/dist/uts/common/fs/vnode.c
vendor/illumos/dist/uts/common/fs/zfs/
vendor/illumos/dist/uts/common/fs/zfs/arc.c
vendor/illumos/dist/uts/common/fs/zfs/bplist.c
vendor/illumos/dist/uts/common/fs/zfs/bpobj.c
vendor/illumos/dist/uts/common/fs/zfs/bptree.c
vendor/illumos/dist/uts/common/fs/zfs/dbuf.c
vendor/illumos/dist/uts/common/fs/zfs/ddt.c
vendor/illumos/dist/uts/common/fs/zfs/ddt_zap.c
vendor/illumos/dist/uts/common/fs/zfs/dmu.c
vendor/illumos/dist/uts/common/fs/zfs/dmu_diff.c
vendor/illumos/dist/uts/common/fs/zfs/dmu_object.c
vendor/illumos/dist/uts/common/fs/zfs/dmu_objset.c
vendor/illumos/dist/uts/common/fs/zfs/dmu_send.c
vendor/illumos/dist/uts/common/fs/zfs/dmu_traverse.c
vendor/illumos/dist/uts/common/fs/zfs/dmu_tx.c
vendor/illumos/dist/uts/common/fs/zfs/dmu_zfetch.c
vendor/illumos/dist/uts/common/fs/zfs/dnode.c
vendor/illumos/dist/uts/common/fs/zfs/dnode_sync.c
vendor/illumos/dist/uts/common/fs/zfs/dsl_dataset.c
vendor/illumos/dist/uts/common/fs/zfs/dsl_deadlist.c
vendor/illumos/dist/uts/common/fs/zfs/dsl_deleg.c
vendor/illumos/dist/uts/common/fs/zfs/dsl_dir.c
vendor/illumos/dist/uts/common/fs/zfs/dsl_pool.c
vendor/illumos/dist/uts/common/fs/zfs/dsl_prop.c
vendor/illumos/dist/uts/common/fs/zfs/dsl_scan.c
vendor/illumos/dist/uts/common/fs/zfs/dsl_synctask.c
vendor/illumos/dist/uts/common/fs/zfs/gzip.c
vendor/illumos/dist/uts/common/fs/zfs/lzjb.c
vendor/illumos/dist/uts/common/fs/zfs/metaslab.c
vendor/illumos/dist/uts/common/fs/zfs/refcount.c
vendor/illumos/dist/uts/common/fs/zfs/rrwlock.c
vendor/illumos/dist/uts/common/fs/zfs/sa.c
vendor/illumos/dist/uts/common/fs/zfs/sha256.c
vendor/illumos/dist/uts/common/fs/zfs/spa.c
vendor/illumos/dist/uts/common/fs/zfs/spa_config.c
vendor/illumos/dist/uts/common/fs/zfs/spa_errlog.c
vendor/illumos/dist/uts/common/fs/zfs/spa_history.c
vendor/illumos/dist/uts/common/fs/zfs/spa_misc.c
vendor/illumos/dist/uts/common/fs/zfs/space_map.c
vendor/illumos/dist/uts/common/fs/zfs/sys/
vendor/illumos/dist/uts/common/fs/zfs/sys/arc.h
vendor/illumos/dist/uts/common/fs/zfs/sys/bplist.h
vendor/illumos/dist/uts/common/fs/zfs/sys/bpobj.h
vendor/illumos/dist/uts/common/fs/zfs/sys/bptree.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dbuf.h
vendor/illumos/dist/uts/common/fs/zfs/sys/ddt.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dmu.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dmu_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dmu_objset.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dmu_traverse.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dmu_tx.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dmu_zfetch.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dnode.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dsl_deadlist.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dsl_deleg.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dsl_dir.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dsl_pool.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dsl_prop.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dsl_scan.h
vendor/illumos/dist/uts/common/fs/zfs/sys/dsl_synctask.h
vendor/illumos/dist/uts/common/fs/zfs/sys/metaslab.h
vendor/illumos/dist/uts/common/fs/zfs/sys/metaslab_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/refcount.h
vendor/illumos/dist/uts/common/fs/zfs/sys/rrwlock.h
vendor/illumos/dist/uts/common/fs/zfs/sys/sa.h
vendor/illumos/dist/uts/common/fs/zfs/sys/sa_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/spa.h
vendor/illumos/dist/uts/common/fs/zfs/sys/spa_boot.h
vendor/illumos/dist/uts/common/fs/zfs/sys/spa_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/space_map.h
vendor/illumos/dist/uts/common/fs/zfs/sys/txg.h
vendor/illumos/dist/uts/common/fs/zfs/sys/txg_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/uberblock.h
vendor/illumos/dist/uts/common/fs/zfs/sys/uberblock_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/unique.h
vendor/illumos/dist/uts/common/fs/zfs/sys/vdev.h
vendor/illumos/dist/uts/common/fs/zfs/sys/vdev_disk.h
vendor/illumos/dist/uts/common/fs/zfs/sys/vdev_file.h
vendor/illumos/dist/uts/common/fs/zfs/sys/vdev_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zap.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zap_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zap_leaf.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfeature.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_acl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_context.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_ctldir.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_debug.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_dir.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_fuid.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_ioctl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_onexit.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_rlock.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_sa.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_stat.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_vfsops.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zfs_znode.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zil.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zil_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zio.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zio_checksum.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zio_compress.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zio_impl.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zrlock.h
vendor/illumos/dist/uts/common/fs/zfs/sys/zvol.h
vendor/illumos/dist/uts/common/fs/zfs/txg.c
vendor/illumos/dist/uts/common/fs/zfs/uberblock.c
vendor/illumos/dist/uts/common/fs/zfs/unique.c
vendor/illumos/dist/uts/common/fs/zfs/vdev.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_cache.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_disk.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_file.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_label.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_mirror.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_missing.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_queue.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_raidz.c
vendor/illumos/dist/uts/common/fs/zfs/vdev_root.c
vendor/illumos/dist/uts/common/fs/zfs/zap.c
vendor/illumos/dist/uts/common/fs/zfs/zap_leaf.c
vendor/illumos/dist/uts/common/fs/zfs/zap_micro.c
vendor/illumos/dist/uts/common/fs/zfs/zfeature.c
vendor/illumos/dist/uts/common/fs/zfs/zfs.conf
vendor/illumos/dist/uts/common/fs/zfs/zfs_acl.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_byteswap.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_ctldir.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_debug.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_dir.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_fm.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_fuid.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_log.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_onexit.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_replay.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_rlock.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_sa.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_vfsops.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_vnops.c
vendor/illumos/dist/uts/common/fs/zfs/zfs_znode.c
vendor/illumos/dist/uts/common/fs/zfs/zil.c
vendor/illumos/dist/uts/common/fs/zfs/zio.c
vendor/illumos/dist/uts/common/fs/zfs/zio_checksum.c
vendor/illumos/dist/uts/common/fs/zfs/zio_compress.c
vendor/illumos/dist/uts/common/fs/zfs/zio_inject.c
vendor/illumos/dist/uts/common/fs/zfs/zle.c
vendor/illumos/dist/uts/common/fs/zfs/zrlock.c
vendor/illumos/dist/uts/common/fs/zfs/zvol.c
vendor/illumos/dist/uts/common/os/
vendor/illumos/dist/uts/common/os/callb.c
vendor/illumos/dist/uts/common/os/fm.c
vendor/illumos/dist/uts/common/os/nvpair_alloc_system.c
vendor/illumos/dist/uts/common/sys/
vendor/illumos/dist/uts/common/sys/acl.h
vendor/illumos/dist/uts/common/sys/acl_impl.h
vendor/illumos/dist/uts/common/sys/avl.h
vendor/illumos/dist/uts/common/sys/avl_impl.h
vendor/illumos/dist/uts/common/sys/bitmap.h
vendor/illumos/dist/uts/common/sys/callb.h
vendor/illumos/dist/uts/common/sys/ccompile.h
vendor/illumos/dist/uts/common/sys/cmn_err.h
vendor/illumos/dist/uts/common/sys/compress.h
vendor/illumos/dist/uts/common/sys/cpupart.h
vendor/illumos/dist/uts/common/sys/cpuvar.h
vendor/illumos/dist/uts/common/sys/cred.h
vendor/illumos/dist/uts/common/sys/ctf.h
vendor/illumos/dist/uts/common/sys/ctf_api.h
vendor/illumos/dist/uts/common/sys/debug.h
vendor/illumos/dist/uts/common/sys/dtrace.h
vendor/illumos/dist/uts/common/sys/dtrace_impl.h
vendor/illumos/dist/uts/common/sys/errorq.h
vendor/illumos/dist/uts/common/sys/extdirent.h
vendor/illumos/dist/uts/common/sys/fasttrap.h
vendor/illumos/dist/uts/common/sys/fasttrap_impl.h
vendor/illumos/dist/uts/common/sys/feature_tests.h
vendor/illumos/dist/uts/common/sys/fm/
vendor/illumos/dist/uts/common/sys/fm/fs/
vendor/illumos/dist/uts/common/sys/fm/fs/zfs.h
vendor/illumos/dist/uts/common/sys/fm/protocol.h
vendor/illumos/dist/uts/common/sys/fm/util.h
vendor/illumos/dist/uts/common/sys/fs/
vendor/illumos/dist/uts/common/sys/fs/zfs.h
vendor/illumos/dist/uts/common/sys/fs/zut.h
vendor/illumos/dist/uts/common/sys/gfs.h
vendor/illumos/dist/uts/common/sys/idmap.h
vendor/illumos/dist/uts/common/sys/isa_defs.h
vendor/illumos/dist/uts/common/sys/list.h
vendor/illumos/dist/uts/common/sys/list_impl.h
vendor/illumos/dist/uts/common/sys/note.h
vendor/illumos/dist/uts/common/sys/nvpair.h
vendor/illumos/dist/uts/common/sys/nvpair_impl.h
vendor/illumos/dist/uts/common/sys/processor.h
vendor/illumos/dist/uts/common/sys/procset.h
vendor/illumos/dist/uts/common/sys/synch.h
vendor/illumos/dist/uts/common/sys/sysevent/
vendor/illumos/dist/uts/common/sys/sysevent.h
vendor/illumos/dist/uts/common/sys/sysevent/dev.h
vendor/illumos/dist/uts/common/sys/sysevent/eventdefs.h
vendor/illumos/dist/uts/common/sys/sysmacros.h
vendor/illumos/dist/uts/common/sys/taskq.h
vendor/illumos/dist/uts/common/sys/u8_textprep.h
vendor/illumos/dist/uts/common/sys/u8_textprep_data.h
vendor/illumos/dist/uts/common/sys/vnode.h
vendor/illumos/dist/uts/common/sys/zmod.h
vendor/illumos/dist/uts/common/zmod/
vendor/illumos/dist/uts/common/zmod/adler32.c
vendor/illumos/dist/uts/common/zmod/crc32.h
vendor/illumos/dist/uts/common/zmod/deflate.c
vendor/illumos/dist/uts/common/zmod/deflate.h
vendor/illumos/dist/uts/common/zmod/inffast.c
vendor/illumos/dist/uts/common/zmod/inffast.h
vendor/illumos/dist/uts/common/zmod/inffixed.h
vendor/illumos/dist/uts/common/zmod/inflate.c
vendor/illumos/dist/uts/common/zmod/inflate.h
vendor/illumos/dist/uts/common/zmod/inftrees.c
vendor/illumos/dist/uts/common/zmod/inftrees.h
vendor/illumos/dist/uts/common/zmod/trees.c
vendor/illumos/dist/uts/common/zmod/zconf.h
vendor/illumos/dist/uts/common/zmod/zlib.h
vendor/illumos/dist/uts/common/zmod/zmod.c
vendor/illumos/dist/uts/common/zmod/zmod_subr.c
vendor/illumos/dist/uts/common/zmod/zutil.c
vendor/illumos/dist/uts/common/zmod/zutil.h
vendor/illumos/dist/uts/intel/
vendor/illumos/dist/uts/intel/dtrace/
vendor/illumos/dist/uts/intel/dtrace/fasttrap_isa.c
vendor/illumos/dist/uts/intel/sys/
vendor/illumos/dist/uts/intel/sys/fasttrap_isa.h
vendor/illumos/dist/uts/sparc/
vendor/illumos/dist/uts/sparc/dtrace/
vendor/illumos/dist/uts/sparc/dtrace/fasttrap_isa.c
vendor/illumos/dist/uts/sparc/sys/
vendor/illumos/dist/uts/sparc/sys/fasttrap_isa.h
Added: vendor/illumos/dist/common/acl/acl_common.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/illumos/dist/common/acl/acl_common.c Sun Jul 1 14:55:35 2012 (r237927)
@@ -0,0 +1,1760 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/avl.h>
+#if defined(_KERNEL)
+#include <sys/systm.h>
+#include <sys/sysmacros.h>
+#include <acl/acl_common.h>
+#else
+#include <errno.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <strings.h>
+#include <unistd.h>
+#include <assert.h>
+#include <grp.h>
+#include <pwd.h>
+#include <acl_common.h>
+#define ASSERT assert
+#endif
+
+#define ACE_POSIX_SUPPORTED_BITS (ACE_READ_DATA | \
+ ACE_WRITE_DATA | ACE_APPEND_DATA | ACE_EXECUTE | \
+ ACE_READ_ATTRIBUTES | ACE_READ_ACL | ACE_WRITE_ACL)
+
+
+#define ACL_SYNCHRONIZE_SET_DENY 0x0000001
+#define ACL_SYNCHRONIZE_SET_ALLOW 0x0000002
+#define ACL_SYNCHRONIZE_ERR_DENY 0x0000004
+#define ACL_SYNCHRONIZE_ERR_ALLOW 0x0000008
+
+#define ACL_WRITE_OWNER_SET_DENY 0x0000010
+#define ACL_WRITE_OWNER_SET_ALLOW 0x0000020
+#define ACL_WRITE_OWNER_ERR_DENY 0x0000040
+#define ACL_WRITE_OWNER_ERR_ALLOW 0x0000080
+
+#define ACL_DELETE_SET_DENY 0x0000100
+#define ACL_DELETE_SET_ALLOW 0x0000200
+#define ACL_DELETE_ERR_DENY 0x0000400
+#define ACL_DELETE_ERR_ALLOW 0x0000800
+
+#define ACL_WRITE_ATTRS_OWNER_SET_DENY 0x0001000
+#define ACL_WRITE_ATTRS_OWNER_SET_ALLOW 0x0002000
+#define ACL_WRITE_ATTRS_OWNER_ERR_DENY 0x0004000
+#define ACL_WRITE_ATTRS_OWNER_ERR_ALLOW 0x0008000
+
+#define ACL_WRITE_ATTRS_WRITER_SET_DENY 0x0010000
+#define ACL_WRITE_ATTRS_WRITER_SET_ALLOW 0x0020000
+#define ACL_WRITE_ATTRS_WRITER_ERR_DENY 0x0040000
+#define ACL_WRITE_ATTRS_WRITER_ERR_ALLOW 0x0080000
+
+#define ACL_WRITE_NAMED_WRITER_SET_DENY 0x0100000
+#define ACL_WRITE_NAMED_WRITER_SET_ALLOW 0x0200000
+#define ACL_WRITE_NAMED_WRITER_ERR_DENY 0x0400000
+#define ACL_WRITE_NAMED_WRITER_ERR_ALLOW 0x0800000
+
+#define ACL_READ_NAMED_READER_SET_DENY 0x1000000
+#define ACL_READ_NAMED_READER_SET_ALLOW 0x2000000
+#define ACL_READ_NAMED_READER_ERR_DENY 0x4000000
+#define ACL_READ_NAMED_READER_ERR_ALLOW 0x8000000
+
+
+#define ACE_VALID_MASK_BITS (\
+ ACE_READ_DATA | \
+ ACE_LIST_DIRECTORY | \
+ ACE_WRITE_DATA | \
+ ACE_ADD_FILE | \
+ ACE_APPEND_DATA | \
+ ACE_ADD_SUBDIRECTORY | \
+ ACE_READ_NAMED_ATTRS | \
+ ACE_WRITE_NAMED_ATTRS | \
+ ACE_EXECUTE | \
+ ACE_DELETE_CHILD | \
+ ACE_READ_ATTRIBUTES | \
+ ACE_WRITE_ATTRIBUTES | \
+ ACE_DELETE | \
+ ACE_READ_ACL | \
+ ACE_WRITE_ACL | \
+ ACE_WRITE_OWNER | \
+ ACE_SYNCHRONIZE)
+
+#define ACE_MASK_UNDEFINED 0x80000000
+
+#define ACE_VALID_FLAG_BITS (ACE_FILE_INHERIT_ACE | \
+ ACE_DIRECTORY_INHERIT_ACE | \
+ ACE_NO_PROPAGATE_INHERIT_ACE | ACE_INHERIT_ONLY_ACE | \
+ ACE_SUCCESSFUL_ACCESS_ACE_FLAG | ACE_FAILED_ACCESS_ACE_FLAG | \
+ ACE_IDENTIFIER_GROUP | ACE_OWNER | ACE_GROUP | ACE_EVERYONE)
+
+/*
+ * ACL conversion helpers
+ */
+
+typedef enum {
+ ace_unused,
+ ace_user_obj,
+ ace_user,
+ ace_group, /* includes GROUP and GROUP_OBJ */
+ ace_other_obj
+} ace_to_aent_state_t;
+
+typedef struct acevals {
+ uid_t key;
+ avl_node_t avl;
+ uint32_t mask;
+ uint32_t allowed;
+ uint32_t denied;
+ int aent_type;
+} acevals_t;
+
+typedef struct ace_list {
+ acevals_t user_obj;
+ avl_tree_t user;
+ int numusers;
+ acevals_t group_obj;
+ avl_tree_t group;
+ int numgroups;
+ acevals_t other_obj;
+ uint32_t acl_mask;
+ int hasmask;
+ int dfacl_flag;
+ ace_to_aent_state_t state;
+ int seen; /* bitmask of all aclent_t a_type values seen */
+} ace_list_t;
+
+/*
+ * Generic shellsort, from K&R (1st ed, p 58.), somewhat modified.
+ * v = Ptr to array/vector of objs
+ * n = # objs in the array
+ * s = size of each obj (must be multiples of a word size)
+ * f = ptr to function to compare two objs
+ * returns (-1 = less than, 0 = equal, 1 = greater than
+ */
+void
+ksort(caddr_t v, int n, int s, int (*f)())
+{
+ int g, i, j, ii;
+ unsigned int *p1, *p2;
+ unsigned int tmp;
+
+ /* No work to do */
+ if (v == NULL || n <= 1)
+ return;
+
+ /* Sanity check on arguments */
+ ASSERT(((uintptr_t)v & 0x3) == 0 && (s & 0x3) == 0);
+ ASSERT(s > 0);
+ for (g = n / 2; g > 0; g /= 2) {
+ for (i = g; i < n; i++) {
+ for (j = i - g; j >= 0 &&
+ (*f)(v + j * s, v + (j + g) * s) == 1;
+ j -= g) {
+ p1 = (void *)(v + j * s);
+ p2 = (void *)(v + (j + g) * s);
+ for (ii = 0; ii < s / 4; ii++) {
+ tmp = *p1;
+ *p1++ = *p2;
+ *p2++ = tmp;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Compare two acls, all fields. Returns:
+ * -1 (less than)
+ * 0 (equal)
+ * +1 (greater than)
+ */
+int
+cmp2acls(void *a, void *b)
+{
+ aclent_t *x = (aclent_t *)a;
+ aclent_t *y = (aclent_t *)b;
+
+ /* Compare types */
+ if (x->a_type < y->a_type)
+ return (-1);
+ if (x->a_type > y->a_type)
+ return (1);
+ /* Equal types; compare id's */
+ if (x->a_id < y->a_id)
+ return (-1);
+ if (x->a_id > y->a_id)
+ return (1);
+ /* Equal ids; compare perms */
+ if (x->a_perm < y->a_perm)
+ return (-1);
+ if (x->a_perm > y->a_perm)
+ return (1);
+ /* Totally equal */
+ return (0);
+}
+
+/*ARGSUSED*/
+static void *
+cacl_realloc(void *ptr, size_t size, size_t new_size)
+{
+#if defined(_KERNEL)
+ void *tmp;
+
+ tmp = kmem_alloc(new_size, KM_SLEEP);
+ (void) memcpy(tmp, ptr, (size < new_size) ? size : new_size);
+ kmem_free(ptr, size);
+ return (tmp);
+#else
+ return (realloc(ptr, new_size));
+#endif
+}
+
+static int
+cacl_malloc(void **ptr, size_t size)
+{
+#if defined(_KERNEL)
+ *ptr = kmem_zalloc(size, KM_SLEEP);
+ return (0);
+#else
+ *ptr = calloc(1, size);
+ if (*ptr == NULL)
+ return (errno);
+
+ return (0);
+#endif
+}
+
+/*ARGSUSED*/
+static void
+cacl_free(void *ptr, size_t size)
+{
+#if defined(_KERNEL)
+ kmem_free(ptr, size);
+#else
+ free(ptr);
+#endif
+}
+
+acl_t *
+acl_alloc(enum acl_type type)
+{
+ acl_t *aclp;
+
+ if (cacl_malloc((void **)&aclp, sizeof (acl_t)) != 0)
+ return (NULL);
+
+ aclp->acl_aclp = NULL;
+ aclp->acl_cnt = 0;
+
+ switch (type) {
+ case ACE_T:
+ aclp->acl_type = ACE_T;
+ aclp->acl_entry_size = sizeof (ace_t);
+ break;
+ case ACLENT_T:
+ aclp->acl_type = ACLENT_T;
+ aclp->acl_entry_size = sizeof (aclent_t);
+ break;
+ default:
+ acl_free(aclp);
+ aclp = NULL;
+ }
+ return (aclp);
+}
+
+/*
+ * Free acl_t structure
+ */
+void
+acl_free(acl_t *aclp)
+{
+ int acl_size;
+
+ if (aclp == NULL)
+ return;
+
+ if (aclp->acl_aclp) {
+ acl_size = aclp->acl_cnt * aclp->acl_entry_size;
+ cacl_free(aclp->acl_aclp, acl_size);
+ }
+
+ cacl_free(aclp, sizeof (acl_t));
+}
+
+static uint32_t
+access_mask_set(int haswriteperm, int hasreadperm, int isowner, int isallow)
+{
+ uint32_t access_mask = 0;
+ int acl_produce;
+ int synchronize_set = 0, write_owner_set = 0;
+ int delete_set = 0, write_attrs_set = 0;
+ int read_named_set = 0, write_named_set = 0;
+
+ acl_produce = (ACL_SYNCHRONIZE_SET_ALLOW |
+ ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
+ ACL_WRITE_ATTRS_WRITER_SET_DENY);
+
+ if (isallow) {
+ synchronize_set = ACL_SYNCHRONIZE_SET_ALLOW;
+ write_owner_set = ACL_WRITE_OWNER_SET_ALLOW;
+ delete_set = ACL_DELETE_SET_ALLOW;
+ if (hasreadperm)
+ read_named_set = ACL_READ_NAMED_READER_SET_ALLOW;
+ if (haswriteperm)
+ write_named_set = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
+ if (isowner)
+ write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
+ else if (haswriteperm)
+ write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
+ } else {
+
+ synchronize_set = ACL_SYNCHRONIZE_SET_DENY;
+ write_owner_set = ACL_WRITE_OWNER_SET_DENY;
+ delete_set = ACL_DELETE_SET_DENY;
+ if (hasreadperm)
+ read_named_set = ACL_READ_NAMED_READER_SET_DENY;
+ if (haswriteperm)
+ write_named_set = ACL_WRITE_NAMED_WRITER_SET_DENY;
+ if (isowner)
+ write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_DENY;
+ else if (haswriteperm)
+ write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_DENY;
+ else
+ /*
+ * If the entity is not the owner and does not
+ * have write permissions ACE_WRITE_ATTRIBUTES will
+ * always go in the DENY ACE.
+ */
+ access_mask |= ACE_WRITE_ATTRIBUTES;
+ }
+
+ if (acl_produce & synchronize_set)
+ access_mask |= ACE_SYNCHRONIZE;
+ if (acl_produce & write_owner_set)
+ access_mask |= ACE_WRITE_OWNER;
+ if (acl_produce & delete_set)
+ access_mask |= ACE_DELETE;
+ if (acl_produce & write_attrs_set)
+ access_mask |= ACE_WRITE_ATTRIBUTES;
+ if (acl_produce & read_named_set)
+ access_mask |= ACE_READ_NAMED_ATTRS;
+ if (acl_produce & write_named_set)
+ access_mask |= ACE_WRITE_NAMED_ATTRS;
+
+ return (access_mask);
+}
+
+/*
+ * Given an mode_t, convert it into an access_mask as used
+ * by nfsace, assuming aclent_t -> nfsace semantics.
+ */
+static uint32_t
+mode_to_ace_access(mode_t mode, boolean_t isdir, int isowner, int isallow)
+{
+ uint32_t access = 0;
+ int haswriteperm = 0;
+ int hasreadperm = 0;
+
+ if (isallow) {
+ haswriteperm = (mode & S_IWOTH);
+ hasreadperm = (mode & S_IROTH);
+ } else {
+ haswriteperm = !(mode & S_IWOTH);
+ hasreadperm = !(mode & S_IROTH);
+ }
+
+ /*
+ * The following call takes care of correctly setting the following
+ * mask bits in the access_mask:
+ * ACE_SYNCHRONIZE, ACE_WRITE_OWNER, ACE_DELETE,
+ * ACE_WRITE_ATTRIBUTES, ACE_WRITE_NAMED_ATTRS, ACE_READ_NAMED_ATTRS
+ */
+ access = access_mask_set(haswriteperm, hasreadperm, isowner, isallow);
+
+ if (isallow) {
+ access |= ACE_READ_ACL | ACE_READ_ATTRIBUTES;
+ if (isowner)
+ access |= ACE_WRITE_ACL;
+ } else {
+ if (! isowner)
+ access |= ACE_WRITE_ACL;
+ }
+
+ /* read */
+ if (mode & S_IROTH) {
+ access |= ACE_READ_DATA;
+ }
+ /* write */
+ if (mode & S_IWOTH) {
+ access |= ACE_WRITE_DATA |
+ ACE_APPEND_DATA;
+ if (isdir)
+ access |= ACE_DELETE_CHILD;
+ }
+ /* exec */
+ if (mode & S_IXOTH) {
+ access |= ACE_EXECUTE;
+ }
+
+ return (access);
+}
+
+/*
+ * Given an nfsace (presumably an ALLOW entry), make a
+ * corresponding DENY entry at the address given.
+ */
+static void
+ace_make_deny(ace_t *allow, ace_t *deny, int isdir, int isowner)
+{
+ (void) memcpy(deny, allow, sizeof (ace_t));
+
+ deny->a_who = allow->a_who;
+
+ deny->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
+ deny->a_access_mask ^= ACE_POSIX_SUPPORTED_BITS;
+ if (isdir)
+ deny->a_access_mask ^= ACE_DELETE_CHILD;
+
+ deny->a_access_mask &= ~(ACE_SYNCHRONIZE | ACE_WRITE_OWNER |
+ ACE_DELETE | ACE_WRITE_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
+ ACE_WRITE_NAMED_ATTRS);
+ deny->a_access_mask |= access_mask_set((allow->a_access_mask &
+ ACE_WRITE_DATA), (allow->a_access_mask & ACE_READ_DATA), isowner,
+ B_FALSE);
+}
+/*
+ * Make an initial pass over an array of aclent_t's. Gather
+ * information such as an ACL_MASK (if any), number of users,
+ * number of groups, and whether the array needs to be sorted.
+ */
+static int
+ln_aent_preprocess(aclent_t *aclent, int n,
+ int *hasmask, mode_t *mask,
+ int *numuser, int *numgroup, int *needsort)
+{
+ int error = 0;
+ int i;
+ int curtype = 0;
+
+ *hasmask = 0;
+ *mask = 07;
+ *needsort = 0;
+ *numuser = 0;
+ *numgroup = 0;
+
+ for (i = 0; i < n; i++) {
+ if (aclent[i].a_type < curtype)
+ *needsort = 1;
+ else if (aclent[i].a_type > curtype)
+ curtype = aclent[i].a_type;
+ if (aclent[i].a_type & USER)
+ (*numuser)++;
+ if (aclent[i].a_type & (GROUP | GROUP_OBJ))
+ (*numgroup)++;
+ if (aclent[i].a_type & CLASS_OBJ) {
+ if (*hasmask) {
+ error = EINVAL;
+ goto out;
+ } else {
+ *hasmask = 1;
+ *mask = aclent[i].a_perm;
+ }
+ }
+ }
+
+ if ((! *hasmask) && (*numuser + *numgroup > 1)) {
+ error = EINVAL;
+ goto out;
+ }
+
+out:
+ return (error);
+}
+
+/*
+ * Convert an array of aclent_t into an array of nfsace entries,
+ * following POSIX draft -> nfsv4 conversion semantics as outlined in
+ * the IETF draft.
+ */
+static int
+ln_aent_to_ace(aclent_t *aclent, int n, ace_t **acepp, int *rescount, int isdir)
+{
+ int error = 0;
+ mode_t mask;
+ int numuser, numgroup, needsort;
+ int resultsize = 0;
+ int i, groupi = 0, skip;
+ ace_t *acep, *result = NULL;
+ int hasmask;
+
+ error = ln_aent_preprocess(aclent, n, &hasmask, &mask,
+ &numuser, &numgroup, &needsort);
+ if (error != 0)
+ goto out;
+
+ /* allow + deny for each aclent */
+ resultsize = n * 2;
+ if (hasmask) {
+ /*
+ * stick extra deny on the group_obj and on each
+ * user|group for the mask (the group_obj was added
+ * into the count for numgroup)
+ */
+ resultsize += numuser + numgroup;
+ /* ... and don't count the mask itself */
+ resultsize -= 2;
+ }
+
+ /* sort the source if necessary */
+ if (needsort)
+ ksort((caddr_t)aclent, n, sizeof (aclent_t), cmp2acls);
+
+ if (cacl_malloc((void **)&result, resultsize * sizeof (ace_t)) != 0)
+ goto out;
+
+ acep = result;
+
+ for (i = 0; i < n; i++) {
+ /*
+ * don't process CLASS_OBJ (mask); mask was grabbed in
+ * ln_aent_preprocess()
+ */
+ if (aclent[i].a_type & CLASS_OBJ)
+ continue;
+
+ /* If we need an ACL_MASK emulator, prepend it now */
+ if ((hasmask) &&
+ (aclent[i].a_type & (USER | GROUP | GROUP_OBJ))) {
+ acep->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
+ acep->a_flags = 0;
+ if (aclent[i].a_type & GROUP_OBJ) {
+ acep->a_who = (uid_t)-1;
+ acep->a_flags |=
+ (ACE_IDENTIFIER_GROUP|ACE_GROUP);
+ } else if (aclent[i].a_type & USER) {
+ acep->a_who = aclent[i].a_id;
+ } else {
+ acep->a_who = aclent[i].a_id;
+ acep->a_flags |= ACE_IDENTIFIER_GROUP;
+ }
+ if (aclent[i].a_type & ACL_DEFAULT) {
+ acep->a_flags |= ACE_INHERIT_ONLY_ACE |
+ ACE_FILE_INHERIT_ACE |
+ ACE_DIRECTORY_INHERIT_ACE;
+ }
+ /*
+ * Set the access mask for the prepended deny
+ * ace. To do this, we invert the mask (found
+ * in ln_aent_preprocess()) then convert it to an
+ * DENY ace access_mask.
+ */
+ acep->a_access_mask = mode_to_ace_access((mask ^ 07),
+ isdir, 0, 0);
+ acep += 1;
+ }
+
+ /* handle a_perm -> access_mask */
+ acep->a_access_mask = mode_to_ace_access(aclent[i].a_perm,
+ isdir, aclent[i].a_type & USER_OBJ, 1);
+
+ /* emulate a default aclent */
+ if (aclent[i].a_type & ACL_DEFAULT) {
+ acep->a_flags |= ACE_INHERIT_ONLY_ACE |
+ ACE_FILE_INHERIT_ACE |
+ ACE_DIRECTORY_INHERIT_ACE;
+ }
+
+ /*
+ * handle a_perm and a_id
+ *
+ * this must be done last, since it involves the
+ * corresponding deny aces, which are handled
+ * differently for each different a_type.
+ */
+ if (aclent[i].a_type & USER_OBJ) {
+ acep->a_who = (uid_t)-1;
+ acep->a_flags |= ACE_OWNER;
+ ace_make_deny(acep, acep + 1, isdir, B_TRUE);
+ acep += 2;
+ } else if (aclent[i].a_type & USER) {
+ acep->a_who = aclent[i].a_id;
+ ace_make_deny(acep, acep + 1, isdir, B_FALSE);
+ acep += 2;
+ } else if (aclent[i].a_type & (GROUP_OBJ | GROUP)) {
+ if (aclent[i].a_type & GROUP_OBJ) {
+ acep->a_who = (uid_t)-1;
+ acep->a_flags |= ACE_GROUP;
+ } else {
+ acep->a_who = aclent[i].a_id;
+ }
+ acep->a_flags |= ACE_IDENTIFIER_GROUP;
+ /*
+ * Set the corresponding deny for the group ace.
+ *
+ * The deny aces go after all of the groups, unlike
+ * everything else, where they immediately follow
+ * the allow ace.
+ *
+ * We calculate "skip", the number of slots to
+ * skip ahead for the deny ace, here.
+ *
+ * The pattern is:
+ * MD1 A1 MD2 A2 MD3 A3 D1 D2 D3
+ * thus, skip is
+ * (2 * numgroup) - 1 - groupi
+ * (2 * numgroup) to account for MD + A
+ * - 1 to account for the fact that we're on the
+ * access (A), not the mask (MD)
+ * - groupi to account for the fact that we have
+ * passed up groupi number of MD's.
+ */
+ skip = (2 * numgroup) - 1 - groupi;
+ ace_make_deny(acep, acep + skip, isdir, B_FALSE);
+ /*
+ * If we just did the last group, skip acep past
+ * all of the denies; else, just move ahead one.
+ */
+ if (++groupi >= numgroup)
+ acep += numgroup + 1;
+ else
+ acep += 1;
+ } else if (aclent[i].a_type & OTHER_OBJ) {
+ acep->a_who = (uid_t)-1;
+ acep->a_flags |= ACE_EVERYONE;
+ ace_make_deny(acep, acep + 1, isdir, B_FALSE);
+ acep += 2;
+ } else {
+ error = EINVAL;
+ goto out;
+ }
+ }
+
+ *acepp = result;
+ *rescount = resultsize;
+
+out:
+ if (error != 0) {
+ if ((result != NULL) && (resultsize > 0)) {
+ cacl_free(result, resultsize * sizeof (ace_t));
+ }
+ }
+
+ return (error);
+}
+
+static int
+convert_aent_to_ace(aclent_t *aclentp, int aclcnt, boolean_t isdir,
+ ace_t **retacep, int *retacecnt)
+{
+ ace_t *acep;
+ ace_t *dfacep;
+ int acecnt = 0;
+ int dfacecnt = 0;
+ int dfaclstart = 0;
+ int dfaclcnt = 0;
+ aclent_t *aclp;
+ int i;
+ int error;
+ int acesz, dfacesz;
+
+ ksort((caddr_t)aclentp, aclcnt, sizeof (aclent_t), cmp2acls);
+
+ for (i = 0, aclp = aclentp; i < aclcnt; aclp++, i++) {
+ if (aclp->a_type & ACL_DEFAULT)
+ break;
+ }
+
+ if (i < aclcnt) {
+ dfaclstart = i;
+ dfaclcnt = aclcnt - i;
+ }
+
+ if (dfaclcnt && !isdir) {
+ return (EINVAL);
+ }
+
+ error = ln_aent_to_ace(aclentp, i, &acep, &acecnt, isdir);
+ if (error)
+ return (error);
+
+ if (dfaclcnt) {
+ error = ln_aent_to_ace(&aclentp[dfaclstart], dfaclcnt,
+ &dfacep, &dfacecnt, isdir);
+ if (error) {
+ if (acep) {
+ cacl_free(acep, acecnt * sizeof (ace_t));
+ }
+ return (error);
+ }
+ }
+
+ if (dfacecnt != 0) {
+ acesz = sizeof (ace_t) * acecnt;
+ dfacesz = sizeof (ace_t) * dfacecnt;
+ acep = cacl_realloc(acep, acesz, acesz + dfacesz);
+ if (acep == NULL)
+ return (ENOMEM);
+ if (dfaclcnt) {
+ (void) memcpy(acep + acecnt, dfacep, dfacesz);
+ }
+ }
+ if (dfaclcnt)
+ cacl_free(dfacep, dfacecnt * sizeof (ace_t));
+
+ *retacecnt = acecnt + dfacecnt;
+ *retacep = acep;
+ return (0);
+}
+
+static int
+ace_mask_to_mode(uint32_t mask, o_mode_t *modep, boolean_t isdir)
+{
+ int error = 0;
+ o_mode_t mode = 0;
+ uint32_t bits, wantbits;
+
+ /* read */
+ if (mask & ACE_READ_DATA)
+ mode |= S_IROTH;
+
+ /* write */
+ wantbits = (ACE_WRITE_DATA | ACE_APPEND_DATA);
+ if (isdir)
+ wantbits |= ACE_DELETE_CHILD;
+ bits = mask & wantbits;
+ if (bits != 0) {
+ if (bits != wantbits) {
+ error = ENOTSUP;
+ goto out;
+ }
+ mode |= S_IWOTH;
+ }
+
+ /* exec */
+ if (mask & ACE_EXECUTE) {
+ mode |= S_IXOTH;
+ }
+
+ *modep = mode;
+
+out:
+ return (error);
+}
+
+static void
+acevals_init(acevals_t *vals, uid_t key)
+{
+ bzero(vals, sizeof (*vals));
+ vals->allowed = ACE_MASK_UNDEFINED;
+ vals->denied = ACE_MASK_UNDEFINED;
+ vals->mask = ACE_MASK_UNDEFINED;
+ vals->key = key;
+}
+
+static void
+ace_list_init(ace_list_t *al, int dfacl_flag)
+{
+ acevals_init(&al->user_obj, NULL);
+ acevals_init(&al->group_obj, NULL);
+ acevals_init(&al->other_obj, NULL);
+ al->numusers = 0;
+ al->numgroups = 0;
+ al->acl_mask = 0;
+ al->hasmask = 0;
+ al->state = ace_unused;
+ al->seen = 0;
+ al->dfacl_flag = dfacl_flag;
+}
+
+/*
+ * Find or create an acevals holder for a given id and avl tree.
+ *
+ * Note that only one thread will ever touch these avl trees, so
+ * there is no need for locking.
+ */
+static acevals_t *
+acevals_find(ace_t *ace, avl_tree_t *avl, int *num)
+{
+ acevals_t key, *rc;
+ avl_index_t where;
+
+ key.key = ace->a_who;
+ rc = avl_find(avl, &key, &where);
+ if (rc != NULL)
+ return (rc);
+
+ /* this memory is freed by ln_ace_to_aent()->ace_list_free() */
+ if (cacl_malloc((void **)&rc, sizeof (acevals_t)) != 0)
+ return (NULL);
+
+ acevals_init(rc, ace->a_who);
+ avl_insert(avl, rc, where);
+ (*num)++;
+
+ return (rc);
+}
+
+static int
+access_mask_check(ace_t *acep, int mask_bit, int isowner)
+{
+ int set_deny, err_deny;
+ int set_allow, err_allow;
+ int acl_consume;
+ int haswriteperm, hasreadperm;
+
+ if (acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) {
+ haswriteperm = (acep->a_access_mask & ACE_WRITE_DATA) ? 0 : 1;
+ hasreadperm = (acep->a_access_mask & ACE_READ_DATA) ? 0 : 1;
+ } else {
+ haswriteperm = (acep->a_access_mask & ACE_WRITE_DATA) ? 1 : 0;
+ hasreadperm = (acep->a_access_mask & ACE_READ_DATA) ? 1 : 0;
+ }
+
+ acl_consume = (ACL_SYNCHRONIZE_ERR_DENY |
+ ACL_DELETE_ERR_DENY |
+ ACL_WRITE_OWNER_ERR_DENY |
+ ACL_WRITE_OWNER_ERR_ALLOW |
+ ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
+ ACL_WRITE_ATTRS_OWNER_ERR_DENY |
+ ACL_WRITE_ATTRS_WRITER_SET_DENY |
+ ACL_WRITE_ATTRS_WRITER_ERR_ALLOW |
+ ACL_WRITE_NAMED_WRITER_ERR_DENY |
+ ACL_READ_NAMED_READER_ERR_DENY);
+
+ if (mask_bit == ACE_SYNCHRONIZE) {
+ set_deny = ACL_SYNCHRONIZE_SET_DENY;
+ err_deny = ACL_SYNCHRONIZE_ERR_DENY;
+ set_allow = ACL_SYNCHRONIZE_SET_ALLOW;
+ err_allow = ACL_SYNCHRONIZE_ERR_ALLOW;
+ } else if (mask_bit == ACE_WRITE_OWNER) {
+ set_deny = ACL_WRITE_OWNER_SET_DENY;
+ err_deny = ACL_WRITE_OWNER_ERR_DENY;
+ set_allow = ACL_WRITE_OWNER_SET_ALLOW;
+ err_allow = ACL_WRITE_OWNER_ERR_ALLOW;
+ } else if (mask_bit == ACE_DELETE) {
+ set_deny = ACL_DELETE_SET_DENY;
+ err_deny = ACL_DELETE_ERR_DENY;
+ set_allow = ACL_DELETE_SET_ALLOW;
+ err_allow = ACL_DELETE_ERR_ALLOW;
+ } else if (mask_bit == ACE_WRITE_ATTRIBUTES) {
+ if (isowner) {
+ set_deny = ACL_WRITE_ATTRS_OWNER_SET_DENY;
+ err_deny = ACL_WRITE_ATTRS_OWNER_ERR_DENY;
+ set_allow = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
+ err_allow = ACL_WRITE_ATTRS_OWNER_ERR_ALLOW;
+ } else if (haswriteperm) {
+ set_deny = ACL_WRITE_ATTRS_WRITER_SET_DENY;
+ err_deny = ACL_WRITE_ATTRS_WRITER_ERR_DENY;
+ set_allow = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
+ err_allow = ACL_WRITE_ATTRS_WRITER_ERR_ALLOW;
+ } else {
+ if ((acep->a_access_mask & mask_bit) &&
+ (acep->a_type & ACE_ACCESS_ALLOWED_ACE_TYPE)) {
+ return (ENOTSUP);
+ }
+ return (0);
+ }
+ } else if (mask_bit == ACE_READ_NAMED_ATTRS) {
+ if (!hasreadperm)
+ return (0);
+
+ set_deny = ACL_READ_NAMED_READER_SET_DENY;
+ err_deny = ACL_READ_NAMED_READER_ERR_DENY;
+ set_allow = ACL_READ_NAMED_READER_SET_ALLOW;
+ err_allow = ACL_READ_NAMED_READER_ERR_ALLOW;
+ } else if (mask_bit == ACE_WRITE_NAMED_ATTRS) {
+ if (!haswriteperm)
+ return (0);
+
+ set_deny = ACL_WRITE_NAMED_WRITER_SET_DENY;
+ err_deny = ACL_WRITE_NAMED_WRITER_ERR_DENY;
+ set_allow = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
+ err_allow = ACL_WRITE_NAMED_WRITER_ERR_ALLOW;
+ } else {
+ return (EINVAL);
+ }
+
+ if (acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) {
+ if (acl_consume & set_deny) {
+ if (!(acep->a_access_mask & mask_bit)) {
+ return (ENOTSUP);
+ }
+ } else if (acl_consume & err_deny) {
+ if (acep->a_access_mask & mask_bit) {
+ return (ENOTSUP);
+ }
+ }
+ } else {
+ /* ACE_ACCESS_ALLOWED_ACE_TYPE */
+ if (acl_consume & set_allow) {
+ if (!(acep->a_access_mask & mask_bit)) {
+ return (ENOTSUP);
+ }
+ } else if (acl_consume & err_allow) {
+ if (acep->a_access_mask & mask_bit) {
+ return (ENOTSUP);
+ }
+ }
+ }
+ return (0);
+}
+
+static int
+ace_to_aent_legal(ace_t *acep)
+{
+ int error = 0;
+ int isowner;
+
+ /* only ALLOW or DENY */
+ if ((acep->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE) &&
+ (acep->a_type != ACE_ACCESS_DENIED_ACE_TYPE)) {
+ error = ENOTSUP;
+ goto out;
+ }
+
+ /* check for invalid flags */
+ if (acep->a_flags & ~(ACE_VALID_FLAG_BITS)) {
+ error = EINVAL;
+ goto out;
+ }
+
+ /* some flags are illegal */
+ if (acep->a_flags & (ACE_SUCCESSFUL_ACCESS_ACE_FLAG |
+ ACE_FAILED_ACCESS_ACE_FLAG |
+ ACE_NO_PROPAGATE_INHERIT_ACE)) {
+ error = ENOTSUP;
+ goto out;
+ }
+
+ /* check for invalid masks */
+ if (acep->a_access_mask & ~(ACE_VALID_MASK_BITS)) {
+ error = EINVAL;
+ goto out;
+ }
+
+ if ((acep->a_flags & ACE_OWNER)) {
+ isowner = 1;
+ } else {
+ isowner = 0;
+ }
+
+ error = access_mask_check(acep, ACE_SYNCHRONIZE, isowner);
+ if (error)
+ goto out;
+
+ error = access_mask_check(acep, ACE_WRITE_OWNER, isowner);
+ if (error)
+ goto out;
+
+ error = access_mask_check(acep, ACE_DELETE, isowner);
+ if (error)
+ goto out;
+
+ error = access_mask_check(acep, ACE_WRITE_ATTRIBUTES, isowner);
+ if (error)
+ goto out;
+
+ error = access_mask_check(acep, ACE_READ_NAMED_ATTRS, isowner);
+ if (error)
+ goto out;
+
+ error = access_mask_check(acep, ACE_WRITE_NAMED_ATTRS, isowner);
+ if (error)
+ goto out;
+
+ /* more detailed checking of masks */
+ if (acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) {
+ if (! (acep->a_access_mask & ACE_READ_ATTRIBUTES)) {
+ error = ENOTSUP;
+ goto out;
+ }
+ if ((acep->a_access_mask & ACE_WRITE_DATA) &&
+ (! (acep->a_access_mask & ACE_APPEND_DATA))) {
+ error = ENOTSUP;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-vendor
mailing list