/* Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
 *	    Joshua Brindle <jbrindle@tresys.com>
 *          Jason Tang <jtang@tresys.com>
 *
 * Copyright (C) 2004-2005 Tresys Technology, LLC
 * Copyright (C) 2007 Red Hat, Inc.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <sepol/policydb/policydb.h>
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/hashtab.h>
#include <sepol/policydb/avrule_block.h>
#include <sepol/policydb/link.h>
#include <sepol/policydb/util.h>

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

#include "debug.h"

#undef min
#define min(a,b) (((a) < (b)) ? (a) : (b))

typedef struct policy_module {
	policydb_t *policy;
	uint32_t num_decls;
	uint32_t *map[SYM_NUM];
	uint32_t *avdecl_map;
	uint32_t **perm_map;
	uint32_t *perm_map_len;

	/* a pointer to within the base module's avrule_block chain to
	 * where this module's global now resides */
	avrule_block_t *base_global;
} policy_module_t;

typedef struct link_state {
	int verbose;
	policydb_t *base;
	avrule_block_t *last_avrule_block, *last_base_avrule_block;
	uint32_t next_decl_id, current_decl_id;

	/* temporary variables, used during hashtab_map() calls */
	policy_module_t *cur;
	char *cur_mod_name;
	avrule_decl_t *dest_decl;
	class_datum_t *src_class, *dest_class;
	char *dest_class_name;
	char dest_class_req;	/* flag indicating the class was not declared */
	uint32_t symbol_num;
	/* used to report the name of the module if dependancy error occurs */
	policydb_t **decl_to_mod;

	/* error reporting fields */
	sepol_handle_t *handle;
} link_state_t;

typedef struct missing_requirement {
	uint32_t symbol_type;
	uint32_t symbol_value;
	uint32_t perm_value;
} missing_requirement_t;

static const char *symtab_names[SYM_NUM] = {
	"common", "class", "role", "type/attribute", "user",
	"bool", "level", "category"
};

/* Deallocates all elements within a module, but NOT the policydb_t
 * structure within, as well as the pointer itself. */
static void policy_module_destroy(policy_module_t * mod)
{
	unsigned int i;
	if (mod == NULL) {
		return;
	}
	for (i = 0; i < SYM_NUM; i++) {
		free(mod->map[i]);
	}
	for (i = 0; mod->perm_map != NULL && i < mod->policy->p_classes.nprim;
	     i++) {
		free(mod->perm_map[i]);
	}
	free(mod->perm_map);
	free(mod->perm_map_len);
	free(mod->avdecl_map);
	free(mod);
}

/***** functions that copy identifiers from a module to base *****/

/* Note: there is currently no scoping for permissions, which causes some
 * strange side-effects. The current approach is this:
 *
 * a) perm is required and the class _and_ perm are declared in base: only add a mapping.
 * b) perm is required and the class and perm are _not_ declared in base: simply add the permissions
 *    to the object class. This means that the requirements for the decl are the union of the permissions
 *    required for all decls, but who cares.
 * c) perm is required, the class is declared in base, but the perm is not present. Nothing we can do
 *    here because we can't mark a single permission as required, so we bail with a requirement error
 *    _even_ if we are in an optional.
 *
 * A is correct behavior, b is wrong but not too bad, c is totall wrong for optionals. Fixing this requires
 * a format change.
 */
static int permission_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
				    void *data)
{
	char *perm_id = key, *new_id = NULL;
	perm_datum_t *perm, *new_perm = NULL, *dest_perm;
	link_state_t *state = (link_state_t *) data;

	class_datum_t *src_class = state->src_class;
	class_datum_t *dest_class = state->dest_class;
	policy_module_t *mod = state->cur;
	uint32_t sclassi = src_class->s.value - 1;
	int ret;

	perm = (perm_datum_t *) datum;
	dest_perm = hashtab_search(dest_class->permissions.table, perm_id);
	if (dest_perm == NULL && dest_class->comdatum != NULL) {
		dest_perm =
		    hashtab_search(dest_class->comdatum->permissions.table,
				   perm_id);
	}

	if (dest_perm == NULL) {
		/* If the object class was not declared in the base, add the perm
		 * to the object class. */
		if (state->dest_class_req) {
			/* If the class was required (not declared), insert the new permission */
			new_id = strdup(perm_id);
			if (new_id == NULL) {
				ERR(state->handle, "Memory error");
				ret = SEPOL_ERR;
				goto err;
			}
			new_perm =
			    (perm_datum_t *) calloc(1, sizeof(perm_datum_t));
			if (new_perm == NULL) {
				ERR(state->handle, "Memory error");
				ret = SEPOL_ERR;
				goto err;
			}
			ret = hashtab_insert(dest_class->permissions.table,
					     (hashtab_key_t) new_id,
					     (hashtab_datum_t) new_perm);
			if (ret) {
				ERR(state->handle,
				    "could not insert permission into class\n");
				goto err;
			}
			new_perm->s.value = dest_class->permissions.nprim + 1;
			dest_perm = new_perm;
		} else {
			/* this is case c from above */
			ERR(state->handle,
			    "Module %s depends on permission %s in class %s, not satisfied",
			    state->cur_mod_name, perm_id,
			    state->dest_class_name);
			return SEPOL_EREQ;
		}
	}

	/* build the mapping for permissions encompassing this class.
	 * unlike symbols, the permission map translates between
	 * module permission bit to target permission bit.  that bit
	 * may have originated from the class -or- it could be from
	 * the class's common parent.*/
	if (perm->s.value > mod->perm_map_len[sclassi]) {
		uint32_t *newmap = calloc(perm->s.value, sizeof(*newmap));
		if (newmap == NULL) {
			ERR(state->handle, "Out of memory!");
			return -1;
		}
		memcpy(newmap, mod->perm_map[sclassi],
		       mod->perm_map_len[sclassi] * sizeof(*newmap));
		free(mod->perm_map[sclassi]);
		mod->perm_map[sclassi] = newmap;
		mod->perm_map_len[sclassi] = perm->s.value;
	}
	mod->perm_map[sclassi][perm->s.value - 1] = dest_perm->s.value;

	return 0;
      err:
	free(new_id);
	free(new_perm);
	return ret;
}

static int class_copy_default_new_object(link_state_t *state,
					 class_datum_t *olddatum,
					 class_datum_t *newdatum)
{
	if (olddatum->default_user) {
		if (newdatum->default_user && olddatum->default_user != newdatum->default_user) {
			ERR(state->handle, "Found conflicting default user definitions");
			return SEPOL_ENOTSUP;
		}
		newdatum->default_user = olddatum->default_user;
	}
	if (olddatum->default_role) {
		if (newdatum->default_role && olddatum->default_role != newdatum->default_role) {
			ERR(state->handle, "Found conflicting default role definitions");
			return SEPOL_ENOTSUP;
		}
		newdatum->default_role = olddatum->default_role;
	}
	if (olddatum->default_type) {
		if (newdatum->default_type && olddatum->default_type != newdatum->default_type) {
			ERR(state->handle, "Found conflicting default type definitions");
			return SEPOL_ENOTSUP;
		}
		newdatum->default_type = olddatum->default_type;
	}
	if (olddatum->default_range) {
		if (newdatum->default_range && olddatum->default_range != newdatum->default_range) {
			ERR(state->handle, "Found conflicting default range definitions");
			return SEPOL_ENOTSUP;
		}
		newdatum->default_range = olddatum->default_range;
	}
	return 0;
}

static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			       void *data)
{
	char *id = key, *new_id = NULL;
	class_datum_t *cladatum, *new_class = NULL;
	link_state_t *state = (link_state_t *) data;
	scope_datum_t *scope = NULL;
	int ret;

	cladatum = (class_datum_t *) datum;
	state->dest_class_req = 0;

	new_class = hashtab_search(state->base->p_classes.table, id);
	/* If there is not an object class already in the base symtab that means
	 * that either a) a module is trying to declare a new object class (which
	 * the compiler should prevent) or b) an object class was required that is
	 * not in the base.
	 */
	if (new_class == NULL) {
		scope =
		    hashtab_search(state->cur->policy->p_classes_scope.table,
				   id);
		if (scope == NULL) {
			ret = SEPOL_ERR;
			goto err;
		}
		if (scope->scope == SCOPE_DECL) {
			/* disallow declarations in modules */
			ERR(state->handle,
			    "%s: Modules may not yet declare new classes.",
			    state->cur_mod_name);
			ret = SEPOL_ENOTSUP;
			goto err;
		} else {
			/* It would be nice to error early here because the requirement is
			 * not met, but we cannot because the decl might be optional (in which
			 * case we should record the requirement so that it is just turned
			 * off). Note: this will break horribly if modules can declare object
			 * classes because the class numbers will be all wrong (i.e., they
			 * might be assigned in the order they were required rather than the
			 * current scheme which ensures correct numbering by ordering the 
			 * declarations properly). This can't be fixed until some infrastructure
			 * for querying the object class numbers is in place. */
			state->dest_class_req = 1;
			new_class =
			    (class_datum_t *) calloc(1, sizeof(class_datum_t));
			if (new_class == NULL) {
				ERR(state->handle, "Memory error\n");
				ret = SEPOL_ERR;
				goto err;
			}
			if (symtab_init
			    (&new_class->permissions, PERM_SYMTAB_SIZE)) {
				ret = SEPOL_ERR;
				goto err;
			}
			new_id = strdup(id);
			if (new_id == NULL) {
				ERR(state->handle, "Memory error\n");
				symtab_destroy(&new_class->permissions);
				ret = SEPOL_ERR;
				goto err;
			}
			ret = hashtab_insert(state->base->p_classes.table,
					     (hashtab_key_t) new_id,
					     (hashtab_datum_t) new_class);
			if (ret) {
				ERR(state->handle,
				    "could not insert new class into symtab");
				symtab_destroy(&new_class->permissions);
				goto err;
			}
			new_class->s.value = ++(state->base->p_classes.nprim);
		}
	}

	state->cur->map[SYM_CLASSES][cladatum->s.value - 1] =
	    new_class->s.value;

	/* copy permissions */
	state->src_class = cladatum;
	state->dest_class = new_class;
	state->dest_class_name = (char *)key;

	/* copy default new object rules */
	ret = class_copy_default_new_object(state, cladatum, new_class);
	if (ret)
		return ret;

	ret =
	    hashtab_map(cladatum->permissions.table, permission_copy_callback,
			state);
	if (ret != 0) {
		return ret;
	}

	return 0;
      err:
	free(new_class);
	free(new_id);
	return ret;
}

