/* Author : Joshua Brindle <jbrindle@tresys.com>
 *	    Karl MacMillan <kmacmillan@tresys.com>
 *          Jason Tang     <jtang@tresys.com>
 *	Added support for binary policy modules
 *
 * Copyright (C) 2004 - 2005 Tresys Technology, LLC
 *	This program is free software; you can redistribute it and/or modify
 *  	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, version 2.
 */

#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include <sepol/policydb/policydb.h>
#include <sepol/policydb/avrule_block.h>
#include <sepol/policydb/conditional.h>

#include "queue.h"
#include "module_compiler.h"

union stack_item_u {
	avrule_block_t *avrule;
	cond_list_t *cond_list;
};

typedef struct scope_stack {
	union stack_item_u u;
	int type;		/* for above union: 1 = avrule block, 2 = conditional */
	avrule_decl_t *decl;	/* if in an avrule block, which
				 * declaration is current */
	avrule_t *last_avrule;
	int in_else;		/* if in an avrule block, within ELSE branch */
	int require_given;	/* 1 if this block had at least one require */
	struct scope_stack *parent, *child;
} scope_stack_t;

extern policydb_t *policydbp;
extern queue_t id_queue;
extern int yyerror(const char *msg);
__attribute__ ((format(printf, 1, 2)))
extern void yyerror2(const char *fmt, ...);

static int push_stack(int stack_type, ...);
static void pop_stack(void);

/* keep track of the last item added to the stack */
static scope_stack_t *stack_top = NULL;
static avrule_block_t *last_block;
static uint32_t next_decl_id = 1;

static const char * const flavor_str[SYM_NUM] = {
	[SYM_COMMONS] = "common",
	[SYM_CLASSES] = "class",
	[SYM_ROLES] = "role",
	[SYM_TYPES] = "type",
	[SYM_USERS] = "user",
	[SYM_BOOLS] = "bool",
	[SYM_LEVELS] = "level",
	[SYM_CATS] = "cat"
};

static void print_error_msg(int ret, uint32_t symbol_type)
{
	switch (ret) {
	case -3:
		yyerror("Out of memory!");
		break;
	case -2:
		yyerror2("Duplicate declaration of %s", flavor_str[symbol_type]);
		break;
	case -1:
		yyerror2("Could not declare %s here", flavor_str[symbol_type]);
		break;
	default:
		yyerror("Unknown error");
	}
}

int define_policy(int pass, int module_header_given)
{
	char *id;

	if (module_header_given) {
		if (policydbp->policy_type != POLICY_MOD) {
			yyerror
			    ("Module specification found while not building a policy module.\n");
			return -1;
		}

		if (pass == 2) {
			while ((id = queue_remove(id_queue)) != NULL)
				free(id);
		} else {
			id = (char *)queue_remove(id_queue);
			if (!id) {
				yyerror("no module name");
				return -1;
			}
			policydbp->name = id;
			if ((policydbp->version =
			     queue_remove(id_queue)) == NULL) {
				yyerror
				    ("Expected a module version but none was found.");
				return -1;
			}
		}
	} else {
		if (policydbp->policy_type == POLICY_MOD) {
			yyerror
			    ("Building a policy module, but no module specification found.\n");
			return -1;
		}
	}
	/* the first declaration within the global avrule
	   block will always have an id of 1 */
	next_decl_id = 2;

	/* reset the scoping stack */
	while (stack_top != NULL) {
		pop_stack();
	}
	if (push_stack(1, policydbp->global, policydbp->global->branch_list) ==
	    -1) {
		return -1;
	}
	last_block = policydbp->global;
	return 0;
}

/* Given the current parse stack, returns 1 if a declaration or require would
 * be allowed here or 0 if not.  For example, declarations and requirements are
 * not allowed in conditionals, so if there are any conditionals in the
 * current scope stack then this would return a 0.
 */
static int is_creation_allowed(void)
{
	if (stack_top->type != 1 || stack_top->in_else) {
		return 0;
	}
	return 1;
}

/* Attempt to declare or require a symbol within the current scope.
 * Returns:
 *  0: Success - Symbol had not been previously created.
 *  1: Success - Symbol had already been created and caller must free datum.
 * -1: Failure - Symbol cannot be created here
 * -2: Failure - Duplicate declaration or type/attribute mismatch
 * -3: Failure - Out of memory or some other error
 */
static int create_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum,
			 uint32_t * dest_value, uint32_t scope)
{
	avrule_decl_t *decl = stack_top->decl;
	int ret;

	if (!is_creation_allowed()) {
		return -1;
	}

	ret = symtab_insert(policydbp, symbol_type, key, datum, scope,
			    decl->decl_id, dest_value);

	if (ret == 1 && dest_value) {
		symtab_datum_t *s =
			hashtab_search(policydbp->symtab[symbol_type].table,
				       key);
		assert(s != NULL);

		if (symbol_type == SYM_LEVELS) {
			*dest_value = ((level_datum_t *)s)->level->sens;
		} else {
			*dest_value = s->value;
		}
	} else if (ret == -2) {
		return -2;
	} else if (ret < 0) {
		return -3;
	}

	return ret;
}

