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-all mailing list