static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			      void *data)
{
	int ret;
	char *id = key, *new_id = NULL;
	role_datum_t *role, *base_role, *new_role = NULL;
	link_state_t *state = (link_state_t *) data;

	role = (role_datum_t *) datum;

	base_role = hashtab_search(state->base->p_roles.table, id);
	if (base_role != NULL) {
		/* role already exists.  check that it is what this
		 * module expected.  duplicate declarations (e.g., two
		 * modules both declare role foo_r) is checked during
		 * scope_copy_callback(). */
		if (role->flavor == ROLE_ATTRIB
		    && base_role->flavor != ROLE_ATTRIB) {
			ERR(state->handle,
			    "%s: Expected %s to be a role attribute, but it was already declared as a regular role.",
			    state->cur_mod_name, id);
			return -1;
		} else if (role->flavor != ROLE_ATTRIB
			   && base_role->flavor == ROLE_ATTRIB) {
			ERR(state->handle,
			    "%s: Expected %s to be a regular role, but it was already declared as a role attribute.",
			    state->cur_mod_name, id);
			return -1;
		}
	} else {
		if (state->verbose)
			INFO(state->handle, "copying role %s", id);

		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}

		if ((new_role =
		     (role_datum_t *) malloc(sizeof(*new_role))) == NULL) {
			goto cleanup;
		}
		role_datum_init(new_role);

		/* new_role's dominates, types and roles field will be copied
		 * during role_fix_callback() */
		new_role->flavor = role->flavor;
		new_role->s.value = state->base->p_roles.nprim + 1;

		ret = hashtab_insert(state->base->p_roles.table,
				     (hashtab_key_t) new_id,
				     (hashtab_datum_t) new_role);
		if (ret) {
			goto cleanup;
		}
		state->base->p_roles.nprim++;
		base_role = new_role;
	}

	if (state->dest_decl) {
		new_id = NULL;
		if ((new_role = malloc(sizeof(*new_role))) == NULL) {
			goto cleanup;
		}
		role_datum_init(new_role);
		new_role->flavor = base_role->flavor;
		new_role->s.value = base_role->s.value;
		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}
		if (hashtab_insert
		    (state->dest_decl->p_roles.table, new_id, new_role)) {
			goto cleanup;
		}
		state->dest_decl->p_roles.nprim++;
	}

	state->cur->map[SYM_ROLES][role->s.value - 1] = base_role->s.value;
	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	role_datum_destroy(new_role);
	free(new_id);
	free(new_role);
	return -1;
}

/* Copy types and attributes from a module into the base module. The
 * attributes are copied, but the types that make up this attribute
 * are delayed type_fix_callback(). */
static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			      void *data)
{
	int ret;
	char *id = key, *new_id = NULL;
	type_datum_t *type, *base_type, *new_type = NULL;
	link_state_t *state = (link_state_t *) data;

	type = (type_datum_t *) datum;
	if ((type->flavor == TYPE_TYPE && !type->primary)
	    || type->flavor == TYPE_ALIAS) {
		/* aliases are handled later, in alias_copy_callback() */
		return 0;
	}

	base_type = hashtab_search(state->base->p_types.table, id);
	if (base_type != NULL) {
		/* type already exists.  check that it is what this
		 * module expected.  duplicate declarations (e.g., two
		 * modules both declare type foo_t) is checked during
		 * scope_copy_callback(). */
		if (type->flavor == TYPE_ATTRIB
		    && base_type->flavor != TYPE_ATTRIB) {
			ERR(state->handle,
			    "%s: Expected %s to be an attribute, but it was already declared as a type.",
			    state->cur_mod_name, id);
			return -1;
		} else if (type->flavor != TYPE_ATTRIB
			   && base_type->flavor == TYPE_ATTRIB) {
			ERR(state->handle,
			    "%s: Expected %s to be a type, but it was already declared as an attribute.",
			    state->cur_mod_name, id);
			return -1;
		}
		/* permissive should pass to the base type */
		base_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE);
	} else {
		if (state->verbose)
			INFO(state->handle, "copying type %s", id);

		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}

		if ((new_type =
		     (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) {
			goto cleanup;
		}
		new_type->primary = type->primary;
		new_type->flags = type->flags;
		new_type->flavor = type->flavor;
		/* for attributes, the writing of new_type->types is
		   done in type_fix_callback() */

		new_type->s.value = state->base->p_types.nprim + 1;

		ret = hashtab_insert(state->base->p_types.table,
				     (hashtab_key_t) new_id,
				     (hashtab_datum_t) new_type);
		if (ret) {
			goto cleanup;
		}
		state->base->p_types.nprim++;
		base_type = new_type;
	}

	if (state->dest_decl) {
		new_id = NULL;
		if ((new_type = calloc(1, sizeof(*new_type))) == NULL) {
			goto cleanup;
		}
		new_type->primary = type->primary;
		new_type->flavor = type->flavor;
		new_type->flags = type->flags;
		new_type->s.value = base_type->s.value;
		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}
		if (hashtab_insert
		    (state->dest_decl->p_types.table, new_id, new_type)) {
			goto cleanup;
		}
		state->dest_decl->p_types.nprim++;
	}

	state->cur->map[SYM_TYPES][type->s.value - 1] = base_type->s.value;
	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	free(new_id);
	free(new_type);
	return -1;
}

static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			      void *data)
{
	int ret;
	char *id = key, *new_id = NULL;
	user_datum_t *user, *base_user, *new_user = NULL;
	link_state_t *state = (link_state_t *) data;

	user = (user_datum_t *) datum;

	base_user = hashtab_search(state->base->p_users.table, id);
	if (base_user == NULL) {
		if (state->verbose)
			INFO(state->handle, "copying user %s", id);

		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}

		if ((new_user =
		     (user_datum_t *) malloc(sizeof(*new_user))) == NULL) {
			goto cleanup;
		}
		user_datum_init(new_user);
		/* new_users's roles and MLS fields will be copied during
		   user_fix_callback(). */

		new_user->s.value = state->base->p_users.nprim + 1;

		ret = hashtab_insert(state->base->p_users.table,
				     (hashtab_key_t) new_id,
				     (hashtab_datum_t) new_user);
		if (ret) {
			goto cleanup;
		}
		state->base->p_users.nprim++;
		base_user = new_user;
	}

	if (state->dest_decl) {
		new_id = NULL;
		if ((new_user = malloc(sizeof(*new_user))) == NULL) {
			goto cleanup;
		}
		user_datum_init(new_user);
		new_user->s.value = base_user->s.value;
		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}
		if (hashtab_insert
		    (state->dest_decl->p_users.table, new_id, new_user)) {
			goto cleanup;
		}
		state->dest_decl->p_users.nprim++;
	}

	state->cur->map[SYM_USERS][user->s.value - 1] = base_user->s.value;
	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	user_datum_destroy(new_user);
	free(new_id);
	free(new_user);
	return -1;
}

static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			      void *data)
{
	int ret;
	char *id = key, *new_id = NULL;
	cond_bool_datum_t *booldatum, *base_bool, *new_bool = NULL;
	link_state_t *state = (link_state_t *) data;
	scope_datum_t *scope;

	booldatum = (cond_bool_datum_t *) datum;

	base_bool = hashtab_search(state->base->p_bools.table, id);
	if (base_bool == NULL) {
		if (state->verbose)
			INFO(state->handle, "copying boolean %s", id);

		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}

		if ((new_bool =
		     (cond_bool_datum_t *) malloc(sizeof(*new_bool))) == NULL) {
			goto cleanup;
		}
		new_bool->s.value = state->base->p_bools.nprim + 1;

		ret = hashtab_insert(state->base->p_bools.table,
				     (hashtab_key_t) new_id,
				     (hashtab_datum_t) new_bool);
		if (ret) {
			goto cleanup;
		}
		state->base->p_bools.nprim++;
		base_bool = new_bool;
		base_bool->flags = booldatum->flags;
		base_bool->state = booldatum->state;
	} else if ((booldatum->flags & COND_BOOL_FLAGS_TUNABLE) !=
		   (base_bool->flags & COND_BOOL_FLAGS_TUNABLE)) {
			/* A mismatch between boolean/tunable declaration
			 * and usage(for example a boolean used in the
			 * tunable_policy() or vice versa).
			 *
			 * This is not allowed and bail out with errors */
			ERR(state->handle,
			    "%s: Mismatch between boolean/tunable definition "
			    "and usage for %s", state->cur_mod_name, id);
			return -1;
	}

	/* Get the scope info for this boolean to see if this is the declaration, 
 	 * if so set the state */
	scope = hashtab_search(state->cur->policy->p_bools_scope.table, id);
	if (!scope)
		return SEPOL_ERR;
	if (scope->scope == SCOPE_DECL) {
		base_bool->state = booldatum->state;
		/* Only the declaration rather than requirement
		 * decides if it is a boolean or tunable. */
		base_bool->flags = booldatum->flags;
	}
	state->cur->map[SYM_BOOLS][booldatum->s.value - 1] = base_bool->s.value;
	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	cond_destroy_bool(new_id, new_bool, NULL);
	return -1;
}