/* Attempt to declare a symbol within the current declaration.  If
 * currently within a non-conditional and in a non-else branch then
 * insert the symbol, return 0 on success if symbol was undeclared.
 * For roles and users, it is legal to have multiple declarations; as
 * such return 1 to indicate that caller must free() the datum because
 * it was not added.  If symbols may not be declared here return -1.
 * For duplicate declarations return -2.  For all else, including out
 * of memory, return -3.  Note that dest_value and datum_value might
 * not be restricted pointers. */
int declare_symbol(uint32_t symbol_type,
		   hashtab_key_t key, hashtab_datum_t datum,
		   uint32_t * dest_value, uint32_t * datum_value)
{
	avrule_decl_t *decl = stack_top->decl;
	int ret = create_symbol(symbol_type, key, datum, dest_value, SCOPE_DECL);

	if (ret < 0) {
		return ret;
	}

	if (ebitmap_set_bit(decl->declared.scope + symbol_type,
			    *datum_value - 1, 1)) {
		return -3;
	}

	return ret;
}

static int role_implicit_bounds(hashtab_t roles_tab,
				char *role_id, role_datum_t *role)
{
	role_datum_t *bounds;
	char *bounds_id, *delim;

	delim = strrchr(role_id, '.');
	if (!delim)
		return 0;	/* no implicit boundary */

	bounds_id = strdup(role_id);
	if (!bounds_id) {
		yyerror("out of memory");
		return -1;
	}
	bounds_id[(size_t)(delim - role_id)] = '\0';

	bounds = hashtab_search(roles_tab, bounds_id);
	if (!bounds) {
		yyerror2("role %s doesn't exist, is implicit bounds of %s",
			 bounds_id, role_id);
		return -1;
	}

	if (!role->bounds)
		role->bounds = bounds->s.value;
	else if (role->bounds != bounds->s.value) {
		yyerror2("role %s has inconsistent bounds %s/%s",
			 role_id, bounds_id,
			 policydbp->p_role_val_to_name[role->bounds - 1]);
		return -1;
	}
	free(bounds_id);

	return 0;
}

static int create_role(uint32_t scope, unsigned char isattr, role_datum_t **role, char **key)
{
	char *id = queue_remove(id_queue);
	role_datum_t *datum = NULL;
	int ret;
	uint32_t value;

	*role = NULL;
	*key = NULL;
	isattr = isattr ? ROLE_ATTRIB : ROLE_ROLE;

	if (id == NULL) {
		yyerror("no role name");
		return -1;
	}

	datum = malloc(sizeof(*datum));
	if (datum == NULL) {
		yyerror("Out of memory!");
		free(id);
		return -1;
	}

	role_datum_init(datum);
	datum->flavor = isattr;

	if (scope == SCOPE_DECL) {
		ret = declare_symbol(SYM_ROLES, id, datum, &value, &value);
	} else {
		ret = require_symbol(SYM_ROLES, id, datum, &value, &value);
	}

	datum->s.value = value;

	if (ret == 0) {
		*role = datum;
		*key = strdup(id);
		if (*key == NULL) {
			yyerror("Out of memory!");
			return -1;
		}
	} else if (ret == 1) {
		*role = hashtab_search(policydbp->symtab[SYM_ROLES].table, id);
		if (*role && (isattr != (*role)->flavor)) {
			yyerror2("Identifier %s used as both an attribute and a role",
				 id);
			free(id);
			role_datum_destroy(datum);
			free(datum);
			return -1;
		}
		*role = datum;
		*key = id;
	} else {
		print_error_msg(ret, SYM_ROLES);
		free(id);
		role_datum_destroy(datum);
		free(datum);
	}

	return ret;
}

role_datum_t *declare_role(unsigned char isattr)
{
	char *key = NULL;
	role_datum_t *role = NULL;
	role_datum_t *dest_role = NULL;
	hashtab_t roles_tab;
	int ret, ret2;

	ret = create_role(SCOPE_DECL, isattr, &role, &key);
	if (ret < 0) {
		return NULL;
	}

	/* create a new role_datum_t for this decl, if necessary */
	assert(stack_top->type == 1);

	if (stack_top->parent == NULL) {
		/* in parent, so use global symbol table */
		roles_tab = policydbp->p_roles.table;
	} else {
		roles_tab = stack_top->decl->p_roles.table;
	}

	dest_role = hashtab_search(roles_tab, key);
	if (dest_role == NULL) {
		if (ret == 0) {
			dest_role = malloc(sizeof(*dest_role));
			if (dest_role == NULL) {
				yyerror("Out of memory!");
				free(key);
				return NULL;
			}
			role_datum_init(dest_role);
			dest_role->s.value = role->s.value;
			dest_role->flavor = role->flavor;
		} else {
			dest_role = role;
		}
		ret2 = role_implicit_bounds(roles_tab, key, dest_role);
		if (ret2 != 0) {
			free(key);
			role_datum_destroy(dest_role);
			free(dest_role);
			return NULL;
		}
		ret2 = hashtab_insert(roles_tab, key, dest_role);
		if (ret2 != 0) {
			yyerror("Out of memory!");
			free(key);
			role_datum_destroy(dest_role);
			free(dest_role);
			return NULL;
		}
	} else {
		free(key);
		if (ret == 1) {
			role_datum_destroy(role);
			free(role);
		}
	}

	if (ret == 0) {
		ret2 = ebitmap_set_bit(&dest_role->dominates, dest_role->s.value - 1, 1);
		if (ret2 != 0) {
			yyerror("out of memory");
			return NULL;
		}
	}

	return dest_role;
}

