/*
 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * The contents of this file constitute Original Code as defined in and
 * are subject to the Apple Public Source License Version 1.1 (the
 * "License").  You may not use this file except in compliance with the
 * License.  Please obtain a copy of the License at
 * http://www.apple.com/publicsource and read it before using this file.
 * 
 * This Original Code and all software distributed under the License are
 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */

#ifndef _ACLVAR_H
#define _ACLVAR_H

#include <sys/kauth.h>

#define _ACL_HEADER_SIZE	sizeof(struct kauth_filesec)
#define _ACL_ENTRY_SIZE		sizeof(struct kauth_ace)

/*
 * Internal access control list entry representation.
 */
struct _acl_entry {
	u_int32_t	ae_magic;
#define _ACL_ENTRY_MAGIC	0xac1ac101
	u_int32_t	ae_tag;
	guid_t		ae_applicable;
	u_int32_t	ae_flags;
	u_int32_t	ae_perms;
};

/*
 * Internal representation of an ACL.
 * XXX static allocation is wasteful. 
 */
struct _acl {
	u_int32_t	a_magic;
#define _ACL_ACL_MAGIC		0xac1ac102
	unsigned	a_entries;
	int		a_last_get;
	u_int32_t	a_flags;
	struct _acl_entry a_ace[ACL_MAX_ENTRIES];
};

/*
 * ACL/entry flags.
 */
struct _acl_flagset {
	u_int32_t	af_flags;
};

/*
 * ACL entry permissions.
 */
struct _acl_permset {
	u_int32_t	ap_perms;
};

/*
 * Argument validation.
 */

#define _ACL_VALID_ENTRY(_e)	((_e)->ae_magic == _ACL_ENTRY_MAGIC)

#define _ACL_VALID_ACL(_a)	((_a)->a_magic == _ACL_ACL_MAGIC)

#define _ACL_ENTRY_CONTAINED(_a, _e) \
	((_e) >= &(_a)->a_ace[0]) && ((_e) < &(_a)->a_ace[ACL_MAX_ENTRIES])

#define _ACL_VALID_FLAG(_f) (((_f) & _ACL_FLAGS_MASK) == (_f))

#define _ACL_VALID_ENTRY_FLAG(_f) (((_f) & _ACL_ENTRY_FLAGS_MASK) == (_f))

#define _ACL_PERMS_MASK	(ACL_READ_DATA |					\
			ACL_LIST_DIRECTORY |				\
			ACL_WRITE_DATA |				\
			ACL_ADD_FILE |					\
			ACL_EXECUTE |					\
			ACL_SEARCH |					\
			ACL_DELETE |					\
			ACL_APPEND_DATA |				\
			ACL_ADD_SUBDIRECTORY |				\
			ACL_DELETE_CHILD |				\
			ACL_READ_ATTRIBUTES |				\
			ACL_WRITE_ATTRIBUTES |				\
			ACL_READ_EXTATTRIBUTES |			\
			ACL_WRITE_EXTATTRIBUTES |			\
			ACL_READ_SECURITY |				\
			ACL_WRITE_SECURITY |				\
			ACL_CHANGE_OWNER)

#define _ACL_VALID_PERM(_f)	(((_f) & ~_ACL_PERMS_MASK) == 0)

#define _ACL_VALIDATE_ACL(_a)						\
do {									\
	if (!_ACL_VALID_ACL((_a))) {					\
		errno = EINVAL;						\
		return(-1);						\
	}								\
} while (0)

#define _ACL_VALIDATE_ENTRY(_e)						\
do {									\
	if (!_ACL_VALID_ENTRY((_e))) {					\
		errno = EINVAL;						\
		return(-1);						\
	}								\
} while (0)

#define _ACL_VALIDATE_ENTRY_CONTAINED(_a, _e)				\
do {									\
	if (!_ACL_ENTRY_CONTAINED((_a), (_e))) {			\
		errno = EINVAL;						\
		return(-1);						\
	}								\
} while (0)
	
#define _ACL_VALIDATE_FLAG(_f)						\
do {									\
	if (!_ACL_VALID_FLAG((_f))) {					\
		errno = EINVAL;						\
		return(-1);						\
	}								\
} while (0)

#define _ACL_VALIDATE_ENTRY_FLAG(_f)					\
do {									\
	if (!_ACL_VALID_ENTRY_FLAG((_f))) {				\
		errno = EINVAL;						\
		return(-1);						\
	}								\
} while (0)

#define _ACL_VALIDATE_PERM(_f)						\
do {									\
	if (!_ACL_VALID_PERM((_f))) {					\
		errno = EINVAL;						\
		return(-1);						\
	}								\
} while (0)

#endif /* _ACLVAR_H */