static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			      void *data)
{
	char *id = key;
	level_datum_t *level, *base_level;
	link_state_t *state = (link_state_t *) data;
	scope_datum_t *scope;

	level = (level_datum_t *) datum;

	base_level = hashtab_search(state->base->p_levels.table, id);
	if (!base_level) {
		scope =
		    hashtab_search(state->cur->policy->p_sens_scope.table, id);
		if (!scope)
			return SEPOL_ERR;
		if (scope->scope == SCOPE_DECL) {
			/* disallow declarations in modules */
			ERR(state->handle,
			    "%s: Modules may not declare new sensitivities.",
			    state->cur_mod_name);
			return SEPOL_ENOTSUP;
		} else if (scope->scope == SCOPE_REQ) {
			/* unmet requirement */
			ERR(state->handle,
			    "%s: Sensitivity %s not declared by base.",
			    state->cur_mod_name, id);
			return SEPOL_ENOTSUP;
		} else {
			ERR(state->handle,
			    "%s: has an unknown scope: %d\n",
			    state->cur_mod_name, scope->scope);
			return SEPOL_ENOTSUP;
		}
	}

	state->cur->map[SYM_LEVELS][level->level->sens - 1] =
	    base_level->level->sens;

	return 0;
}

static int cat_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			     void *data)
{
	char *id = key;
	cat_datum_t *cat, *base_cat;
	link_state_t *state = (link_state_t *) data;
	scope_datum_t *scope;

	cat = (cat_datum_t *) datum;

	base_cat = hashtab_search(state->base->p_cats.table, id);
	if (!base_cat) {
		scope = hashtab_search(state->cur->policy->p_cat_scope.table, id);
		if (!scope)
			return SEPOL_ERR;
		if (scope->scope == SCOPE_DECL) {
			/* disallow declarations in modules */
			ERR(state->handle,
			    "%s: Modules may not declare new categories.",
			    state->cur_mod_name);
			return SEPOL_ENOTSUP;
		} else if (scope->scope == SCOPE_REQ) {
			/* unmet requirement */
			ERR(state->handle,
			    "%s: Category %s not declared by base.",
			    state->cur_mod_name, id);
			return SEPOL_ENOTSUP;
		} else {
			/* unknown scope?  malformed policy? */
			ERR(state->handle,
			    "%s: has an unknown scope: %d\n",
			    state->cur_mod_name, scope->scope);
			return SEPOL_ENOTSUP;
		}
	}

	state->cur->map[SYM_CATS][cat->s.value - 1] = base_cat->s.value;

	return 0;
}

static int (*copy_callback_f[SYM_NUM]) (hashtab_key_t key,
					hashtab_datum_t datum, void *datap) = {
NULL, class_copy_callback, role_copy_callback, type_copy_callback,
	    user_copy_callback, bool_copy_callback, sens_copy_callback,
	    cat_copy_callback};

/*
 * The boundaries have to be copied after the types/roles/users are copied,
 * because it refers hashtab to lookup destinated objects.
 */
static int type_bounds_copy_callback(hashtab_key_t key,
				     hashtab_datum_t datum, void *data)
{
	link_state_t *state = (link_state_t *) data;
	type_datum_t *type = (type_datum_t *) datum;
	type_datum_t *dest;
	uint32_t bounds_val;

	if (!type->bounds)
		return 0;

	bounds_val = state->cur->map[SYM_TYPES][type->bounds - 1];

	dest = hashtab_search(state->base->p_types.table, key);
	if (!dest) {
		ERR(state->handle,
		    "Type lookup failed for %s", (char *)key);
		return -1;
	}
	if (dest->bounds != 0 && dest->bounds != bounds_val) {
		ERR(state->handle,
		    "Inconsistent boundary for %s", (char *)key);
		return -1;
	}
	dest->bounds = bounds_val;

	return 0;
}

static int role_bounds_copy_callback(hashtab_key_t key,
				     hashtab_datum_t datum, void *data)
{
	link_state_t *state = (link_state_t *) data;
	role_datum_t *role = (role_datum_t *) datum;
	role_datum_t *dest;
	uint32_t bounds_val;

	if (!role->bounds)
		return 0;

	bounds_val = state->cur->map[SYM_ROLES][role->bounds - 1];

	dest = hashtab_search(state->base->p_roles.table, key);
	if (!dest) {
		ERR(state->handle,
		    "Role lookup failed for %s", (char *)key);
		return -1;
	}
	if (dest->bounds != 0 && dest->bounds != bounds_val) {
		ERR(state->handle,
		    "Inconsistent boundary for %s", (char *)key);
		return -1;
	}
	dest->bounds = bounds_val;

	return 0;
}

static int user_bounds_copy_callback(hashtab_key_t key,
				     hashtab_datum_t datum, void *data)
{
	link_state_t *state = (link_state_t *) data;
	user_datum_t *user = (user_datum_t *) datum;
	user_datum_t *dest;
	uint32_t bounds_val;

	if (!user->bounds)
		return 0;

	bounds_val = state->cur->map[SYM_USERS][user->bounds - 1];

	dest = hashtab_search(state->base->p_users.table, key);
	if (!dest) {
		ERR(state->handle,
		    "User lookup failed for %s", (char *)key);
		return -1;
	}
	if (dest->bounds != 0 && dest->bounds != bounds_val) {
		ERR(state->handle,
		    "Inconsistent boundary for %s", (char *)key);
		return -1;
	}
	dest->bounds = bounds_val;

	return 0;
}

/* The aliases have to be copied after the types and attributes to be
 * certain that the base symbol table will have the type that the
 * alias refers. Otherwise, we won't be able to find the type value
 * for the alias. We can't depend on the declaration ordering because
 * of the hash table.
 */
static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			       void *data)
{
	char *id = key, *new_id = NULL, *target_id;
	type_datum_t *type, *base_type, *new_type = NULL, *target_type;
	link_state_t *state = (link_state_t *) data;
	policy_module_t *mod = state->cur;
	int primval;

	type = (type_datum_t *) datum;
	/* there are 2 kinds of aliases. Ones with their own value (TYPE_ALIAS)
	 * and ones with the value of their primary (TYPE_TYPE && type->primary = 0)
	 */
	if (!
	    (type->flavor == TYPE_ALIAS
	     || (type->flavor == TYPE_TYPE && !type->primary))) {
		/* ignore types and attributes -- they were handled in
		 * type_copy_callback() */
		return 0;
	}

	if (type->flavor == TYPE_ALIAS)
		primval = type->primary;
	else
		primval = type->s.value;

	target_id = mod->policy->p_type_val_to_name[primval - 1];
	target_type = hashtab_search(state->base->p_types.table, target_id);
	if (target_type == NULL) {
		ERR(state->handle, "%s: Could not find type %s for alias %s.",
		    state->cur_mod_name, target_id, id);
		return -1;
	}

	if (!strcmp(id, target_id)) {
		ERR(state->handle, "%s: Self aliasing of %s.",
		    state->cur_mod_name, id);
		return -1;
	}

	target_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE);

	base_type = hashtab_search(state->base->p_types.table, id);
	if (base_type == NULL) {
		if (state->verbose)
			INFO(state->handle, "copying alias %s", id);

		if ((new_type =
		     (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) {
			goto cleanup;
		}
		/* the linked copy always has TYPE_ALIAS style aliases */
		new_type->primary = target_type->s.value;
		new_type->flags = target_type->flags;
		new_type->flavor = TYPE_ALIAS;
		new_type->s.value = state->base->p_types.nprim + 1;
		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}
		if (hashtab_insert
		    (state->base->p_types.table, new_id, new_type)) {
			goto cleanup;
		}
		state->base->p_types.nprim++;
		base_type = new_type;
	} else {

		/* if this already exists and isn't an alias it was required by another module (or base)
		 * and inserted into the hashtable as a type, fix it up now */

		if (base_type->flavor == TYPE_ALIAS) {
			/* error checking */
			assert(base_type->primary == target_type->s.value);
			assert(base_type->primary ==
			       mod->map[SYM_TYPES][primval - 1]);
			assert(mod->map[SYM_TYPES][type->s.value - 1] ==
			       base_type->primary);
			return 0;
		}

		if (base_type->flavor == TYPE_ATTRIB) {
			ERR(state->handle,
			    "%s is an alias of an attribute, not allowed", id);
			return -1;
		}

		base_type->flavor = TYPE_ALIAS;
		base_type->primary = target_type->s.value;
		base_type->flags |= (target_type->flags & TYPE_FLAGS_PERMISSIVE);

	}
	/* the aliases map points from its value to its primary so when this module 
	 * references this type the value it gets back from the map is the primary */
	mod->map[SYM_TYPES][type->s.value - 1] = base_type->primary;

	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	free(new_id);
	free(new_type);
	return -1;
}

/*********** callbacks that fix bitmaps ***********/

static int type_set_convert(type_set_t * types, type_set_t * dst,
			    policy_module_t * mod, link_state_t * state
			    __attribute__ ((unused)))
{
	unsigned int i;
	ebitmap_node_t *tnode;
	ebitmap_for_each_bit(&types->types, tnode, i) {
		if (ebitmap_node_get_bit(tnode, i)) {
			assert(mod->map[SYM_TYPES][i]);
			if (ebitmap_set_bit
			    (&dst->types, mod->map[SYM_TYPES][i] - 1, 1)) {
				goto cleanup;
			}
		}
	}
	ebitmap_for_each_bit(&types->negset, tnode, i) {
		if (ebitmap_node_get_bit(tnode, i)) {
			assert(mod->map[SYM_TYPES][i]);
			if (ebitmap_set_bit
			    (&dst->negset, mod->map[SYM_TYPES][i] - 1, 1)) {
				goto cleanup;
			}
		}
	}
	dst->flags = types->flags;
	return 0;

      cleanup:
	return -1;
}

/* OR 2 typemaps together and at the same time map the src types to
 * the correct values in the dst typeset.
 */