static int create_type(uint32_t scope, unsigned char isattr, type_datum_t **type)
{
	char *id;
	type_datum_t *datum;
	int ret;
	uint32_t value = 0;

	*type = NULL;
	isattr = isattr ? TYPE_ATTRIB : TYPE_TYPE;

	id = (char *)queue_remove(id_queue);
	if (!id) {
		yyerror("no type/attribute name?");
		return -1;
	}
	if (strcmp(id, "self") == 0) {
		yyerror("\"self\" is a reserved type name.");
		free(id);
		return -1;
	}

	datum = malloc(sizeof(*datum));
	if (!datum) {
		yyerror("Out of memory!");
		free(id);
		return -1;
	}
	type_datum_init(datum);
	datum->primary = 1;
	datum->flavor = isattr;

	if (scope == SCOPE_DECL) {
		ret = declare_symbol(SYM_TYPES, id, datum, &value, &value);
	} else {
		ret = require_symbol(SYM_TYPES, id, datum, &value, &value);
	}

	if (ret == 0) {
		datum->s.value = value;
		*type = datum;
	} else if (ret == 1) {
		type_datum_destroy(datum);
		free(datum);
		*type = hashtab_search(policydbp->symtab[SYM_TYPES].table, id);
		if (*type && (isattr != (*type)->flavor)) {
			yyerror2("Identifier %s used as both an attribute and a type",
				 id);
			free(id);
			return -1;
		}
		free(id);
	} else {
		print_error_msg(ret, SYM_TYPES);
		free(id);
		type_datum_destroy(datum);
		free(datum);
	}

	return ret;
}

type_datum_t *declare_type(unsigned char primary, unsigned char isattr)
{
	type_datum_t *type = NULL;
	int ret = create_type(SCOPE_DECL, isattr, &type);

	if (ret == 0) {
		type->primary = primary;
	}

	return type;
}

static int user_implicit_bounds(hashtab_t users_tab,
				char *user_id, user_datum_t *user)
{
	user_datum_t *bounds;
	char *bounds_id, *delim;

	delim = strrchr(user_id, '.');
	if (!delim)
		return 0;	/* no implicit boundary */

	bounds_id = strdup(user_id);
	if (!bounds_id) {
		yyerror("out of memory");
		return -1;
	}
	bounds_id[(size_t)(delim - user_id)] = '\0';

	bounds = hashtab_search(users_tab, bounds_id);
	if (!bounds) {
		yyerror2("user %s doesn't exist, is implicit bounds of %s",
			 bounds_id, user_id);
		return -1;
	}

	if (!user->bounds)
		user->bounds = bounds->s.value;
	else if (user->bounds != bounds->s.value) {
		yyerror2("user %s has inconsistent bounds %s/%s",
			 user_id, bounds_id,
			 policydbp->p_role_val_to_name[user->bounds - 1]);
		return -1;
	}
	free(bounds_id);

	return 0;
}

static int create_user(uint32_t scope, user_datum_t **user, char **key)
{
	char *id = queue_remove(id_queue);
	user_datum_t *datum = NULL;
	int ret;
	uint32_t value;

	*user = NULL;
	*key = NULL;

	if (id == NULL) {
		yyerror("no user name");
		return -1;
	}

	datum = malloc(sizeof(*datum));
	if (datum == NULL) {
		yyerror("Out of memory!");
		free(id);
		return -1;
	}

	user_datum_init(datum);

	if (scope == SCOPE_DECL) {
		ret = declare_symbol(SYM_USERS, id, datum, &value, &value);
	} else {
		ret = require_symbol(SYM_USERS, id, datum, &value, &value);
	}

	datum->s.value = value;

	if (ret == 0) {
		*user = datum;
		*key = strdup(id);
		if (*key == NULL) {
			yyerror("Out of memory!");
			return -1;
		}
	} else if (ret == 1) {
		*user = datum;
		*key = id;
	} else {
		print_error_msg(ret, SYM_USERS);
		free(id);
		user_datum_destroy(datum);
		free(datum);
	}

	return ret;
}