static int type_set_or_convert(type_set_t * types, type_set_t * dst,
			       policy_module_t * mod, link_state_t * state)
{
	type_set_t ts_tmp;

	type_set_init(&ts_tmp);
	if (type_set_convert(types, &ts_tmp, mod, state) == -1) {
		goto cleanup;
	}
	if (type_set_or_eq(dst, &ts_tmp)) {
		goto cleanup;
	}
	type_set_destroy(&ts_tmp);
	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	type_set_destroy(&ts_tmp);
	return -1;
}

static int role_set_or_convert(role_set_t * roles, role_set_t * dst,
			       policy_module_t * mod, link_state_t * state)
{
	unsigned int i;
	ebitmap_t tmp;
	ebitmap_node_t *rnode;

	ebitmap_init(&tmp);
	ebitmap_for_each_bit(&roles->roles, rnode, i) {
		if (ebitmap_node_get_bit(rnode, i)) {
			assert(mod->map[SYM_ROLES][i]);
			if (ebitmap_set_bit
			    (&tmp, mod->map[SYM_ROLES][i] - 1, 1)) {
				goto cleanup;
			}
		}
	}
	if (ebitmap_union(&dst->roles, &tmp)) {
		goto cleanup;
	}
	dst->flags |= roles->flags;
	ebitmap_destroy(&tmp);
	return 0;
      cleanup:
	ERR(state->handle, "Out of memory!");
	ebitmap_destroy(&tmp);
	return -1;
}

static int mls_level_convert(mls_semantic_level_t * src, mls_semantic_level_t * dst,
			     policy_module_t * mod, link_state_t * state)
{
	mls_semantic_cat_t *src_cat, *new_cat;

	if (!mod->policy->mls)
		return 0;

	/* Required not declared. */
	if (!src->sens)
		return 0;

	assert(mod->map[SYM_LEVELS][src->sens - 1]);
	dst->sens = mod->map[SYM_LEVELS][src->sens - 1];

	for (src_cat = src->cat; src_cat; src_cat = src_cat->next) {
		new_cat =
		    (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
		if (!new_cat) {
			ERR(state->handle, "Out of memory");
			return -1;
		}
		mls_semantic_cat_init(new_cat);

		new_cat->next = dst->cat;
		dst->cat = new_cat;

		assert(mod->map[SYM_CATS][src_cat->low - 1]);
		dst->cat->low = mod->map[SYM_CATS][src_cat->low - 1];
		assert(mod->map[SYM_CATS][src_cat->high - 1]);
		dst->cat->high = mod->map[SYM_CATS][src_cat->high - 1];
	}

	return 0;
}

static int mls_range_convert(mls_semantic_range_t * src, mls_semantic_range_t * dst,
			     policy_module_t * mod, link_state_t * state)
{
	int ret;
	ret = mls_level_convert(&src->level[0], &dst->level[0], mod, state);
	if (ret)
		return ret;
	ret = mls_level_convert(&src->level[1], &dst->level[1], mod, state);
	if (ret)
		return ret;
	return 0;
}

static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
			     void *data)
{
	unsigned int i;
	char *id = key;
	role_datum_t *role, *dest_role = NULL;
	link_state_t *state = (link_state_t *) data;
	ebitmap_t e_tmp;
	policy_module_t *mod = state->cur;
	ebitmap_node_t *rnode;
	hashtab_t role_tab;

	role = (role_datum_t *) datum;
	if (state->dest_decl == NULL)
		role_tab = state->base->p_roles.table;
	else
		role_tab = state->dest_decl->p_roles.table;

	dest_role = hashtab_search(role_tab, id);
	assert(dest_role != NULL);

	if (state->verbose) {
		INFO(state->handle, "fixing role %s", id);
	}

	ebitmap_init(&e_tmp);
	ebitmap_for_each_bit(&role->dominates, rnode, i) {
		if (ebitmap_node_get_bit(rnode, i)) {
			assert(mod->map[SYM_ROLES][i]);
			if (ebitmap_set_bit
			    (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) {
				goto cleanup;
			}
		}
	}
	if (ebitmap_union(&dest_role->dominates, &e_tmp)) {
		goto cleanup;
	}
	if (type_set_or_convert(&role->types, &dest_role->types, mod, state)) {
		goto cleanup;
	}
	ebitmap_destroy(&e_tmp);
	
	if (role->flavor == ROLE_ATTRIB) {
		ebitmap_init(&e_tmp);
		ebitmap_for_each_bit(&role->roles, rnode, i) {
			if (ebitmap_node_get_bit(rnode, i)) {
				assert(mod->map[SYM_ROLES][i]);
				if (ebitmap_set_bit
				    (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) {
					goto cleanup;
				}
			}
		}
		if (ebitmap_union(&dest_role->roles, &e_tmp)) {
			goto cleanup;
		}
		ebitmap_destroy(&e_tmp);
	}

	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	ebitmap_destroy(&e_tmp);
	return -1;
}

static int type_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
			     void *data)
{
	unsigned int i;
	char *id = key;
	type_datum_t *type, *new_type = NULL;
	link_state_t *state = (link_state_t *) data;
	ebitmap_t e_tmp;
	policy_module_t *mod = state->cur;
	ebitmap_node_t *tnode;
	symtab_t *typetab;

	type = (type_datum_t *) datum;

	if (state->dest_decl == NULL)
		typetab = &state->base->p_types;
	else
		typetab = &state->dest_decl->p_types;

	/* only fix attributes */
	if (type->flavor != TYPE_ATTRIB) {
		return 0;
	}

	new_type = hashtab_search(typetab->table, id);
	assert(new_type != NULL && new_type->flavor == TYPE_ATTRIB);

	if (state->verbose) {
		INFO(state->handle, "fixing attribute %s", id);
	}

	ebitmap_init(&e_tmp);
	ebitmap_for_each_bit(&type->types, tnode, i) {
		if (ebitmap_node_get_bit(tnode, i)) {
			assert(mod->map[SYM_TYPES][i]);
			if (ebitmap_set_bit
			    (&e_tmp, mod->map[SYM_TYPES][i] - 1, 1)) {
				goto cleanup;
			}
		}
	}
	if (ebitmap_union(&new_type->types, &e_tmp)) {
		goto cleanup;
	}
	ebitmap_destroy(&e_tmp);
	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	ebitmap_destroy(&e_tmp);
	return -1;
}

static int user_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
			     void *data)
{
	char *id = key;
	user_datum_t *user, *new_user = NULL;
	link_state_t *state = (link_state_t *) data;
	policy_module_t *mod = state->cur;
	symtab_t *usertab;

	user = (user_datum_t *) datum;

	if (state->dest_decl == NULL)
		usertab = &state->base->p_users;
	else
		usertab = &state->dest_decl->p_users;

	new_user = hashtab_search(usertab->table, id);
	assert(new_user != NULL);

	if (state->verbose) {
		INFO(state->handle, "fixing user %s", id);
	}

	if (role_set_or_convert(&user->roles, &new_user->roles, mod, state)) {
		goto cleanup;
	}

	if (mls_range_convert(&user->range, &new_user->range, mod, state))
		goto cleanup;

	if (mls_level_convert(&user->dfltlevel, &new_user->dfltlevel, mod, state))
		goto cleanup;

	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	return -1;
}

static int (*fix_callback_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
				       void *datap) = {
NULL, NULL, role_fix_callback, type_fix_callback, user_fix_callback,
	    NULL, NULL, NULL};

/*********** functions that copy AV rules ***********/

static int copy_avrule_list(avrule_t * list, avrule_t ** dst,
			    policy_module_t * module, link_state_t * state)
{
	unsigned int i;
	avrule_t *cur, *new_rule = NULL, *tail;
	class_perm_node_t *cur_perm, *new_perm, *tail_perm = NULL;

	tail = *dst;
	while (tail && tail->next) {
		tail = tail->next;
	}

	cur = list;
	while (cur) {
		if ((new_rule = (avrule_t *) malloc(sizeof(avrule_t))) == NULL) {
			goto cleanup;
		}
		avrule_init(new_rule);

		new_rule->specified = cur->specified;
		new_rule->flags = cur->flags;
		if (type_set_convert
		    (&cur->stypes, &new_rule->stypes, module, state) == -1
		    || type_set_convert(&cur->ttypes, &new_rule->ttypes, module,
					state) == -1) {
			goto cleanup;
		}

		cur_perm = cur->perms;
		tail_perm = NULL;
		while (cur_perm) {
			if ((new_perm = (class_perm_node_t *)
			     malloc(sizeof(class_perm_node_t))) == NULL) {
				goto cleanup;
			}
			class_perm_node_init(new_perm);

			new_perm->tclass =
			    module->map[SYM_CLASSES][cur_perm->tclass - 1];
			assert(new_perm->tclass);

			if (new_rule->specified & AVRULE_AV) {
				for (i = 0;
				     i <
				     module->perm_map_len[cur_perm->tclass - 1];
				     i++) {
					if (!(cur_perm->data & (1U << i)))
						continue;
					new_perm->data |=
					    (1U <<
					     (module->
					      perm_map[cur_perm->tclass - 1][i] -
					      1));
				}
			} else {
				new_perm->data =
				    module->map[SYM_TYPES][cur_perm->data - 1];
			}

			if (new_rule->perms == NULL) {
				new_rule->perms = new_perm;
			} else {
				assert(tail_perm);
				tail_perm->next = new_perm;
			}
			tail_perm = new_perm;
			cur_perm = cur_perm->next;
		}
		new_rule->line = cur->line;
		new_rule->source_line = cur->source_line;
		if (cur->source_filename) {
			new_rule->source_filename = strdup(cur->source_filename);
			if (!new_rule->source_filename)
				goto cleanup;
		}

		cur = cur->next;

		if (*dst == NULL) {
			*dst = new_rule;
		} else {
			tail->next = new_rule;
		}
		tail = new_rule;
	}

	return 0;
      cleanup:
	ERR(state->handle, "Out of memory!");
	avrule_destroy(new_rule);
	free(new_rule);
	return -1;
}

static int copy_role_trans_list(role_trans_rule_t * list,
				role_trans_rule_t ** dst,
				policy_module_t * module, link_state_t * state)
{
	role_trans_rule_t *cur, *new_rule = NULL, *tail;
	unsigned int i;
	ebitmap_node_t *cnode;

	cur = list;
	tail = *dst;
	while (tail && tail->next) {
		tail = tail->next;
	}
	while (cur) {
		if ((new_rule =
		     (role_trans_rule_t *) malloc(sizeof(role_trans_rule_t))) ==
		    NULL) {
			goto cleanup;
		}
		role_trans_rule_init(new_rule);

		if (role_set_or_convert
		    (&cur->roles, &new_rule->roles, module, state)
		    || type_set_or_convert(&cur->types, &new_rule->types,
					   module, state)) {
			goto cleanup;
		}

		ebitmap_for_each_bit(&cur->classes, cnode, i) {
			if (ebitmap_node_get_bit(cnode, i)) {
				assert(module->map[SYM_CLASSES][i]);
				if (ebitmap_set_bit(&new_rule->classes,
						    module->
						    map[SYM_CLASSES][i] - 1,
						    1)) {
					goto cleanup;
				}
			}
		}

		new_rule->new_role = module->map[SYM_ROLES][cur->new_role - 1];

		if (*dst == NULL) {
			*dst = new_rule;
		} else {
			tail->next = new_rule;
		}
		tail = new_rule;
		cur = cur->next;
	}
	return 0;
      cleanup:
	ERR(state->handle, "Out of memory!");
	role_trans_rule_list_destroy(new_rule);
	return -1;
}

static int copy_role_allow_list(role_allow_rule_t * list,
				role_allow_rule_t ** dst,
				policy_module_t * module, link_state_t * state)
{
	role_allow_rule_t *cur, *new_rule = NULL, *tail;

	cur = list;
	tail = *dst;
	while (tail && tail->next) {
		tail = tail->next;
	}

	while (cur) {
		if ((new_rule =
		     (role_allow_rule_t *) malloc(sizeof(role_allow_rule_t))) ==
		    NULL) {
			goto cleanup;
		}
		role_allow_rule_init(new_rule);

		if (role_set_or_convert
		    (&cur->roles, &new_rule->roles, module, state)
		    || role_set_or_convert(&cur->new_roles,
					   &new_rule->new_roles, module,
					   state)) {
			goto cleanup;
		}
		if (*dst == NULL) {
			*dst = new_rule;
		} else {
			tail->next = new_rule;
		}
		tail = new_rule;
		cur = cur->next;
	}
	return 0;
      cleanup:
	ERR(state->handle, "Out of memory!");
	role_allow_rule_list_destroy(new_rule);
	return -1;
}

static int copy_filename_trans_list(filename_trans_rule_t * list,
				    filename_trans_rule_t ** dst,
				    policy_module_t * module,
				    link_state_t * state)
{
	filename_trans_rule_t *cur, *new_rule, *tail;

	cur = list;
	tail = *dst;
	while (tail && tail->next)
		tail = tail->next;

	while (cur) {
		new_rule = malloc(sizeof(*new_rule));
		if (!new_rule)
			goto err;

		filename_trans_rule_init(new_rule);

		if (*dst == NULL)
			*dst = new_rule;
		else
			tail->next = new_rule;
		tail = new_rule;

		new_rule->name = strdup(cur->name);
		if (!new_rule->name)
			goto err;

		if (type_set_or_convert(&cur->stypes, &new_rule->stypes, module, state) ||
		    type_set_or_convert(&cur->ttypes, &new_rule->ttypes, module, state))
			goto err;

		new_rule->tclass = module->map[SYM_CLASSES][cur->tclass - 1];
		new_rule->otype = module->map[SYM_TYPES][cur->otype - 1];

		cur = cur->next;
	}
	return 0;
err:
	ERR(state->handle, "Out of memory!");
	return -1;
}

static int copy_range_trans_list(range_trans_rule_t * rules,
				 range_trans_rule_t ** dst,
				 policy_module_t * mod, link_state_t * state)
{
	range_trans_rule_t *rule, *new_rule = NULL;
	unsigned int i;
	ebitmap_node_t *cnode;

	for (rule = rules; rule; rule = rule->next) {
		new_rule =
		    (range_trans_rule_t *) malloc(sizeof(range_trans_rule_t));
		if (!new_rule)
			goto cleanup;

		range_trans_rule_init(new_rule);

		new_rule->next = *dst;
		*dst = new_rule;

		if (type_set_convert(&rule->stypes, &new_rule->stypes,
				     mod, state))
			goto cleanup;

		if (type_set_convert(&rule->ttypes, &new_rule->ttypes,
				     mod, state))
			goto cleanup;

		ebitmap_for_each_bit(&rule->tclasses, cnode, i) {
			if (ebitmap_node_get_bit(cnode, i)) {
				assert(mod->map[SYM_CLASSES][i]);
				if (ebitmap_set_bit
				    (&new_rule->tclasses,
				     mod->map[SYM_CLASSES][i] - 1, 1)) {
					goto cleanup;
				}
			}
		}

		if (mls_range_convert(&rule->trange, &new_rule->trange, mod, state))
			goto cleanup;
	}
	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	range_trans_rule_list_destroy(new_rule);
	return -1;
}

static int copy_cond_list(cond_node_t * list, cond_node_t ** dst,
			  policy_module_t * module, link_state_t * state)
{
	unsigned i;
	cond_node_t *cur, *new_node = NULL, *tail;
	cond_expr_t *cur_expr;
	tail = *dst;
	while (tail && tail->next)
		tail = tail->next;

	cur = list;
	while (cur) {
		new_node = (cond_node_t *) malloc(sizeof(cond_node_t));
		if (!new_node) {
			goto cleanup;
		}
		memset(new_node, 0, sizeof(cond_node_t));

		new_node->cur_state = cur->cur_state;
		new_node->expr = cond_copy_expr(cur->expr);
		if (!new_node->expr)
			goto cleanup;
		/* go back through and remap the expression */
		for (cur_expr = new_node->expr; cur_expr != NULL;
		     cur_expr = cur_expr->next) {
			/* expression nodes don't have a bool value of 0 - don't map them */
			if (cur_expr->expr_type != COND_BOOL)
				continue;
			assert(module->map[SYM_BOOLS][cur_expr->bool - 1] != 0);
			cur_expr->bool =
			    module->map[SYM_BOOLS][cur_expr->bool - 1];
		}
		new_node->nbools = cur->nbools;
		/* FIXME should COND_MAX_BOOLS be used here? */
		for (i = 0; i < min(cur->nbools, COND_MAX_BOOLS); i++) {
			uint32_t remapped_id =
			    module->map[SYM_BOOLS][cur->bool_ids[i] - 1];
			assert(remapped_id != 0);
			new_node->bool_ids[i] = remapped_id;
		}
		new_node->expr_pre_comp = cur->expr_pre_comp;

		if (copy_avrule_list
		    (cur->avtrue_list, &new_node->avtrue_list, module, state)
		    || copy_avrule_list(cur->avfalse_list,
					&new_node->avfalse_list, module,
					state)) {
			goto cleanup;
		}

		if (*dst == NULL) {
			*dst = new_node;
		} else {
			tail->next = new_node;
		}
		tail = new_node;
		cur = cur->next;
	}
	return 0;
      cleanup:
	ERR(state->handle, "Out of memory!");
	cond_node_destroy(new_node);
	free(new_node);
	return -1;

}

/*********** functions that copy avrule_decls from module to base ***********/

static int copy_identifiers(link_state_t * state, symtab_t * src_symtab,
			    avrule_decl_t * dest_decl)
{
	int i, ret;

	state->dest_decl = dest_decl;
	for (i = 0; i < SYM_NUM; i++) {
		if (copy_callback_f[i] != NULL) {
			ret =
			    hashtab_map(src_symtab[i].table, copy_callback_f[i],
					state);
			if (ret) {
				return ret;
			}
		}
	}

	if (hashtab_map(src_symtab[SYM_TYPES].table,
			type_bounds_copy_callback, state))
		return -1;

	if (hashtab_map(src_symtab[SYM_TYPES].table,
			alias_copy_callback, state))
		return -1;

	if (hashtab_map(src_symtab[SYM_ROLES].table,
			role_bounds_copy_callback, state))
		return -1;

	if (hashtab_map(src_symtab[SYM_USERS].table,
			user_bounds_copy_callback, state))
		return -1;

	/* then fix bitmaps associated with those newly copied identifiers */
	for (i = 0; i < SYM_NUM; i++) {
		if (fix_callback_f[i] != NULL &&
		    hashtab_map(src_symtab[i].table, fix_callback_f[i],
				state)) {
			return -1;
		}
	}
	return 0;
}

static int copy_scope_index(scope_index_t * src, scope_index_t * dest,
			    policy_module_t * module, link_state_t * state)
{
	unsigned int i, j;
	uint32_t largest_mapped_class_value = 0;
	ebitmap_node_t *node;
	/* copy the scoping information for this avrule decl block */
	for (i = 0; i < SYM_NUM; i++) {
		ebitmap_t *srcmap = src->scope + i;
		ebitmap_t *destmap = dest->scope + i;
		if (copy_callback_f[i] == NULL) {
			continue;
		}
		ebitmap_for_each_bit(srcmap, node, j) {
			if (ebitmap_node_get_bit(node, j)) {
				assert(module->map[i][j] != 0);
				if (ebitmap_set_bit
				    (destmap, module->map[i][j] - 1, 1) != 0) {

					goto cleanup;
				}
				if (i == SYM_CLASSES &&
				    largest_mapped_class_value <
				    module->map[SYM_CLASSES][j]) {
					largest_mapped_class_value =
					    module->map[SYM_CLASSES][j];
				}
			}
		}
	}

	/* next copy the enabled permissions data  */
	if ((dest->class_perms_map = malloc(largest_mapped_class_value *
					    sizeof(*dest->class_perms_map))) ==
	    NULL) {
		goto cleanup;
	}
	for (i = 0; i < largest_mapped_class_value; i++) {
		ebitmap_init(dest->class_perms_map + i);
	}
	dest->class_perms_len = largest_mapped_class_value;
	for (i = 0; i < src->class_perms_len; i++) {
		ebitmap_t *srcmap = src->class_perms_map + i;
		ebitmap_t *destmap =
		    dest->class_perms_map + module->map[SYM_CLASSES][i] - 1;
		ebitmap_for_each_bit(srcmap, node, j) {
			if (ebitmap_node_get_bit(node, j) &&
			    ebitmap_set_bit(destmap, module->perm_map[i][j] - 1,
					    1)) {
				goto cleanup;
			}
		}
	}

	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	return -1;
}