user_datum_t *declare_user(void)
{
	char *key = NULL;
	user_datum_t *user = NULL;
	user_datum_t *dest_user = NULL;
	hashtab_t users_tab;
	int ret, ret2;

	ret = create_user(SCOPE_DECL, &user, &key);
	if (ret < 0) {
		return NULL;
	}

	/* create a new user_datum_t for this decl, if necessary */
	assert(stack_top->type == 1);

	if (stack_top->parent == NULL) {
		/* in parent, so use global symbol table */
		users_tab = policydbp->p_users.table;
	} else {
		users_tab = stack_top->decl->p_users.table;
	}

	dest_user = hashtab_search(users_tab, key);
	if (dest_user == NULL) {
		if (ret == 0) {
			dest_user = malloc(sizeof(*dest_user));
			if (dest_user == NULL) {
				yyerror("Out of memory!");
				free(key);
				return NULL;
			}
			user_datum_init(dest_user);
			dest_user->s.value = user->s.value;
		} else {
			dest_user = user;
		}
		ret2 = user_implicit_bounds(users_tab, key, dest_user);
		if (ret2 != 0) {
			free(key);
			user_datum_destroy(dest_user);
			free(dest_user);
			return NULL;
		}
		ret2 = hashtab_insert(users_tab, key, dest_user);
		if (ret2 != 0) {
			yyerror("Out of memory!");
			free(key);
			user_datum_destroy(dest_user);
			free(dest_user);
			return NULL;
		}
	} else {
		free(key);
		if (ret == 1) {
			user_datum_destroy(user);
			free(user);
		}
	}

	return dest_user;
}

/* Return a type_datum_t for the local avrule_decl with the given ID.
 * If it does not exist, create one with the same value as 'value'.
 * This function assumes that the ID is within scope.  c.f.,
 * is_id_in_scope().
 *
 * NOTE: this function usurps ownership of id afterwards.  The caller
 * shall not reference it nor free() it afterwards.
 */
type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr)
{
	type_datum_t *dest_typdatum;
	hashtab_t types_tab;
	assert(stack_top->type == 1);
	if (stack_top->parent == NULL) {
		/* in global, so use global symbol table */
		types_tab = policydbp->p_types.table;
	} else {
		types_tab = stack_top->decl->p_types.table;
	}
	dest_typdatum = hashtab_search(types_tab, id);
	if (!dest_typdatum) {
		dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
		if (dest_typdatum == NULL) {
			free(id);
			return NULL;
		}
		type_datum_init(dest_typdatum);
		dest_typdatum->s.value = value;
		dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
		dest_typdatum->primary = 1;
		if (hashtab_insert(types_tab, id, dest_typdatum)) {
			free(id);
			type_datum_destroy(dest_typdatum);
			free(dest_typdatum);
			return NULL;
		}

	} else {
		free(id);
		if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) {
			return NULL;
		}
	}
	return dest_typdatum;
}

/* Return a role_datum_t for the local avrule_decl with the given ID.
 * If it does not exist, create one with the same value as 'value'.
 * This function assumes that the ID is within scope.  c.f.,
 * is_id_in_scope().
 *
 * NOTE: this function usurps ownership of id afterwards.  The caller
 * shall not reference it nor free() it afterwards.
 */
role_datum_t *get_local_role(char *id, uint32_t value, unsigned char isattr)
{
	role_datum_t *dest_roledatum;
	hashtab_t roles_tab;

	assert(stack_top->type == 1);

	if (stack_top->parent == NULL) {
		/* in global, so use global symbol table */
		roles_tab = policydbp->p_roles.table;
	} else {
		roles_tab = stack_top->decl->p_roles.table;
	}

	dest_roledatum = hashtab_search(roles_tab, id);
	if (!dest_roledatum) {
		dest_roledatum = (role_datum_t *)malloc(sizeof(role_datum_t));
		if (dest_roledatum == NULL) {
			free(id);
			return NULL;
		}

		role_datum_init(dest_roledatum);
		dest_roledatum->s.value = value;
		dest_roledatum->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE;

		if (hashtab_insert(roles_tab, id, dest_roledatum)) {
			free(id);
			role_datum_destroy(dest_roledatum);
			free(dest_roledatum);
			return NULL;
		}
	} else {
		free(id);
		if (dest_roledatum->flavor != isattr ? ROLE_ATTRIB : ROLE_ROLE)
			return NULL;
	}
	
	return dest_roledatum;
}

/* Attempt to require a symbol within the current scope.  If currently
 * within an optional (and not its else branch), add the symbol to the
 * required list.  Return 0 on success, 1 if caller needs to free()
 * datum.  If symbols may not be declared here return -1.  For duplicate
 * declarations return -2.  For all else, including out of memory,
 * return -3..  Note that dest_value and datum_value might not be
 * restricted pointers.
 */
int require_symbol(uint32_t symbol_type,
		   hashtab_key_t key, hashtab_datum_t datum,
		   uint32_t * dest_value, uint32_t * datum_value)
{
	avrule_decl_t *decl = stack_top->decl;
	int ret = create_symbol(symbol_type, key, datum, dest_value, SCOPE_REQ);

	if (ret < 0) {
		return ret;
	}

	if (ebitmap_set_bit(decl->required.scope + symbol_type,
			    *datum_value - 1, 1)) {
		return -3;
	}

	stack_top->require_given = 1;
	return ret;
}