static int copy_avrule_decl(link_state_t * state, policy_module_t * module,
			    avrule_decl_t * src_decl, avrule_decl_t * dest_decl)
{
	int ret;

	/* copy all of the RBAC and TE rules */
	if (copy_avrule_list
	    (src_decl->avrules, &dest_decl->avrules, module, state) == -1
	    || copy_role_trans_list(src_decl->role_tr_rules,
				    &dest_decl->role_tr_rules, module,
				    state) == -1
	    || copy_role_allow_list(src_decl->role_allow_rules,
				    &dest_decl->role_allow_rules, module,
				    state) == -1
	    || copy_cond_list(src_decl->cond_list, &dest_decl->cond_list,
			      module, state) == -1) {
		return -1;
	}

	if (copy_filename_trans_list(src_decl->filename_trans_rules,
				     &dest_decl->filename_trans_rules,
				     module, state))
		return -1;

	if (copy_range_trans_list(src_decl->range_tr_rules,
				  &dest_decl->range_tr_rules, module, state))
		return -1;

	/* finally copy any identifiers local to this declaration */
	ret = copy_identifiers(state, src_decl->symtab, dest_decl);
	if (ret < 0) {
		return ret;
	}

	/* then copy required and declared scope indices here */
	if (copy_scope_index(&src_decl->required, &dest_decl->required,
			     module, state) == -1 ||
	    copy_scope_index(&src_decl->declared, &dest_decl->declared,
			     module, state) == -1) {
		return -1;
	}

	return 0;
}

static int copy_avrule_block(link_state_t * state, policy_module_t * module,
			     avrule_block_t * block)
{
	avrule_block_t *new_block = avrule_block_create();
	avrule_decl_t *decl, *last_decl = NULL;
	int ret;

	if (new_block == NULL) {
		ERR(state->handle, "Out of memory!");
		ret = -1;
		goto cleanup;
	}

	new_block->flags = block->flags;

	for (decl = block->branch_list; decl != NULL; decl = decl->next) {
		avrule_decl_t *new_decl =
		    avrule_decl_create(state->next_decl_id);
		if (new_decl == NULL) {
			ERR(state->handle, "Out of memory!");
			ret = -1;
			goto cleanup;
		}

		if (module->policy->name != NULL) {
			new_decl->module_name = strdup(module->policy->name);
			if (new_decl->module_name == NULL) {
				ERR(state->handle, "Out of memory\n");
				avrule_decl_destroy(new_decl);
				ret = -1;
				goto cleanup;
			}
		}

		if (last_decl == NULL) {
			new_block->branch_list = new_decl;
		} else {
			last_decl->next = new_decl;
		}
		last_decl = new_decl;
		state->base->decl_val_to_struct[state->next_decl_id - 1] =
		    new_decl;
		state->decl_to_mod[state->next_decl_id] = module->policy;

		module->avdecl_map[decl->decl_id] = new_decl->decl_id;

		ret = copy_avrule_decl(state, module, decl, new_decl);
		if (ret) {
			avrule_decl_destroy(new_decl);
			goto cleanup;
		}

		state->next_decl_id++;
	}
	state->last_avrule_block->next = new_block;
	state->last_avrule_block = new_block;
	return 0;

      cleanup:
	avrule_block_list_destroy(new_block);
	return ret;
}

static int scope_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
			       void *data)
{
	unsigned int i;
	int ret;
	char *id = key, *new_id = NULL;
	scope_datum_t *scope, *base_scope;
	link_state_t *state = (link_state_t *) data;
	uint32_t symbol_num = state->symbol_num;
	uint32_t *avdecl_map = state->cur->avdecl_map;

	scope = (scope_datum_t *) datum;

	/* check if the base already has a scope entry */
	base_scope = hashtab_search(state->base->scope[symbol_num].table, id);
	if (base_scope == NULL) {
		scope_datum_t *new_scope;
		if ((new_id = strdup(id)) == NULL) {
			goto cleanup;
		}

		if ((new_scope =
		     (scope_datum_t *) calloc(1, sizeof(*new_scope))) == NULL) {
			free(new_id);
			goto cleanup;
		}
		ret = hashtab_insert(state->base->scope[symbol_num].table,
				     (hashtab_key_t) new_id,
				     (hashtab_datum_t) new_scope);
		if (ret) {
			free(new_id);
			free(new_scope);
			goto cleanup;
		}
		new_scope->scope = SCOPE_REQ;	/* this is reset further down */
		base_scope = new_scope;
	}
	if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_DECL) {
		/* this module declared symbol, so overwrite the old
		 * list with the new decl ids */
		base_scope->scope = SCOPE_DECL;
		free(base_scope->decl_ids);
		base_scope->decl_ids = NULL;
		base_scope->decl_ids_len = 0;
		for (i = 0; i < scope->decl_ids_len; i++) {
			if (add_i_to_a(avdecl_map[scope->decl_ids[i]],
				       &base_scope->decl_ids_len,
				       &base_scope->decl_ids) == -1) {
				goto cleanup;
			}
		}
	} else if (base_scope->scope == SCOPE_DECL && scope->scope == SCOPE_REQ) {
		/* this module depended on a symbol that now exists,
		 * so don't do anything */
	} else if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_REQ) {
		/* symbol is still required, so add to the list */
		for (i = 0; i < scope->decl_ids_len; i++) {
			if (add_i_to_a(avdecl_map[scope->decl_ids[i]],
				       &base_scope->decl_ids_len,
				       &base_scope->decl_ids) == -1) {
				goto cleanup;
			}
		}
	} else {
		/* this module declared a symbol, and it was already
		 * declared.  only roles and users may be multiply
		 * declared; for all others this is an error. */
		if (symbol_num != SYM_ROLES && symbol_num != SYM_USERS) {
			ERR(state->handle,
			    "%s: Duplicate declaration in module: %s %s",
			    state->cur_mod_name,
			    symtab_names[state->symbol_num], id);
			return -1;
		}
		for (i = 0; i < scope->decl_ids_len; i++) {
			if (add_i_to_a(avdecl_map[scope->decl_ids[i]],
				       &base_scope->decl_ids_len,
				       &base_scope->decl_ids) == -1) {
				goto cleanup;
			}
		}
	}
	return 0;

      cleanup:
	ERR(state->handle, "Out of memory!");
	return -1;
}

/* Copy a module over to a base, remapping all values within.  After
 * all identifiers and rules are done, copy the scoping information.
 * This is when it checks for duplicate declarations. */
static int copy_module(link_state_t * state, policy_module_t * module)
{
	int i, ret;
	avrule_block_t *cur;
	state->cur = module;
	state->cur_mod_name = module->policy->name;

	/* first copy all of the identifiers */
	ret = copy_identifiers(state, module->policy->symtab, NULL);
	if (ret) {
		return ret;
	}

	/* next copy all of the avrule blocks */
	for (cur = module->policy->global; cur != NULL; cur = cur->next) {
		ret = copy_avrule_block(state, module, cur);
		if (ret) {
			return ret;
		}
	}

	/* then copy the scoping tables */
	for (i = 0; i < SYM_NUM; i++) {
		state->symbol_num = i;
		if (hashtab_map
		    (module->policy->scope[i].table, scope_copy_callback,
		     state)) {
			return -1;
		}
	}

	return 0;
}

/***** functions that check requirements and enable blocks in a module ******/

/* borrowed from checkpolicy.c */

struct find_perm_arg {
	unsigned int valuep;
	hashtab_key_t key;
};

static int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *varg)
{

	struct find_perm_arg *arg = varg;

	perm_datum_t *perdatum = (perm_datum_t *) datum;
	if (arg->valuep == perdatum->s.value) {
		arg->key = key;
		return 1;
	}

	return 0;
}

/* Check if the requirements are met for a single declaration.  If all
 * are met return 1.  For the first requirement found to be missing,
 * if 'missing_sym_num' and 'missing_value' are both not NULL then
 * write to them the symbol number and value for the missing
 * declaration.  Then return 0 to indicate a missing declaration.
 * Note that if a declaration had no requirement at all (e.g., an ELSE
 * block) this returns 1. */
static int is_decl_requires_met(link_state_t * state,
				avrule_decl_t * decl,
				struct missing_requirement *req)
{
	/* (This algorithm is very unoptimized.  It performs many
	 * redundant checks.  A very obvious improvement is to cache
	 * which symbols have been verified, so that they do not need
	 * to be re-checked.) */
	unsigned int i, j;
	ebitmap_t *bitmap;
	char *id, *perm_id;
	policydb_t *pol = state->base;
	ebitmap_node_t *node;