int add_perm_to_class(uint32_t perm_value, uint32_t class_value)
{
	avrule_decl_t *decl = stack_top->decl;
	scope_index_t *scope;

	assert(perm_value >= 1);
	assert(class_value >= 1);
	scope = &decl->required;
	if (class_value > scope->class_perms_len) {
		uint32_t i;
		ebitmap_t *new_map = realloc(scope->class_perms_map,
					     class_value * sizeof(*new_map));
		if (new_map == NULL) {
			return -1;
		}
		scope->class_perms_map = new_map;
		for (i = scope->class_perms_len; i < class_value; i++) {
			ebitmap_init(scope->class_perms_map + i);
		}
		scope->class_perms_len = class_value;
	}
	if (ebitmap_set_bit(scope->class_perms_map + class_value - 1,
			    perm_value - 1, 1)) {
		return -1;
	}
	return 0;
}

static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
			__attribute__ ((unused)))
{
	if (key)
		free(key);
	free(datum);
	return 0;
}

static void class_datum_destroy(class_datum_t * cladatum)
{
	if (cladatum != NULL) {
		hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
		hashtab_destroy(cladatum->permissions.table);
		free(cladatum);
	}
}

int require_class(int pass)
{
	char *class_id = queue_remove(id_queue);
	char *perm_id = NULL;
	class_datum_t *datum = NULL;
	perm_datum_t *perm = NULL;
	int ret;

	if (pass == 2) {
		free(class_id);
		while ((perm_id = queue_remove(id_queue)) != NULL)
			free(perm_id);
		return 0;
	}

	/* first add the class if it is not already there */
	if (class_id == NULL) {
		yyerror("no class name for class definition?");
		return -1;
	}

	if ((datum = calloc(1, sizeof(*datum))) == NULL ||
	    symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) {
		yyerror("Out of memory!");
		class_datum_destroy(datum);
		return -1;
	}
	ret =
	    require_symbol(SYM_CLASSES, class_id, datum, &datum->s.value,
			   &datum->s.value);
	if (ret < 0) {
		print_error_msg(ret, SYM_CLASSES);
		free(class_id);
		class_datum_destroy(datum);
		return -1;
	}

	if (ret == 0) {
		/* a new class was added; reindex everything */
		if (policydb_index_classes(policydbp)) {
			yyerror("Out of memory!");
			return -1;
		}
	} else {
		class_datum_destroy(datum);
		datum = hashtab_search(policydbp->p_classes.table, class_id);
		assert(datum);	/* the class datum should have existed */
		free(class_id);
	}

	/* now add each of the permissions to this class's requirements */
	while ((perm_id = queue_remove(id_queue)) != NULL) {
		int allocated = 0;

		/* Is the permission already in the table? */
		perm = hashtab_search(datum->permissions.table, perm_id);
		if (!perm && datum->comdatum)
			perm =
			    hashtab_search(datum->comdatum->permissions.table,
					   perm_id);
		if (perm) {
			/* Yes, drop the name. */
			free(perm_id);
		} else {
			/* No - allocate and insert an entry for it. */
			if (policydbp->policy_type == POLICY_BASE) {
				yyerror2
				    ("Base policy - require of permission %s without prior declaration.",
				     perm_id);
				free(perm_id);
				return -1;
			}
			allocated = 1;
			if ((perm = malloc(sizeof(*perm))) == NULL) {
				yyerror("Out of memory!");
				free(perm_id);
				return -1;
			}
			memset(perm, 0, sizeof(*perm));
			ret =
			    hashtab_insert(datum->permissions.table, perm_id,
					   perm);
			if (ret) {
				yyerror("Out of memory!");
				free(perm_id);
				free(perm);
				return -1;
			}
			perm->s.value = datum->permissions.nprim + 1;
		}

		if (add_perm_to_class(perm->s.value, datum->s.value) == -1) {
			yyerror("Out of memory!");
			return -1;
		}

		/* Update number of primitives if we allocated one. */
		if (allocated)
			datum->permissions.nprim++;
	}
	return 0;
}

static int require_role_or_attribute(int pass, unsigned char isattr)
{
	char *key = NULL;
	role_datum_t *role = NULL;
	int ret;

	if (pass == 2) {
		free(queue_remove(id_queue));
		return 0;
	}

	ret = create_role(SCOPE_REQ, isattr, &role, &key);
	if (ret < 0) {
		return -1;
	}

	free(key);

	if (ret == 0) {
		ret = ebitmap_set_bit(&role->dominates, role->s.value - 1, 1);
		if (ret != 0) {
			yyerror("Out of memory");
			return -1;
		}
	} else {
		role_datum_destroy(role);
		free(role);
	}

	return 0;
}

int require_role(int pass)
{
	return require_role_or_attribute(pass, 0);
}

int require_attribute_role(int pass)
{
	return require_role_or_attribute(pass, 1);
}

static int require_type_or_attribute(int pass, unsigned char isattr)
{
	type_datum_t *type = NULL;
	int ret;

	if (pass == 2) {
		free(queue_remove(id_queue));
		return 0;
	}

	ret = create_type(SCOPE_REQ, isattr, &type);

	if (ret < 0) {
		return -1;
	}

	return 0;
}

int require_type(int pass)
{
	return require_type_or_attribute(pass, 0);
}

int require_attribute(int pass)
{
	return require_type_or_attribute(pass, 1);
}

int require_user(int pass)
{
	char *key = NULL;
	user_datum_t *user = NULL;
	int ret;

	if (pass == 1) {
		free(queue_remove(id_queue));
		return 0;
	}

	ret = create_user(SCOPE_REQ, &user, &key);
	if (ret < 0) {
		return -1;
	}

	free(key);

	if (ret == 1) {
		user_datum_destroy(user);
		free(user);
	}

	return 0;
}

static int require_bool_tunable(int pass, int is_tunable)
{
	char *id = queue_remove(id_queue);
	cond_bool_datum_t *booldatum = NULL;
	int retval;
	if (pass == 2) {
		free(id);
		return 0;
	}
	if (id == NULL) {
		yyerror("no boolean name");
		return -1;
	}
	if ((booldatum = calloc(1, sizeof(*booldatum))) == NULL) {
		cond_destroy_bool(id, booldatum, NULL);
		yyerror("Out of memory!");
		return -1;
	}
	if (is_tunable)
		booldatum->flags |= COND_BOOL_FLAGS_TUNABLE;
	retval =
	    require_symbol(SYM_BOOLS, id, (hashtab_datum_t *) booldatum,
			   &booldatum->s.value, &booldatum->s.value);
	if (retval != 0) {
		cond_destroy_bool(id, booldatum, NULL);
		if (retval < 0) {
			print_error_msg(retval, SYM_BOOLS);
			return -1;
		}
	}

	return 0;
}

int require_bool(int pass)
{
	return require_bool_tunable(pass, 0);
}

int require_tunable(int pass)
{
	return require_bool_tunable(pass, 1);
}

int require_sens(int pass)
{
	char *id = queue_remove(id_queue);
	level_datum_t *level = NULL;
	int retval;
	if (pass == 2) {
		free(id);
		return 0;
	}
	if (!id) {
		yyerror("no sensitivity name");
		return -1;
	}
	level = malloc(sizeof(level_datum_t));
	if (!level) {
		free(id);
		yyerror("Out of memory!");
		return -1;
	}
	level_datum_init(level);
	level->level = malloc(sizeof(mls_level_t));
	if (!level->level) {
		free(id);
		level_datum_destroy(level);
		free(level);
		yyerror("Out of memory!");
		return -1;
	}
	mls_level_init(level->level);
	retval = require_symbol(SYM_LEVELS, id, (hashtab_datum_t *) level,
				&level->level->sens, &level->level->sens);
	if (retval != 0) {
		free(id);
		mls_level_destroy(level->level);
		free(level->level);
		level_datum_destroy(level);
		free(level);
		if (retval < 0) {
			print_error_msg(retval, SYM_LEVELS);
			return -1;
		}
	}

	return 0;
}

int require_cat(int pass)
{
	char *id = queue_remove(id_queue);
	cat_datum_t *cat = NULL;
	int retval;
	if (pass == 2) {
		free(id);
		return 0;
	}
	if (!id) {
		yyerror("no category name");
		return -1;
	}
	cat = malloc(sizeof(cat_datum_t));
	if (!cat) {
		free(id);
		yyerror("Out of memory!");
		return -1;
	}
	cat_datum_init(cat);

	retval = require_symbol(SYM_CATS, id, (hashtab_datum_t *) cat,
				&cat->s.value, &cat->s.value);
	if (retval != 0) {
		free(id);
		cat_datum_destroy(cat);
		free(cat);
		if (retval < 0) {
			print_error_msg(retval, SYM_CATS);
			return -1;
		}
	}

	return 0;
}

static int is_scope_in_stack(scope_datum_t * scope, scope_stack_t * stack)
{
	uint32_t i;
	if (stack == NULL) {
		return 0;	/* no matching scope found */
	}
	if (stack->type == 1) {
		avrule_decl_t *decl = stack->decl;
		for (i = 0; i < scope->decl_ids_len; i++) {
			if (scope->decl_ids[i] == decl->decl_id) {
				return 1;
			}
		}
	} else {
		/* note that conditionals can't declare or require
		 * symbols, so skip this level */
	}

	/* not within scope of this stack, so try its parent */
	return is_scope_in_stack(scope, stack->parent);
}

int is_id_in_scope(uint32_t symbol_type, hashtab_key_t id)
{
	scope_datum_t *scope =
	    (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type].
					     table, id);
	if (scope == NULL) {
		return 1;	/* id is not known, so return success */
	}
	return is_scope_in_stack(scope, stack_top);
}

static int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value,
				  scope_index_t * scope)
{
	if (class_value > scope->class_perms_len) {
		return 1;
	}
	if (ebitmap_get_bit(scope->class_perms_map + class_value - 1,
			    perm_value - 1)) {
		return 1;
	}
	return 0;
}