	/* check that all symbols have been satisfied */
	for (i = 0; i < SYM_NUM; i++) {
		if (i == SYM_CLASSES) {
			/* classes will be checked during permissions
			 * checking phase below */
			continue;
		}
		bitmap = &decl->required.scope[i];
		ebitmap_for_each_bit(bitmap, node, j) {
			if (!ebitmap_node_get_bit(node, j)) {
				continue;
			}

			/* check base's scope table */
			id = pol->sym_val_to_name[i][j];
			if (!is_id_enabled(id, state->base, i)) {
				/* this symbol was not found */
				if (req != NULL) {
					req->symbol_type = i;
					req->symbol_value = j + 1;
				}
				return 0;
			}
		}
	}
	/* check that all classes and permissions have been satisfied */
	for (i = 0; i < decl->required.class_perms_len; i++) {

		bitmap = decl->required.class_perms_map + i;
		ebitmap_for_each_bit(bitmap, node, j) {
			struct find_perm_arg fparg;
			class_datum_t *cladatum;
			uint32_t perm_value = j + 1;
			int rc;
			scope_datum_t *scope;

			if (!ebitmap_node_get_bit(node, j)) {
				continue;
			}
			id = pol->p_class_val_to_name[i];
			cladatum = pol->class_val_to_struct[i];

			scope =
			    hashtab_search(state->base->p_classes_scope.table,
					   id);
			if (scope == NULL) {
				ERR(state->handle,
				    "Could not find scope information for class %s",
				    id);
				return -1;
			}

			fparg.valuep = perm_value;
			fparg.key = NULL;

			(void)hashtab_map(cladatum->permissions.table, find_perm,
				    &fparg);
			if (fparg.key == NULL && cladatum->comdatum != NULL) {
				rc = hashtab_map(cladatum->comdatum->permissions.table,
						 find_perm, &fparg);
				assert(rc == 1);
			}
			perm_id = fparg.key;

			assert(perm_id != NULL);
			if (!is_perm_enabled(id, perm_id, state->base)) {
				if (req != NULL) {
					req->symbol_type = SYM_CLASSES;
					req->symbol_value = i + 1;
					req->perm_value = perm_value;
				}
				return 0;
			}
		}
	}

	/* all requirements have been met */
	return 1;
}

static int debug_requirements(link_state_t * state, policydb_t * p)
{
	int ret;
	avrule_block_t *cur;
	missing_requirement_t req;
	memset(&req, 0, sizeof(req));

	for (cur = p->global; cur != NULL; cur = cur->next) {
		if (cur->enabled != NULL)
			continue;

		ret = is_decl_requires_met(state, cur->branch_list, &req);
		if (ret < 0) {
			return ret;
		} else if (ret == 0) {
			const char *mod_name = cur->branch_list->module_name ?
			    cur->branch_list->module_name : "BASE";
			if (req.symbol_type == SYM_CLASSES) {
				struct find_perm_arg fparg;

				class_datum_t *cladatum;
				cladatum = p->class_val_to_struct[req.symbol_value - 1];

				fparg.valuep = req.perm_value;
				fparg.key = NULL;
				(void)hashtab_map(cladatum->permissions.table,
						  find_perm, &fparg);

				if (cur->flags & AVRULE_OPTIONAL) {
					ERR(state->handle,
					    "%s[%d]'s optional requirements were not met: class %s, permission %s",
					    mod_name, cur->branch_list->decl_id,
					    p->p_class_val_to_name[req.symbol_value - 1],
					    fparg.key);
				} else {
					ERR(state->handle,
					    "%s[%d]'s global requirements were not met: class %s, permission %s",
					    mod_name, cur->branch_list->decl_id,
					    p->p_class_val_to_name[req.symbol_value - 1],
					    fparg.key);
				}
			} else {
				if (cur->flags & AVRULE_OPTIONAL) {
					ERR(state->handle,
					    "%s[%d]'s optional requirements were not met: %s %s",
					    mod_name, cur->branch_list->decl_id,
					    symtab_names[req.symbol_type],
					    p->sym_val_to_name[req.
							       symbol_type][req.
									    symbol_value
									    -
									    1]);
				} else {
					ERR(state->handle,
					    "%s[%d]'s global requirements were not met: %s %s",
					    mod_name, cur->branch_list->decl_id,
					    symtab_names[req.symbol_type],
					    p->sym_val_to_name[req.
							       symbol_type][req.
									    symbol_value
									    -
									    1]);
				}
			}
		}
	}
	return 0;
}

static void print_missing_requirements(link_state_t * state,
				       avrule_block_t * cur,
				       missing_requirement_t * req)
{
	policydb_t *p = state->base;
	const char *mod_name = cur->branch_list->module_name ?
	    cur->branch_list->module_name : "BASE";

	if (req->symbol_type == SYM_CLASSES) {

		struct find_perm_arg fparg;

		class_datum_t *cladatum;
		cladatum = p->class_val_to_struct[req->symbol_value - 1];

		fparg.valuep = req->perm_value;
		fparg.key = NULL;
		(void)hashtab_map(cladatum->permissions.table, find_perm, &fparg);

		ERR(state->handle,
		    "%s's global requirements were not met: class %s, permission %s",
		    mod_name,
		    p->p_class_val_to_name[req->symbol_value - 1], fparg.key);
	} else {
		ERR(state->handle,
		    "%s's global requirements were not met: %s %s",
		    mod_name,
		    symtab_names[req->symbol_type],
		    p->sym_val_to_name[req->symbol_type][req->symbol_value - 1]);
	}
}

/* Enable all of the avrule_decl blocks for the policy. This simple
 * algorithm is the following:
 *
 * 1) Enable all of the non-else avrule_decls for all blocks.
 * 2) Iterate through the non-else decls looking for decls whose requirements
 *    are not met.
 *    2a) If the decl is non-optional, return immediately with an error.
 *    2b) If the decl is optional, disable the block and mark changed = 1
 * 3) If changed == 1 goto 2.
 * 4) Iterate through all blocks looking for those that have no enabled
 *    decl. If the block has an else decl, enable.
 *
 * This will correctly handle all dependencies, including mutual and
 * cicular. The only downside is that it is slow.
 */
static int enable_avrules(link_state_t * state, policydb_t * pol)
{
	int changed = 1;
	avrule_block_t *block;
	avrule_decl_t *decl;
	missing_requirement_t req;
	int ret = 0, rc;

	if (state->verbose) {
		INFO(state->handle, "Determining which avrules to enable.");
	}

	/* 1) enable all of the non-else blocks */
	for (block = pol->global; block != NULL; block = block->next) {
		block->enabled = block->branch_list;
		block->enabled->enabled = 1;
		for (decl = block->branch_list->next; decl != NULL;
		     decl = decl->next)
			decl->enabled = 0;
	}

	/* 2) Iterate */
	while (changed) {
		changed = 0;
		for (block = pol->global; block != NULL; block = block->next) {
			if (block->enabled == NULL) {
				continue;
			}
			decl = block->branch_list;
			if (state->verbose) {
				const char *mod_name = decl->module_name ?
				    decl->module_name : "BASE";
				INFO(state->handle, "check module %s decl %d\n",
				     mod_name, decl->decl_id);
			}
			rc = is_decl_requires_met(state, decl, &req);
			if (rc < 0) {
				ret = SEPOL_ERR;
				goto out;
			} else if (rc == 0) {
				decl->enabled = 0;
				block->enabled = NULL;
				changed = 1;
				if (!(block->flags & AVRULE_OPTIONAL)) {
					print_missing_requirements(state, block,
								   &req);
					ret = SEPOL_EREQ;
					goto out;
				}
			}
		}
	}

	/* 4) else handling
	 *
	 * Iterate through all of the blocks skipping the first (which is the
	 * global block, is required to be present, and cannot have an else).
	 * If the block is disabled and has an else decl, enable that.
	 *
	 * This code assumes that the second block in the branch list is the else
	 * block. This is currently supported by the compiler.
	 */
	for (block = pol->global->next; block != NULL; block = block->next) {
		if (block->enabled == NULL) {
			if (block->branch_list->next != NULL) {
				block->enabled = block->branch_list->next;
				block->branch_list->next->enabled = 1;
			}
		}
	}

      out:
	if (state->verbose)
		debug_requirements(state, pol);

	return ret;
}

/*********** the main linking functions ***********/

/* Given a module's policy, normalize all conditional expressions
 * within.  Return 0 on success, -1 on error. */
static int cond_normalize(policydb_t * p)
{
	avrule_block_t *block;
	for (block = p->global; block != NULL; block = block->next) {
		avrule_decl_t *decl;
		for (decl = block->branch_list; decl != NULL; decl = decl->next) {
			cond_list_t *cond = decl->cond_list;
			while (cond) {
				if (cond_normalize_expr(p, cond) < 0)
					return -1;
				cond = cond->next;
			}
		}
	}
	return 0;
}

/* Allocate space for the various remapping arrays. */
static int prepare_module(link_state_t * state, policy_module_t * module)
{
	int i;
	uint32_t items, num_decls = 0;
	avrule_block_t *cur;

	/* allocate the maps */
	for (i = 0; i < SYM_NUM; i++) {
		items = module->policy->symtab[i].nprim;
		if ((module->map[i] =
		     (uint32_t *) calloc(items,
					 sizeof(*module->map[i]))) == NULL) {
			ERR(state->handle, "Out of memory!");
			return -1;
		}
	}

	/* allocate the permissions remap here */
	items = module->policy->p_classes.nprim;
	if ((module->perm_map_len =
	     calloc(items, sizeof(*module->perm_map_len))) == NULL) {
		ERR(state->handle, "Out of memory!");
		return -1;
	}
	if ((module->perm_map =
	     calloc(items, sizeof(*module->perm_map))) == NULL) {
		ERR(state->handle, "Out of memory!");
		return -1;
	}

	/* allocate a map for avrule_decls */
	for (cur = module->policy->global; cur != NULL; cur = cur->next) {
		avrule_decl_t *decl;
		for (decl = cur->branch_list; decl != NULL; decl = decl->next) {
			if (decl->decl_id > num_decls) {
				num_decls = decl->decl_id;
			}
		}
	}
	num_decls++;
	if ((module->avdecl_map = calloc(num_decls, sizeof(uint32_t))) == NULL) {
		ERR(state->handle, "Out of memory!");
		return -1;
	}
	module->num_decls = num_decls;

	/* normalize conditionals within */
	if (cond_normalize(module->policy) < 0) {
		ERR(state->handle,
		    "Error while normalizing conditionals within the module %s.",
		    module->policy->name);
		return -1;
	}
	return 0;
}