static int is_perm_in_stack(uint32_t perm_value, uint32_t class_value,
			    scope_stack_t * stack)
{
	if (stack == NULL) {
		return 0;	/* no matching scope found */
	}
	if (stack->type == 1) {
		avrule_decl_t *decl = stack->decl;
		if (is_perm_in_scope_index
		    (perm_value, class_value, &decl->required)
		    || is_perm_in_scope_index(perm_value, class_value,
					      &decl->declared)) {
			return 1;
		}
	} else {
		/* note that conditionals can't declare or require
		 * symbols, so skip this level */
	}

	/* not within scope of this stack, so try its parent */
	return is_perm_in_stack(perm_value, class_value, stack->parent);
}

int is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id)
{
	class_datum_t *cladatum =
	    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
					     class_id);
	perm_datum_t *perdatum;
	if (cladatum == NULL) {
		return 1;
	}
	perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table,
						   perm_id);
	if (perdatum == NULL) {
		return 1;
	}
	return is_perm_in_stack(perdatum->s.value, cladatum->s.value,
				stack_top);
}

cond_list_t *get_current_cond_list(cond_list_t * cond)
{
	/* FIX ME: do something different here if in a nested
	 * conditional? */
	avrule_decl_t *decl = stack_top->decl;
	return get_decl_cond_list(policydbp, decl, cond);
}

/* Append the new conditional node to the existing ones.  During
 * expansion the list will be reversed -- i.e., the last AV rule will
 * be the first one listed in the policy.  This matches the behavior
 * of the upstream compiler. */
void append_cond_list(cond_list_t * cond)
{
	cond_list_t *old_cond = get_current_cond_list(cond);
	avrule_t *tmp;
	assert(old_cond != NULL);	/* probably out of memory */
	if (old_cond->avtrue_list == NULL) {
		old_cond->avtrue_list = cond->avtrue_list;
	} else {
		for (tmp = old_cond->avtrue_list; tmp->next != NULL;
		     tmp = tmp->next) ;
		tmp->next = cond->avtrue_list;
	}
	if (old_cond->avfalse_list == NULL) {
		old_cond->avfalse_list = cond->avfalse_list;
	} else {
		for (tmp = old_cond->avfalse_list; tmp->next != NULL;
		     tmp = tmp->next) ;
		tmp->next = cond->avfalse_list;
	}

	old_cond->flags |= cond->flags;
}

void append_avrule(avrule_t * avrule)
{
	avrule_decl_t *decl = stack_top->decl;

	/* currently avrules follow a completely different code path
	 * for handling avrules and compute types
	 * (define_cond_avrule_te_avtab, define_cond_compute_type);
	 * therefore there ought never be a conditional on top of the
	 * scope stack */
	assert(stack_top->type == 1);

	if (stack_top->last_avrule == NULL) {
		decl->avrules = avrule;
	} else {
		stack_top->last_avrule->next = avrule;
	}
	stack_top->last_avrule = avrule;
}

/* this doesn't actually append, but really prepends it */
void append_role_trans(role_trans_rule_t * role_tr_rules)
{
	avrule_decl_t *decl = stack_top->decl;

	/* role transitions are not allowed within conditionals */
	assert(stack_top->type == 1);

	role_tr_rules->next = decl->role_tr_rules;
	decl->role_tr_rules = role_tr_rules;
}

/* this doesn't actually append, but really prepends it */
void append_role_allow(role_allow_rule_t * role_allow_rules)
{
	avrule_decl_t *decl = stack_top->decl;

	/* role allows are not allowed within conditionals */
	assert(stack_top->type == 1);

	role_allow_rules->next = decl->role_allow_rules;
	decl->role_allow_rules = role_allow_rules;
}

/* this doesn't actually append, but really prepends it */
void append_filename_trans(filename_trans_rule_t * filename_trans_rules)
{
	avrule_decl_t *decl = stack_top->decl;

	/* filename transitions are not allowed within conditionals */
	assert(stack_top->type == 1);

	filename_trans_rules->next = decl->filename_trans_rules;
	decl->filename_trans_rules = filename_trans_rules;
}

/* this doesn't actually append, but really prepends it */
void append_range_trans(range_trans_rule_t * range_tr_rules)
{
	avrule_decl_t *decl = stack_top->decl;

	/* range transitions are not allowed within conditionals */
	assert(stack_top->type == 1);

	range_tr_rules->next = decl->range_tr_rules;
	decl->range_tr_rules = range_tr_rules;
}

int begin_optional(int pass)
{
	avrule_block_t *block = NULL;
	avrule_decl_t *decl;
	if (pass == 1) {
		/* allocate a new avrule block for this optional block */
		if ((block = avrule_block_create()) == NULL ||
		    (decl = avrule_decl_create(next_decl_id)) == NULL) {
			goto cleanup;
		}
		block->flags |= AVRULE_OPTIONAL;
		block->branch_list = decl;
		last_block->next = block;
	} else {
		/* select the next block from the chain built during pass 1 */
		block = last_block->next;
		assert(block != NULL &&
		       block->branch_list != NULL &&
		       block->branch_list->decl_id == next_decl_id);
		decl = block->branch_list;
	}
	if (push_stack(1, block, decl) == -1) {
		goto cleanup;
	}
	stack_top->last_avrule = NULL;
	last_block = block;
	next_decl_id++;
	return 0;
      cleanup:
	yyerror("Out of memory!");
	avrule_block_destroy(block);
	return -1;
}

int end_optional(int pass __attribute__ ((unused)))
{
	/* once nested conditionals are allowed, do the stack unfolding here */
	pop_stack();
	return 0;
}

int begin_optional_else(int pass)
{
	avrule_decl_t *decl;
	assert(stack_top->type == 1 && stack_top->in_else == 0);
	if (pass == 1) {
		/* allocate a new declaration and add it to the
		 * current chain */
		if ((decl = avrule_decl_create(next_decl_id)) == NULL) {
			yyerror("Out of memory!");
			return -1;
		}
		stack_top->decl->next = decl;
	} else {
		/* pick the (hopefully last) declaration of this
		   avrule block, built from pass 1 */
		decl = stack_top->decl->next;
		assert(decl != NULL &&
		       decl->next == NULL && decl->decl_id == next_decl_id);
	}
	stack_top->in_else = 1;
	stack_top->decl = decl;
	stack_top->last_avrule = NULL;
	stack_top->require_given = 0;
	next_decl_id++;
	return 0;
}

static int copy_requirements(avrule_decl_t * dest, scope_stack_t * stack)
{
	uint32_t i;
	if (stack == NULL) {
		return 0;
	}
	if (stack->type == 1) {
		scope_index_t *src_scope = &stack->decl->required;
		scope_index_t *dest_scope = &dest->required;
		for (i = 0; i < SYM_NUM; i++) {
			ebitmap_t *src_bitmap = &src_scope->scope[i];
			ebitmap_t *dest_bitmap = &dest_scope->scope[i];
			if (ebitmap_union(dest_bitmap, src_bitmap)) {
				yyerror("Out of memory!");
				return -1;
			}
		}
		/* now copy class permissions */
		if (src_scope->class_perms_len > dest_scope->class_perms_len) {
			ebitmap_t *new_map =
			    realloc(dest_scope->class_perms_map,
				    src_scope->class_perms_len *
				    sizeof(*new_map));
			if (new_map == NULL) {
				yyerror("Out of memory!");
				return -1;
			}
			dest_scope->class_perms_map = new_map;
			for (i = dest_scope->class_perms_len;
			     i < src_scope->class_perms_len; i++) {
				ebitmap_init(dest_scope->class_perms_map + i);
			}
			dest_scope->class_perms_len =
			    src_scope->class_perms_len;
		}
		for (i = 0; i < src_scope->class_perms_len; i++) {
			ebitmap_t *src_bitmap = &src_scope->class_perms_map[i];
			ebitmap_t *dest_bitmap =
			    &dest_scope->class_perms_map[i];
			if (ebitmap_union(dest_bitmap, src_bitmap)) {
				yyerror("Out of memory!");
				return -1;
			}
		}
	}
	return copy_requirements(dest, stack->parent);
}

/* During pass 1, check that at least one thing was required within
 * this block, for those places where a REQUIRED is necessary.  During
 * pass 2, have this block inherit its parents' requirements.  Return
 * 0 on success, -1 on failure. */
int end_avrule_block(int pass)
{
	avrule_decl_t *decl = stack_top->decl;
	assert(stack_top->type == 1);
	if (pass == 2) {
		/* this avrule_decl inherits all of its parents'
		 * requirements */
		if (copy_requirements(decl, stack_top->parent) == -1) {
			return -1;
		}
		return 0;
	}
	if (!stack_top->in_else && !stack_top->require_given) {
		if (policydbp->policy_type == POLICY_BASE
		    && stack_top->parent != NULL) {
			/* if this is base no require should be in the global block */
			return 0;
		} else {
			/* non-ELSE branches must have at least one thing required */
			yyerror("This block has no require section.");
			return -1;
		}
	}
	return 0;
}

/* Push a new scope on to the stack and update the 'last' pointer.
 * Return 0 on success, -1 if out * of memory. */
static int push_stack(int stack_type, ...)
{
	scope_stack_t *s = calloc(1, sizeof(*s));
	va_list ap;
	if (s == NULL) {
		return -1;
	}
	va_start(ap, stack_type);
	switch (s->type = stack_type) {
	case 1:{
			s->u.avrule = va_arg(ap, avrule_block_t *);
			s->decl = va_arg(ap, avrule_decl_t *);
			break;
		}
	case 2:{
			s->u.cond_list = va_arg(ap, cond_list_t *);
			break;
		}
	default:
		/* invalid stack type given */
		assert(0);
	}
	va_end(ap);
	s->parent = stack_top;
	s->child = NULL;
	stack_top = s;
	return 0;
}

/* Pop off the most recently added from the stack.  Update the 'last'
 * pointer. */
static void pop_stack(void)
{
	scope_stack_t *parent;
	assert(stack_top != NULL);
	parent = stack_top->parent;
	if (parent != NULL) {
		parent->child = NULL;
	}
	free(stack_top);
	stack_top = parent;
}