static int prepare_base(link_state_t * state, uint32_t num_mod_decls)
{
	avrule_block_t *cur = state->base->global;
	assert(cur != NULL);
	state->next_decl_id = 0;

	/* iterate through all of the declarations in the base, to
	   determine what the next decl_id should be */
	while (cur != NULL) {
		avrule_decl_t *decl;
		for (decl = cur->branch_list; decl != NULL; decl = decl->next) {
			if (decl->decl_id > state->next_decl_id) {
				state->next_decl_id = decl->decl_id;
			}
		}
		state->last_avrule_block = cur;
		cur = cur->next;
	}
	state->last_base_avrule_block = state->last_avrule_block;
	state->next_decl_id++;

	/* allocate the table mapping from base's decl_id to its
	 * avrule_decls and set the initial mappings */
	free(state->base->decl_val_to_struct);
	if ((state->base->decl_val_to_struct =
	     calloc(state->next_decl_id + num_mod_decls,
		    sizeof(*(state->base->decl_val_to_struct)))) == NULL) {
		ERR(state->handle, "Out of memory!");
		return -1;
	}
	/* This allocates the decl block to module mapping used for error reporting */
	if ((state->decl_to_mod = calloc(state->next_decl_id + num_mod_decls,
					 sizeof(*(state->decl_to_mod)))) ==
	    NULL) {
		ERR(state->handle, "Out of memory!");
		return -1;
	}
	cur = state->base->global;
	while (cur != NULL) {
		avrule_decl_t *decl = cur->branch_list;
		while (decl != NULL) {
			state->base->decl_val_to_struct[decl->decl_id - 1] =
			    decl;
			state->decl_to_mod[decl->decl_id] = state->base;
			decl = decl->next;
		}
		cur = cur->next;
	}

	/* normalize conditionals within */
	if (cond_normalize(state->base) < 0) {
		ERR(state->handle,
		    "Error while normalizing conditionals within the base module.");
		return -1;
	}
	return 0;
}

static int expand_role_attributes(hashtab_key_t key, hashtab_datum_t datum,
				  void * data)
{
	char *id;
	role_datum_t *role, *sub_attr;
	link_state_t *state;
	unsigned int i;
	ebitmap_node_t *rnode;

	id = key;
	role = (role_datum_t *)datum;
	state = (link_state_t *)data;

	if (strcmp(id, OBJECT_R) == 0){
		/* object_r is never a role attribute by far */
		return 0;
	}

	if (role->flavor != ROLE_ATTRIB)
		return 0;

	if (state->verbose)
		INFO(state->handle, "expanding role attribute %s", id);

restart:
	ebitmap_for_each_bit(&role->roles, rnode, i) {
		if (ebitmap_node_get_bit(rnode, i)) {
			sub_attr = state->base->role_val_to_struct[i];
			if (sub_attr->flavor != ROLE_ATTRIB)
				continue;
			
			/* remove the sub role attribute from the parent
			 * role attribute's roles ebitmap */
			if (ebitmap_set_bit(&role->roles, i, 0))
				return -1;

			/* loop dependency of role attributes */
			if (sub_attr->s.value == role->s.value)
				continue;

			/* now go on to expand a sub role attribute
			 * by escalating its roles ebitmap */
			if (ebitmap_union(&role->roles, &sub_attr->roles)) {
				ERR(state->handle, "Out of memory!");
				return -1;
			}
			
			/* sub_attr->roles may contain other role attributes,
			 * re-scan the parent role attribute's roles ebitmap */
			goto restart;
		}
	}

	return 0;
}

/* For any role attribute in a declaration's local symtab[SYM_ROLES] table,
 * copy its roles ebitmap into its duplicate's in the base->p_roles.table.
 */
static int populate_decl_roleattributes(hashtab_key_t key, 
					hashtab_datum_t datum,
					void *data)
{
	char *id = key;
	role_datum_t *decl_role, *base_role;
	link_state_t *state = (link_state_t *)data;

	decl_role = (role_datum_t *)datum;

	if (strcmp(id, OBJECT_R) == 0) {
		/* object_r is never a role attribute by far */
		return 0;
	}

	if (decl_role->flavor != ROLE_ATTRIB)
		return 0;

	base_role = (role_datum_t *)hashtab_search(state->base->p_roles.table,
						   id);
	assert(base_role != NULL && base_role->flavor == ROLE_ATTRIB);

	if (ebitmap_union(&base_role->roles, &decl_role->roles)) {
		ERR(state->handle, "Out of memory!");
		return -1;
	}

	return 0;
}

static int populate_roleattributes(link_state_t *state, policydb_t *pol)
{
	avrule_block_t *block;
	avrule_decl_t *decl;

	if (state->verbose)
		INFO(state->handle, "Populating role-attribute relationship "
			    "from enabled declarations' local symtab.");

	/* Iterate through all of the blocks skipping the first(which is the
	 * global block, is required to be present and can't have an else).
	 * If the block is disabled or not having an enabled decl, skip it.
	 */
	for (block = pol->global->next; block != NULL; block = block->next)
	{
		decl = block->enabled;
		if (decl == NULL || decl->enabled == 0)
			continue;

		if (hashtab_map(decl->symtab[SYM_ROLES].table, 
				populate_decl_roleattributes, state))
			return -1;
	}

	return 0;
}

/* Link a set of modules into a base module. This process is somewhat
 * similar to an actual compiler: it requires a set of order dependent
 * steps.  The base and every module must have been indexed prior to
 * calling this function.
 */
int link_modules(sepol_handle_t * handle,
		 policydb_t * b, policydb_t ** mods, int len, int verbose)
{
	int i, ret, retval = -1;
	policy_module_t **modules = NULL;
	link_state_t state;
	uint32_t num_mod_decls = 0;

	memset(&state, 0, sizeof(state));
	state.base = b;
	state.verbose = verbose;
	state.handle = handle;

	if (b->policy_type != POLICY_BASE) {
		ERR(state.handle, "Target of link was not a base policy.");
		return -1;
	}

	/* first allocate some space to hold the maps from module
	 * symbol's value to the destination symbol value; then do
	 * other preparation work */
	if ((modules =
	     (policy_module_t **) calloc(len, sizeof(*modules))) == NULL) {
		ERR(state.handle, "Out of memory!");
		return -1;
	}
	for (i = 0; i < len; i++) {
		if (mods[i]->policy_type != POLICY_MOD) {
			ERR(state.handle,
			    "Tried to link in a policy that was not a module.");
			goto cleanup;
		}

		if (mods[i]->mls != b->mls) {
			if (b->mls)
				ERR(state.handle,
				    "Tried to link in a non-MLS module with an MLS base.");
			else
				ERR(state.handle,
				    "Tried to link in an MLS module with a non-MLS base.");
			goto cleanup;
		}

		if ((modules[i] =
		     (policy_module_t *) calloc(1,
						sizeof(policy_module_t))) ==
		    NULL) {
			ERR(state.handle, "Out of memory!");
			goto cleanup;
		}
		modules[i]->policy = mods[i];
		if (prepare_module(&state, modules[i]) == -1) {
			goto cleanup;
		}
		num_mod_decls += modules[i]->num_decls;
	}
	if (prepare_base(&state, num_mod_decls) == -1) {
		goto cleanup;
	}

	/* copy all types, declared and required */
	for (i = 0; i < len; i++) {
		state.cur = modules[i];
		state.cur_mod_name = modules[i]->policy->name;
		ret =
		    hashtab_map(modules[i]->policy->p_types.table,
				type_copy_callback, &state);
		if (ret) {
			retval = ret;
			goto cleanup;
		}
	}

	/* then copy everything else, including aliases, and fixup attributes */
	for (i = 0; i < len; i++) {
		state.cur = modules[i];
		state.cur_mod_name = modules[i]->policy->name;
		ret =
		    copy_identifiers(&state, modules[i]->policy->symtab, NULL);
		if (ret) {
			retval = ret;
			goto cleanup;
		}
	}

	if (policydb_index_others(state.handle, state.base, 0)) {
		ERR(state.handle, "Error while indexing others");
		goto cleanup;
	}

	/* copy and remap the module's data over to base */
	for (i = 0; i < len; i++) {
		state.cur = modules[i];
		ret = copy_module(&state, modules[i]);
		if (ret) {
			retval = ret;
			goto cleanup;
		}
	}

	/* re-index base, for symbols were added to symbol tables  */
	if (policydb_index_classes(state.base)) {
		ERR(state.handle, "Error while indexing classes");
		goto cleanup;
	}
	if (policydb_index_others(state.handle, state.base, 0)) {
		ERR(state.handle, "Error while indexing others");
		goto cleanup;
	}

	if (enable_avrules(&state, state.base)) {
		retval = SEPOL_EREQ;
		goto cleanup;
	}

	/* Now that all role attribute's roles ebitmap have been settled,
	 * escalate sub role attribute's roles ebitmap into that of parent.
	 *
	 * First, since some role-attribute relationships could be recorded
	 * in some decl's local symtab(see get_local_role()), we need to
	 * populate them up to the base.p_roles table. */
	if (populate_roleattributes(&state, state.base)) {
		retval = SEPOL_EREQ;
		goto cleanup;
	}
	
	/* Now do the escalation. */
	if (hashtab_map(state.base->p_roles.table, expand_role_attributes,
			&state))
		goto cleanup;

	retval = 0;
      cleanup:
	for (i = 0; modules != NULL && i < len; i++) {
		policy_module_destroy(modules[i]);
	}
	free(modules);
	free(state.decl_to_mod);
	return retval;
}
