All of lore.kernel.org
 help / color / mirror / Atom feed
* [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch
@ 2007-08-16 15:53 Mark Goldman
  2007-08-16 15:53 ` [POLICYREP] [Patch 1/5] << Part 1 >> This patch removes files that existed solely to support modular policies Mark Goldman
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Mark Goldman @ 2007-08-16 15:53 UTC (permalink / raw)
  To: selinux

This patchset removes module support from libsepol.  This
patchset is in support of the policyrep work.

Patches one and two removes the files that are solely for 
supporting modular policies. 

Patch three and four eliminates the various structures that 
supported modular policies. All functional changes occur in 
this patch.

Patch five puts dispol in libsepol's utils directory.
Dispol was not modified in this move.

This e-mail splits the original patches up so that they will go
through the list-serv without being bounced.

-mdg

Signed-off-by: Joshua Brindle <jbrindle@tresys.com>
-- 

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [POLICYREP] [Patch 1/5] << Part 1 >> This patch removes files that existed solely to support modular policies.
  2007-08-16 15:53 [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Mark Goldman
@ 2007-08-16 15:53 ` Mark Goldman
  2007-08-16 15:53 ` [POLICYREP] [Patch 2/5] " Mark Goldman
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Goldman @ 2007-08-16 15:53 UTC (permalink / raw)
  To: selinux

---
 libsepol/include/sepol/module.h |   82 	0 +	82 -	0 !
 libsepol/src/expand.c           | 2679 	0 +	2679 -	0 !
 2 files changed, 2761 deletions(-)

--- foo.orig/libsepol/include/sepol/module.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef _SEPOL_MODULE_H_
-#define _SEPOL_MODULE_H_
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdint.h>
-
-#include <sepol/handle.h>
-#include <sepol/policydb.h>
-
-struct sepol_module_package;
-typedef struct sepol_module_package sepol_module_package_t;
-
-/* Module package public interfaces. */
-
-extern int sepol_module_package_create(sepol_module_package_t ** p);
-
-extern void sepol_module_package_free(sepol_module_package_t * p);
-
-extern char *sepol_module_package_get_file_contexts(sepol_module_package_t * p);
-
-extern size_t sepol_module_package_get_file_contexts_len(sepol_module_package_t
-							 * p);
-
-extern int sepol_module_package_set_file_contexts(sepol_module_package_t * p,
-						  char *data, size_t len);
-
-extern char *sepol_module_package_get_seusers(sepol_module_package_t * p);
-
-extern size_t sepol_module_package_get_seusers_len(sepol_module_package_t * p);
-
-extern int sepol_module_package_set_seusers(sepol_module_package_t * p,
-					    char *data, size_t len);
-
-extern char *sepol_module_package_get_user_extra(sepol_module_package_t * p);
-
-extern size_t sepol_module_package_get_user_extra_len(sepol_module_package_t *
-						      p);
-
-extern int sepol_module_package_set_user_extra(sepol_module_package_t * p,
-					       char *data, size_t len);
-
-extern char *sepol_module_package_get_netfilter_contexts(sepol_module_package_t
-							 * p);
-
-extern size_t
-sepol_module_package_get_netfilter_contexts_len(sepol_module_package_t * p);
-
-extern int sepol_module_package_set_netfilter_contexts(sepol_module_package_t *
-						       p, char *data,
-						       size_t len);
-
-extern sepol_policydb_t *sepol_module_package_get_policy(sepol_module_package_t
-							 * p);
-
-extern int sepol_link_packages(sepol_handle_t * handle,
-			       sepol_module_package_t * base,
-			       sepol_module_package_t ** modules,
-			       int num_modules, int verbose);
-
-extern int sepol_module_package_read(sepol_module_package_t * mod,
-				     struct sepol_policy_file *file,
-				     int verbose);
-
-extern int sepol_module_package_info(struct sepol_policy_file *file,
-				     int *type, char **name, char **version);
-
-extern int sepol_module_package_write(sepol_module_package_t * p,
-				      struct sepol_policy_file *file);
-
-/* Module linking/expanding public interfaces. */
-
-extern int sepol_link_modules(sepol_handle_t * handle,
-			      sepol_policydb_t * base,
-			      sepol_policydb_t ** modules,
-			      size_t len, int verbose);
-
-extern int sepol_expand_module(sepol_handle_t * handle,
-			       sepol_policydb_t * base,
-			       sepol_policydb_t * out, int verbose, int check);
-
-#endif
--- foo.orig/libsepol/src/expand.c
+++ /dev/null
@@ -1,2679 +0,0 @@
-/* Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
- *          Jason Tang <jtang@tresys.com>
- *	    Joshua Brindle <jbrindle@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 "context.h"
-#include <sepol/policydb/policydb.h>
-#include <sepol/policydb/conditional.h>
-#include <sepol/policydb/hashtab.h>
-#include <sepol/policydb/expand.h>
-#include <sepol/policydb/hierarchy.h>
-#include <sepol/policydb/avrule_block.h>
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include "debug.h"
-#include "private.h"
-
-typedef struct expand_state {
-	int verbose;
-	uint32_t *typemap;
-	uint32_t *boolmap;
-	policydb_t *base;
-	policydb_t *out;
-	sepol_handle_t *handle;
-	int expand_neverallow;
-} expand_state_t;
-
-static void expand_state_init(expand_state_t * state)
-{
-	memset(state, 0, sizeof(expand_state_t));
-}
-
-static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-			      void *data)
-{
-	int ret;
-	char *id, *new_id;
-	type_datum_t *type, *new_type;
-	expand_state_t *state;
-
-	id = (char *)key;
-	type = (type_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	if ((type->flavor == TYPE_TYPE && !type->primary)
-	    || type->flavor == TYPE_ALIAS) {
-		/* aliases are handled later */
-		return 0;
-	}
-	if (!is_id_enabled(id, state->base, SYM_TYPES)) {
-		/* identifier's scope is not enabled */
-		return 0;
-	}
-
-	if (state->verbose)
-		INFO(state->handle, "copying type or attribute %s", id);
-
-	new_id = strdup(id);
-	if (new_id == NULL) {
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-
-	new_type = (type_datum_t *) malloc(sizeof(type_datum_t));
-	if (!new_type) {
-		ERR(state->handle, "Out of memory!");
-		free(new_id);
-		return SEPOL_ENOMEM;
-	}
-	memset(new_type, 0, sizeof(type_datum_t));
-
-	new_type->flavor = type->flavor;
-	new_type->s.value = ++state->out->p_types.nprim;
-	if (new_type->s.value > UINT16_MAX) {
-		free(new_id);
-		free(new_type);
-		ERR(state->handle, "type space overflow");
-		return -1;
-	}
-	new_type->primary = 1;
-	state->typemap[type->s.value - 1] = new_type->s.value;
-
-	ret = hashtab_insert(state->out->p_types.table,
-			     (hashtab_key_t) new_id,
-			     (hashtab_datum_t) new_type);
-	if (ret) {
-		free(new_id);
-		free(new_type);
-		ERR(state->handle, "hashtab overflow");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int attr_convert_callback(hashtab_key_t key, hashtab_datum_t datum,
-				 void *data)
-{
-	char *id;
-	type_datum_t *type, *new_type;
-	expand_state_t *state;
-	ebitmap_t tmp_union;
-
-	id = (char *)key;
-	type = (type_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	if (type->flavor != TYPE_ATTRIB)
-		return 0;
-
-	if (!is_id_enabled(id, state->base, SYM_TYPES)) {
-		/* identifier's scope is not enabled */
-		return 0;
-	}
-
-	if (state->verbose)
-		INFO(state->handle, "converting attribute %s", id);
-
-	new_type = hashtab_search(state->out->p_types.table, id);
-	if (!new_type) {
-		ERR(state->handle, "attribute %s vanished!", id);
-		return -1;
-	}
-	if (convert_type_ebitmap(&type->types, &tmp_union, state->typemap)) {
-		ERR(state->handle, "out of memory");
-		return -1;
-	}
-
-	/* then union tmp_union onto &new_type->types */
-	if (ebitmap_union(&new_type->types, &tmp_union)) {
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-	ebitmap_destroy(&tmp_union);
-
-	return 0;
-}
-
-static int perm_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-			      void *data)
-{
-	int ret;
-	char *id, *new_id;
-	symtab_t *s;
-	perm_datum_t *perm, *new_perm;
-
-	id = key;
-	perm = (perm_datum_t *) datum;
-	s = (symtab_t *) data;
-
-	new_perm = (perm_datum_t *) malloc(sizeof(perm_datum_t));
-	if (!new_perm) {
-		return -1;
-	}
-	memset(new_perm, 0, sizeof(perm_datum_t));
-
-	new_id = strdup(id);
-	if (!new_id) {
-		free(new_perm);
-		return -1;
-	}
-
-	new_perm->s.value = perm->s.value;
-	s->nprim++;
-
-	ret = hashtab_insert(s->table, new_id, (hashtab_datum_t *) new_perm);
-	if (ret) {
-		free(new_id);
-		free(new_perm);
-		return -1;
-	}
-
-	return 0;
-}
-
-static int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-				void *data)
-{
-	int ret;
-	char *id, *new_id;
-	common_datum_t *common, *new_common;
-	expand_state_t *state;
-
-	id = (char *)key;
-	common = (common_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	if (state->verbose)
-		INFO(state->handle, "copying common %s", id);
-
-	new_common = (common_datum_t *) malloc(sizeof(common_datum_t));
-	if (!new_common) {
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-	memset(new_common, 0, sizeof(common_datum_t));
-	if (symtab_init(&new_common->permissions, PERM_SYMTAB_SIZE)) {
-		ERR(state->handle, "Out of memory!");
-		free(new_common);
-		return -1;
-	}
-
-	new_id = strdup(id);
-	if (!new_id) {
-		ERR(state->handle, "Out of memory!");
-		free(new_common);
-		return -1;
-	}
-
-	new_common->s.value = common->s.value;
-	state->out->p_commons.nprim++;
-
-	ret =
-	    hashtab_insert(state->out->p_commons.table, new_id,
-			   (hashtab_datum_t *) new_common);
-	if (ret) {
-		ERR(state->handle, "hashtab overflow");
-		free(new_common);
-		free(new_id);
-		return -1;
-	}
-
-	if (hashtab_map
-	    (common->permissions.table, perm_copy_callback,
-	     &new_common->permissions)) {
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int constraint_node_clone(constraint_node_t ** dst,
-				 constraint_node_t * src,
-				 expand_state_t * state)
-{
-	constraint_node_t *new_con = NULL, *last_new_con = NULL;
-	constraint_expr_t *new_expr = NULL;
-	*dst = NULL;
-	while (src != NULL) {
-		constraint_expr_t *expr, *expr_l = NULL;
-		new_con =
-		    (constraint_node_t *) malloc(sizeof(constraint_node_t));
-		if (!new_con) {
-			goto out_of_mem;
-		}
-		memset(new_con, 0, sizeof(constraint_node_t));
-		new_con->permissions = src->permissions;
-		for (expr = src->expr; expr; expr = expr->next) {
-			if ((new_expr = calloc(1, sizeof(*new_expr))) == NULL) {
-				goto out_of_mem;
-			}
-			if (constraint_expr_init(new_expr) == -1) {
-				goto out_of_mem;
-			}
-			new_expr->expr_type = expr->expr_type;
-			new_expr->attr = expr->attr;
-			new_expr->op = expr->op;
-			if (new_expr->expr_type == CEXPR_NAMES) {
-				if (new_expr->attr & CEXPR_TYPE) {
-					/* Type sets require expansion and conversion. */
-					if (expand_convert_type_set(state->out,
-								    state->
-								    typemap,
-								    expr->
-								    type_names,
-								    &new_expr->
-								    names, 1)) {
-						goto out_of_mem;
-					}
-				} else {
-					/* Other kinds of sets do not. */
-					if (ebitmap_cpy(&new_expr->names,
-							&expr->names)) {
-						goto out_of_mem;
-					}
-				}
-			}
-			if (expr_l) {
-				expr_l->next = new_expr;
-			} else {
-				new_con->expr = new_expr;
-			}
-			expr_l = new_expr;
-			new_expr = NULL;
-		}
-		if (last_new_con == NULL) {
-			*dst = new_con;
-		} else {
-			last_new_con->next = new_con;
-		}
-		last_new_con = new_con;
-		src = src->next;
-	}
-
-	return 0;
-      out_of_mem:
-	ERR(state->handle, "Out of memory!");
-	if (new_con)
-		free(new_con);
-	constraint_expr_destroy(new_expr);
-	return -1;
-}
-
-static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-			       void *data)
-{
-	int ret;
-	char *id, *new_id;
-	class_datum_t *class, *new_class;
-	expand_state_t *state;
-
-	id = (char *)key;
-	class = (class_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	if (!is_id_enabled(id, state->base, SYM_CLASSES)) {
-		/* identifier's scope is not enabled */
-		return 0;
-	}
-
-	if (state->verbose)
-		INFO(state->handle, "copying class %s", id);
-
-	new_class = (class_datum_t *) malloc(sizeof(class_datum_t));
-	if (!new_class) {
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-	memset(new_class, 0, sizeof(class_datum_t));
-	if (symtab_init(&new_class->permissions, PERM_SYMTAB_SIZE)) {
-		ERR(state->handle, "Out of memory!");
-		free(new_class);
-		return -1;
-	}
-
-	new_class->s.value = class->s.value;
-	state->out->p_classes.nprim++;
-
-	new_id = strdup(id);
-	if (!new_id) {
-		ERR(state->handle, "Out of memory!");
-		free(new_class);
-		return -1;
-	}
-
-	ret =
-	    hashtab_insert(state->out->p_classes.table, new_id,
-			   (hashtab_datum_t *) new_class);
-	if (ret) {
-		ERR(state->handle, "hashtab overflow");
-		free(new_class);
-		free(new_id);
-		return -1;
-	}
-
-	if (hashtab_map
-	    (class->permissions.table, perm_copy_callback,
-	     &new_class->permissions)) {
-		ERR(state->handle, "hashtab overflow");
-		return -1;
-	}
-
-	if (class->comkey) {
-		new_class->comkey = strdup(class->comkey);
-		if (!new_class->comkey) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-
-		new_class->comdatum =
-		    hashtab_search(state->out->p_commons.table,
-				   new_class->comkey);
-		if (!new_class->comdatum) {
-			ERR(state->handle, "could not find common datum %s",
-			    new_class->comkey);
-			return -1;
-		}
-		new_class->permissions.nprim +=
-		    new_class->comdatum->permissions.nprim;
-	}
-
-	return 0;
-}
-
-static int constraint_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-				    void *data)
-{
-	char *id;
-	class_datum_t *class, *new_class;
-	expand_state_t *state;
-
-	id = (char *)key;
-	class = (class_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	new_class = hashtab_search(state->out->p_classes.table, id);
-	if (!new_class) {
-		ERR(state->handle, "class %s vanished", id);
-		return -1;
-	}
-
-	/* constraints */
-	if (constraint_node_clone
-	    (&new_class->constraints, class->constraints, state) == -1
-	    || constraint_node_clone(&new_class->validatetrans,
-				     class->validatetrans, state) == -1) {
-		return -1;
-	}
-	return 0;
-}
-
-/* The aliases have to be copied after the types and attributes to be certain that
- * the out 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)
-{
-	int ret;
-	char *id, *new_id;
-	type_datum_t *alias, *new_alias;
-	expand_state_t *state;
-
-	id = (char *)key;
-	alias = (type_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	/* ignore regular types */
-	if (alias->flavor == TYPE_TYPE && alias->primary)
-		return 0;
-
-	/* ignore attributes */
-	if (alias->flavor == TYPE_ATTRIB)
-		return 0;
-
-	if (state->verbose)
-		INFO(state->handle, "copying alias %s", id);
-
-	new_id = strdup(id);
-	if (!new_id) {
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-
-	new_alias = (type_datum_t *) malloc(sizeof(type_datum_t));
-	if (!new_alias) {
-		ERR(state->handle, "Out of memory!");
-		free(new_id);
-		return SEPOL_ENOMEM;
-	}
-	memset(new_alias, 0, sizeof(type_datum_t));
-	if (alias->flavor == TYPE_TYPE)
-		new_alias->s.value = state->typemap[alias->s.value - 1];
-	else if (alias->flavor == TYPE_ALIAS)
-		new_alias->s.value = state->typemap[alias->primary - 1];
-	else
-		assert(0);	/* unreachable */
-
-	ret = hashtab_insert(state->out->p_types.table,
-			     (hashtab_key_t) new_id,
-			     (hashtab_datum_t) new_alias);
-
-	if (ret) {
-		ERR(state->handle, "hashtab overflow");
-		free(new_alias);
-		free(new_id);
-		return -1;
-	}
-
-	state->typemap[alias->s.value - 1] = new_alias->s.value;
-	return 0;
-}
-
-static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-			      void *data)
-{
-	int ret;
-	char *id, *new_id;
-	role_datum_t *role;
-	role_datum_t *new_role;
-	expand_state_t *state;
-	ebitmap_t tmp_union_types;
-
-	id = key;
-	role = (role_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	if (strcmp(id, OBJECT_R) == 0)
-		return 0;
-
-	if (!is_id_enabled(id, state->base, SYM_ROLES)) {
-		/* identifier's scope is not enabled */
-		return 0;
-	}
-
-	if (state->verbose)
-		INFO(state->handle, "copying role %s", id);
-
-	new_role =
-	    (role_datum_t *) hashtab_search(state->out->p_roles.table, id);
-	if (!new_role) {
-		new_role = (role_datum_t *) malloc(sizeof(role_datum_t));
-		if (!new_role) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		memset(new_role, 0, sizeof(role_datum_t));
-
-		new_id = strdup(id);
-		if (!new_id) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-
-		new_role->s.value = role->s.value;
-		state->out->p_roles.nprim++;
-		ret = hashtab_insert(state->out->p_roles.table,
-				     (hashtab_key_t) new_id,
-				     (hashtab_datum_t) new_role);
-
-		if (ret) {
-			ERR(state->handle, "hashtab overflow");
-			free(new_role);
-			free(new_id);
-			return -1;
-		}
-	}
-
-	if (!(&new_role->dominates.node)) {
-		ebitmap_init(&new_role->dominates);
-	}
-
-	if (ebitmap_union(&new_role->dominates, &role->dominates)) {
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-
-	ebitmap_init(&tmp_union_types);
-
-	/* convert types in the role datum in the global symtab */
-	if (expand_convert_type_set
-	    (state->out, state->typemap, &role->types, &tmp_union_types, 1)) {
-		ebitmap_destroy(&tmp_union_types);
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-
-	if (!(&new_role->types.types.node)) {
-		ebitmap_init(&new_role->types.types);
-	}
-
-	if (ebitmap_union(&new_role->types.types, &tmp_union_types)) {
-		ERR(state->handle, "Out of memory!");
-		ebitmap_destroy(&tmp_union_types);
-		return -1;
-	}
-	ebitmap_destroy(&tmp_union_types);
-
-	return 0;
-}
-
-int mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l,
-			      policydb_t * p, sepol_handle_t * h)
-{
-	mls_semantic_cat_t *cat;
-	level_datum_t *levdatum;
-	unsigned int i;
-
-	mls_level_init(l);
-
-	if (!p->mls)
-		return 0;
-
-	l->sens = sl->sens;
-	levdatum = (level_datum_t *) hashtab_search(p->p_levels.table,
-						    p->p_sens_val_to_name[l->
-									  sens -
-									  1]);
-	for (cat = sl->cat; cat; cat = cat->next) {
-		if (cat->low > cat->high) {
-			ERR(h, "Category range is not valid %s.%s",
-			    p->p_cat_val_to_name[cat->low - 1],
-			    p->p_cat_val_to_name[cat->high - 1]);
-			return -1;
-		}
-		for (i = cat->low - 1; i < cat->high; i++) {
-			if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
-				ERR(h, "Category %s can not be associate with "
-				    "level %s",
-				    p->p_cat_val_to_name[i],
-				    p->p_sens_val_to_name[l->sens - 1]);
-			}
-			if (ebitmap_set_bit(&l->cat, i, 1)) {
-				ERR(h, "Out of memory!");
-				return -1;
-			}
-		}
-	}
-
-	return 0;
-}
-
-int mls_semantic_range_expand(mls_semantic_range_t * sr, mls_range_t * r,
-			      policydb_t * p, sepol_handle_t * h)
-{
-	if (mls_semantic_level_expand(&sr->level[0], &r->level[0], p, h) < 0)
-		return -1;
-
-	if (mls_semantic_level_expand(&sr->level[1], &r->level[1], p, h) < 0) {
-		mls_semantic_level_destroy(&sr->level[0]);
-		return -1;
-	}
-
-	if (!mls_level_dom(&r->level[1], &r->level[0])) {
-		mls_range_destroy(r);
-		ERR(h, "MLS range high level does not dominate low level");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-			      void *data)
-{
-	int ret;
-	expand_state_t *state;
-	user_datum_t *user;
-	user_datum_t *new_user;
-	char *id, *new_id;
-	ebitmap_t tmp_union;
-
-	id = key;
-	user = (user_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	if (!is_id_enabled(id, state->base, SYM_USERS)) {
-		/* identifier's scope is not enabled */
-		return 0;
-	}
-
-	if (state->verbose)
-		INFO(state->handle, "copying user %s", id);
-
-	new_user =
-	    (user_datum_t *) hashtab_search(state->out->p_users.table, id);
-	if (!new_user) {
-		new_user = (user_datum_t *) malloc(sizeof(user_datum_t));
-		if (!new_user) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		memset(new_user, 0, sizeof(user_datum_t));
-
-		new_user->s.value = user->s.value;
-		state->out->p_users.nprim++;
-
-		new_id = strdup(id);
-		if (!new_id) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		ret = hashtab_insert(state->out->p_users.table,
-				     (hashtab_key_t) new_id,
-				     (hashtab_datum_t) new_user);
-		if (ret) {
-			ERR(state->handle, "hashtab overflow");
-			user_datum_destroy(new_user);
-			free(new_user);
-			free(new_id);
-			return -1;
-		}
-
-		/* expand the semantic MLS info */
-		if (mls_semantic_range_expand(&user->range,
-					      &new_user->exp_range,
-					      state->out, state->handle)) {
-			return -1;
-		}
-		if (mls_semantic_level_expand(&user->dfltlevel,
-					      &new_user->exp_dfltlevel,
-					      state->out, state->handle)) {
-			return -1;
-		}
-		if (!mls_level_between(&new_user->exp_dfltlevel,
-				       &new_user->exp_range.level[0],
-				       &new_user->exp_range.level[1])) {
-			ERR(state->handle, "default level not within user "
-			    "range");
-			return -1;
-		}
-	} else {
-		/* require that the MLS info match */
-		mls_range_t tmp_range;
-		mls_level_t tmp_level;
-
-		if (mls_semantic_range_expand(&user->range, &tmp_range,
-					      state->out, state->handle)) {
-			return -1;
-		}
-		if (mls_semantic_level_expand(&user->dfltlevel, &tmp_level,
-					      state->out, state->handle)) {
-			mls_range_destroy(&tmp_range);
-			return -1;
-		}
-		if (!mls_range_eq(&new_user->exp_range, &tmp_range) ||
-		    !mls_level_eq(&new_user->exp_dfltlevel, &tmp_level)) {
-			mls_range_destroy(&tmp_range);
-			mls_level_destroy(&tmp_level);
-			return -1;
-		}
-		mls_range_destroy(&tmp_range);
-		mls_level_destroy(&tmp_level);
-	}
-
-	ebitmap_init(&tmp_union);
-
-	/* get global roles for this user */
-	if (role_set_expand(&user->roles, &tmp_union, state->base)) {
-		ERR(state->handle, "Out of memory!");
-		ebitmap_destroy(&tmp_union);
-		return -1;
-	}
-
-	if (!(&new_user->roles.roles.node)) {
-		ebitmap_init(&new_user->roles.roles);
-	}
-
-	if (ebitmap_union(&new_user->roles.roles, &tmp_union)) {
-		ERR(state->handle, "Out of memory!");
-		ebitmap_destroy(&tmp_union);
-		return -1;
-	}
-	ebitmap_destroy(&tmp_union);
-
-	return 0;
-}
-
-static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-			      void *data)
-{
-	int ret;
-	expand_state_t *state;
-	cond_bool_datum_t *bool, *new_bool;
-	char *id, *new_id;
-
-	id = key;
-	bool = (cond_bool_datum_t *) datum;
-	state = (expand_state_t *) data;
-
-	if (!is_id_enabled(id, state->base, SYM_BOOLS)) {
-		/* identifier's scope is not enabled */
-		return 0;
-	}
-
-	if (state->verbose)
-		INFO(state->handle, "copying boolean %s", id);
-
-	new_bool = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
-	if (!new_bool) {
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-
-	new_id = strdup(id);
-	if (!new_id) {
-		ERR(state->handle, "Out of memory!");
-		free(new_bool);
-		return -1;
-	}
-
-	state->out->p_bools.nprim++;
-	new_bool->s.value = state->out->p_bools.nprim;
-
-	ret = hashtab_insert(state->out->p_bools.table,
-			     (hashtab_key_t) new_id,
-			     (hashtab_datum_t) new_bool);
-	if (ret) {
-		ERR(state->handle, "hashtab overflow");
-		free(new_bool);
-		free(new_id);
-		return -1;
-	}
-
-	state->boolmap[bool->s.value - 1] = new_bool->s.value;
-
-	new_bool->state = bool->state;
-
-	return 0;
-}
-
-static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-			      void *data)
-{
-	expand_state_t *state = (expand_state_t *) data;
-	level_datum_t *level = (level_datum_t *) datum, *new_level = NULL;
-	char *id = (char *)key, *new_id = NULL;
-
-	if (!is_id_enabled(id, state->base, SYM_LEVELS)) {
-		/* identifier's scope is not enabled */
-		return 0;
-	}
-
-	if (state->verbose)
-		INFO(state->handle, "copying sensitivity level %s", id);
-
-	new_level = (level_datum_t *) malloc(sizeof(level_datum_t));
-	if (!new_level)
-		goto out_of_mem;
-	level_datum_init(new_level);
-	new_level->level = (mls_level_t *) malloc(sizeof(mls_level_t));
-	if (!new_level->level)
-		goto out_of_mem;
-	mls_level_init(new_level->level);
-	new_id = strdup(id);
-	if (!new_id)
-		goto out_of_mem;
-
-	if (mls_level_cpy(new_level->level, level->level)) {
-		goto out_of_mem;
-	}
-	new_level->isalias = level->isalias;
-	state->out->p_levels.nprim++;
-
-	if (hashtab_insert(state->out->p_levels.table,
-			   (hashtab_key_t) new_id,
-			   (hashtab_datum_t) new_level)) {
-		goto out_of_mem;
-	}
-	return 0;
-
-      out_of_mem:
-	ERR(state->handle, "Out of memory!");
-	if (new_level != NULL && new_level->level != NULL) {
-		mls_level_destroy(new_level->level);
-		free(new_level->level);
-	}
-	level_datum_destroy(new_level);
-	free(new_level);
-	free(new_id);
-	return -1;
-}
-
-static int cats_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
-			      void *data)
-{
-	expand_state_t *state = (expand_state_t *) data;
-	cat_datum_t *cat = (cat_datum_t *) datum, *new_cat = NULL;
-	char *id = (char *)key, *new_id = NULL;
-
-	if (!is_id_enabled(id, state->base, SYM_CATS)) {
-		/* identifier's scope is not enabled */
-		return 0;
-	}
-
-	if (state->verbose)
-		INFO(state->handle, "copying category attribute %s", id);
-
-	new_cat = (cat_datum_t *) malloc(sizeof(cat_datum_t));
-	if (!new_cat)
-		goto out_of_mem;
-	cat_datum_init(new_cat);
-	new_id = strdup(id);
-	if (!new_id)
-		goto out_of_mem;
-
-	new_cat->s.value = cat->s.value;
-	new_cat->isalias = cat->isalias;
-	state->out->p_cats.nprim++;
-	if (hashtab_insert(state->out->p_cats.table,
-			   (hashtab_key_t) new_id, (hashtab_datum_t) new_cat)) {
-		goto out_of_mem;
-	}
-
-	return 0;
-
-      out_of_mem:
-	ERR(state->handle, "Out of memory!");
-	cat_datum_destroy(new_cat);
-	free(new_cat);
-	free(new_id);
-	return -1;
-}
-
-static int copy_role_allows(expand_state_t * state, role_allow_rule_t * rules)
-{
-	unsigned int i, j;
-	role_allow_t *cur_allow, *n, *l;
-	role_allow_rule_t *cur;
-	ebitmap_t roles, new_roles;
-	ebitmap_node_t *snode, *tnode;
-
-	/* start at the end of the list */
-	for (l = state->out->role_allow; l && l->next; l = l->next) ;
-
-	cur = rules;
-	while (cur) {
-		ebitmap_init(&roles);
-		ebitmap_init(&new_roles);
-
-		if (role_set_expand(&cur->roles, &roles, state->out)) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		if (role_set_expand(&cur->new_roles, &new_roles, state->out)) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		ebitmap_for_each_bit(&roles, snode, i) {
-			if (!ebitmap_node_get_bit(snode, i))
-				continue;
-			ebitmap_for_each_bit(&new_roles, tnode, j) {
-				if (!ebitmap_node_get_bit(tnode, j))
-					continue;
-				/* check for duplicates */
-				cur_allow = state->out->role_allow;
-				while (cur_allow) {
-					if ((cur_allow->role == i + 1) &&
-					    (cur_allow->new_role == j + 1))
-						break;
-					cur_allow = cur_allow->next;
-				}
-				if (cur_allow)
-					continue;
-				n = (role_allow_t *)
-				    malloc(sizeof(role_allow_t));
-				if (!n) {
-					ERR(state->handle, "Out of memory!");
-					return -1;
-				}
-				memset(n, 0, sizeof(role_allow_t));
-				n->role = i + 1;
-				n->new_role = j + 1;
-				if (l) {
-					l->next = n;
-				} else {
-					state->out->role_allow = n;
-				}
-				l = n;
-			}
-		}
-
-		ebitmap_destroy(&roles);
-		ebitmap_destroy(&new_roles);
-
-		cur = cur->next;
-	}
-
-	return 0;
-}
-
-static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules)
-{
-	unsigned int i, j;
-	role_trans_t *n, *l, *cur_trans;
-	role_trans_rule_t *cur;
-	ebitmap_t roles, types;
-	ebitmap_node_t *rnode, *tnode;
-
-	/* start at the end of the list */
-	for (l = state->out->role_tr; l && l->next; l = l->next) ;
-
-	cur = rules;
-	while (cur) {
-		ebitmap_init(&roles);
-		ebitmap_init(&types);
-
-		if (role_set_expand(&cur->roles, &roles, state->out)) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		if (expand_convert_type_set
-		    (state->out, state->typemap, &cur->types, &types, 1)) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		ebitmap_for_each_bit(&roles, rnode, i) {
-			if (!ebitmap_node_get_bit(rnode, i))
-				continue;
-			ebitmap_for_each_bit(&types, tnode, j) {
-				if (!ebitmap_node_get_bit(tnode, j))
-					continue;
-
-				cur_trans = state->out->role_tr;
-				while (cur_trans) {
-					if ((cur_trans->role == i + 1) &&
-					    (cur_trans->type == j + 1)) {
-						if (cur_trans->new_role ==
-						    cur->new_role) {
-							break;
-						} else {
-							ERR(state->handle,
-							    "Conflicting role trans rule %s %s : %s",
-							    state->out->
-							    p_role_val_to_name
-							    [i],
-							    state->out->
-							    p_type_val_to_name
-							    [j],
-							    state->out->
-							    p_role_val_to_name
-							    [cur->new_role -
-							     1]);
-							return -1;
-						}
-					}
-					cur_trans = cur_trans->next;
-				}
-				if (cur_trans)
-					continue;
-
-				n = (role_trans_t *)
-				    malloc(sizeof(role_trans_t));
-				if (!n) {
-					ERR(state->handle, "Out of memory!");
-					return -1;
-				}
-				memset(n, 0, sizeof(role_trans_t));
-				n->role = i + 1;
-				n->type = j + 1;
-				n->new_role = cur->new_role;
-				if (l) {
-					l->next = n;
-				} else {
-					state->out->role_tr = n;
-				}
-				l = n;
-			}
-		}
-
-		ebitmap_destroy(&roles);
-		ebitmap_destroy(&types);
-
-		cur = cur->next;
-	}
-	return 0;
-}
-
-static int exp_rangetr_helper(uint32_t stype, uint32_t ttype, uint32_t tclass,
-			      mls_semantic_range_t * trange,
-			      expand_state_t * state)
-{
-	range_trans_t *rt, *check_rt = state->out->range_tr;
-	mls_range_t exp_range;
-	int rc = -1;
-
-	if (mls_semantic_range_expand(trange, &exp_range, state->out,
-				      state->handle))
-		goto out;
-
-	/* check for duplicates/conflicts */
-	while (check_rt) {
-		if ((check_rt->source_type == stype) &&
-		    (check_rt->target_type == ttype) &&
-		    (check_rt->target_class == tclass)) {
-			if (mls_range_eq(&check_rt->target_range, &exp_range)) {
-				/* duplicate */
-				break;
-			} else {
-				/* conflict */
-				ERR(state->handle,
-				    "Conflicting range trans rule %s %s : %s",
-				    state->out->p_type_val_to_name[stype - 1],
-				    state->out->p_type_val_to_name[ttype - 1],
-				    state->out->p_class_val_to_name[tclass -
-								    1]);
-				goto out;
-			}
-		}
-		check_rt = check_rt->next;
-	}
-	if (check_rt) {
-		/* this is a dup - skip */
-		rc = 0;
-		goto out;
-	}
-
-	rt = (range_trans_t *) calloc(1, sizeof(range_trans_t));
-	if (!rt) {
-		ERR(state->handle, "Out of memory!");
-		goto out;
-	}
-
-	rt->next = state->out->range_tr;
-	state->out->range_tr = rt;
-
-	rt->source_type = stype;
-	rt->target_type = ttype;
-	rt->target_class = tclass;
-	if (mls_range_cpy(&rt->target_range, &exp_range)) {
-		ERR(state->handle, "Out of memory!");
-		goto out;
-	}
-
-	rc = 0;
-
-      out:
-	mls_range_destroy(&exp_range);
-	return rc;
-}
-
-static int expand_range_trans(expand_state_t * state,
-			      range_trans_rule_t * rules)
-{
-	unsigned int i, j, k;
-	range_trans_rule_t *rule;
-
-	ebitmap_t stypes, ttypes;
-	ebitmap_node_t *snode, *tnode, *cnode;
-
-	if (state->verbose)
-		INFO(state->handle, "expanding range transitions");
-
-	for (rule = rules; rule; rule = rule->next) {
-		ebitmap_init(&stypes);
-		ebitmap_init(&ttypes);
-
-		/* expand the type sets */
-		if (expand_convert_type_set(state->out, state->typemap,
-					    &rule->stypes, &stypes, 1)) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		if (expand_convert_type_set(state->out, state->typemap,
-					    &rule->ttypes, &ttypes, 1)) {
-			ebitmap_destroy(&stypes);
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-
-		/* loop on source type */
-		ebitmap_for_each_bit(&stypes, snode, i) {
-			if (!ebitmap_node_get_bit(snode, i))
-				continue;
-			/* loop on target type */
-			ebitmap_for_each_bit(&ttypes, tnode, j) {
-				if (!ebitmap_node_get_bit(tnode, j))
-					continue;
-				/* loop on target class */
-				ebitmap_for_each_bit(&rule->tclasses, cnode, k) {
-					if (!ebitmap_node_get_bit(cnode, k))
-						continue;
-
-					if (exp_rangetr_helper(i + 1,
-							       j + 1,
-							       k + 1,
-							       &rule->trange,
-							       state)) {
-						ebitmap_destroy(&stypes);
-						ebitmap_destroy(&ttypes);
-						return -1;
-					}
-				}
-			}
-		}
-
-		ebitmap_destroy(&stypes);
-		ebitmap_destroy(&ttypes);
-	}
-
-	return 0;
-}
-
-/* Search for an AV tab node within a hash table with the given key.
- * If the node does not exist, create it and return it; otherwise
- * return the pre-existing one.
-*/
-static avtab_ptr_t find_avtab_node(sepol_handle_t * handle,
-				   avtab_t * avtab, avtab_key_t * key,
-				   cond_av_list_t ** cond)
-{
-	avtab_ptr_t node;
-	avtab_datum_t avdatum;
-	cond_av_list_t *nl;
-
-	node = avtab_search_node(avtab, key);
-
-	/* If this is for conditional policies, keep searching in case
-	   the node is part of my conditional avtab. */
-	if (cond) {
-		while (node) {
-			if (node->parse_context == cond)
-				break;
-			node = avtab_search_node_next(node, key->specified);
-		}
-	}
-
-	if (!node) {
-		memset(&avdatum, 0, sizeof avdatum);
-		/* this is used to get the node - insertion is actually unique */
-		node = avtab_insert_nonunique(avtab, key, &avdatum);
-		if (!node) {
-			ERR(handle, "hash table overflow");
-			return NULL;
-		}
-		if (cond) {
-			node->parse_context = cond;
-			nl = (cond_av_list_t *) malloc(sizeof(cond_av_list_t));
-			if (!nl) {
-				ERR(handle, "Memory error");
-				return NULL;
-			}
-			memset(nl, 0, sizeof(cond_av_list_t));
-			nl->node = node;
-			nl->next = *cond;
-			*cond = nl;
-		}
-	}
-
-	return node;
-}
-
-#define EXPAND_RULE_SUCCESS   1
-#define EXPAND_RULE_CONFLICT  0
-#define EXPAND_RULE_ERROR    -1
-
-static int expand_terule_helper(sepol_handle_t * handle,
-				policydb_t * p, uint32_t * typemap,
-				uint32_t specified, cond_av_list_t ** cond,
-				cond_av_list_t ** other, uint32_t stype,
-				uint32_t ttype, class_perm_node_t * perms,
-				avtab_t * avtab, int enabled)
-{
-	avtab_key_t avkey;
-	avtab_datum_t *avdatump;
-	avtab_ptr_t node;
-	class_perm_node_t *cur;
-	int conflict;
-	uint32_t oldtype = 0, spec = 0;
-
-	if (specified & AVRULE_TRANSITION) {
-		spec = AVTAB_TRANSITION;
-	} else if (specified & AVRULE_MEMBER) {
-		spec = AVTAB_MEMBER;
-	} else if (specified & AVRULE_CHANGE) {
-		spec = AVTAB_CHANGE;
-	} else {
-		assert(0);	/* unreachable */
-	}
-
-	cur = perms;
-	while (cur) {
-		uint32_t remapped_data =
-		    typemap ? typemap[cur->data - 1] : cur->data;
-		avkey.source_type = stype + 1;
-		avkey.target_type = ttype + 1;
-		avkey.target_class = cur->class;
-		avkey.specified = spec;
-
-		conflict = 0;
-		/* check to see if the expanded TE already exists --
-		 * either in the global scope or in another
-		 * conditional AV tab */
-		node = avtab_search_node(&p->te_avtab, &avkey);
-		if (node) {
-			conflict = 1;
-		} else {
-			node = avtab_search_node(&p->te_cond_avtab, &avkey);
-			if (node && node->parse_context != other) {
-				conflict = 2;
-			}
-		}
-
-		if (conflict) {
-			avdatump = &node->datum;
-			if (specified & AVRULE_TRANSITION) {
-				oldtype = avdatump->data;
-			} else if (specified & AVRULE_MEMBER) {
-				oldtype = avdatump->data;
-			} else if (specified & AVRULE_CHANGE) {
-				oldtype = avdatump->data;
-			}
-
-			if (oldtype == remapped_data) {
-				/* if the duplicate is inside the same scope (eg., unconditional 
-				 * or in same conditional then ignore it */
-				if ((conflict == 1 && cond == NULL)
-				    || node->parse_context == cond)
-					return EXPAND_RULE_SUCCESS;
-				ERR(handle, "duplicate TE rule for %s %s:%s %s",
-				    p->p_type_val_to_name[avkey.source_type -
-							  1],
-				    p->p_type_val_to_name[avkey.target_type -
-							  1],
-				    p->p_class_val_to_name[avkey.target_class -
-							   1],
-				    p->p_type_val_to_name[oldtype - 1]);
-				return EXPAND_RULE_CONFLICT;
-			}
-			ERR(handle,
-			    "conflicting TE rule for (%s, %s:%s):  old was %s, new is %s",
-			    p->p_type_val_to_name[avkey.source_type - 1],
-			    p->p_type_val_to_name[avkey.target_type - 1],
-			    p->p_class_val_to_name[avkey.target_class - 1],
-			    p->p_type_val_to_name[oldtype - 1],
-			    p->p_type_val_to_name[remapped_data - 1]);
-			return EXPAND_RULE_CONFLICT;
-		}
-
-		node = find_avtab_node(handle, avtab, &avkey, cond);
-		if (!node)
-			return -1;
-		if (enabled) {
-			node->key.specified |= AVTAB_ENABLED;
-		} else {
-			node->key.specified &= ~AVTAB_ENABLED;
-		}
-
-		avdatump = &node->datum;
-		if (specified & AVRULE_TRANSITION) {
-			avdatump->data = remapped_data;
-		} else if (specified & AVRULE_MEMBER) {
-			avdatump->data = remapped_data;
-		} else if (specified & AVRULE_CHANGE) {
-			avdatump->data = remapped_data;
-		} else {
-			assert(0);	/* should never occur */
-		}
-
-		cur = cur->next;
-	}
-
-	return EXPAND_RULE_SUCCESS;
-}
-
-static int expand_avrule_helper(sepol_handle_t * handle,
-				uint32_t specified,
-				cond_av_list_t ** cond,
-				uint32_t stype, uint32_t ttype,
-				class_perm_node_t * perms, avtab_t * avtab,
-				int enabled)
-{
-	avtab_key_t avkey;
-	avtab_datum_t *avdatump;
-	avtab_ptr_t node;
-	class_perm_node_t *cur;
-	uint32_t spec = 0;
-
-	if (specified & AVRULE_ALLOWED) {
-		spec = AVTAB_ALLOWED;
-	} else if (specified & AVRULE_AUDITALLOW) {
-		spec = AVTAB_AUDITALLOW;
-	} else if (specified & AVRULE_AUDITDENY) {
-		spec = AVTAB_AUDITDENY;
-	} else if (specified & AVRULE_DONTAUDIT) {
-		spec = AVTAB_AUDITDENY;
-	} else if (specified & AVRULE_NEVERALLOW) {
-		spec = AVTAB_NEVERALLOW;
-	} else {
-		assert(0);	/* unreachable */
-	}
-
-	cur = perms;
-	while (cur) {
-		avkey.source_type = stype + 1;
-		avkey.target_type = ttype + 1;
-		avkey.target_class = cur->class;
-		avkey.specified = spec;
-
-		node = find_avtab_node(handle, avtab, &avkey, cond);
-		if (!node)
-			return EXPAND_RULE_ERROR;
-		if (enabled) {
-			node->key.specified |= AVTAB_ENABLED;
-		} else {
-			node->key.specified &= ~AVTAB_ENABLED;
-		}
-
-		avdatump = &node->datum;
-		if (specified & AVRULE_ALLOWED) {
-			avdatump->data |= cur->data;
-		} else if (specified & AVRULE_AUDITALLOW) {
-			avdatump->data |= cur->data;
-		} else if (specified & AVRULE_NEVERALLOW) {
-			avdatump->data |= cur->data;
-		} else if (specified & AVRULE_AUDITDENY) {
-			/* Since a '0' in an auditdeny mask represents
-			 * a permission we do NOT want to audit
-			 * (dontaudit), we use the '&' operand to
-			 * ensure that all '0's in the mask are
-			 * retained (much unlike the allow and
-			 * auditallow cases).
-			 */
-			avdatump->data &= cur->data;
-		} else if (specified & AVRULE_DONTAUDIT) {
-			if (avdatump->data)
-				avdatump->data &= ~cur->data;
-			else
-				avdatump->data = ~cur->data;
-		} else {
-			assert(0);	/* should never occur */
-		}
-
-		cur = cur->next;
-	}
-	return EXPAND_RULE_SUCCESS;
-}
-
-static int expand_rule_helper(sepol_handle_t * handle,
-			      policydb_t * p, uint32_t * typemap,
-			      avrule_t * source_rule, avtab_t * dest_avtab,
-			      cond_av_list_t ** cond, cond_av_list_t ** other,
-			      int enabled,
-			      ebitmap_t * stypes, ebitmap_t * ttypes)
-{
-	unsigned int i, j;
-	int retval;
-	ebitmap_node_t *snode, *tnode;
-
-	ebitmap_for_each_bit(stypes, snode, i) {
-		if (!ebitmap_node_get_bit(snode, i))
-			continue;
-		if (source_rule->flags & RULE_SELF) {
-			if (source_rule->specified & AVRULE_AV) {
-				if ((retval =
-				     expand_avrule_helper(handle,
-							  source_rule->
-							  specified, cond, i, i,
-							  source_rule->perms,
-							  dest_avtab,
-							  enabled)) !=
-				    EXPAND_RULE_SUCCESS) {
-					return retval;
-				}
-			} else {
-				if ((retval =
-				     expand_terule_helper(handle, p,
-							  typemap,
-							  source_rule->
-							  specified, cond,
-							  other, i, i,
-							  source_rule->perms,
-							  dest_avtab,
-							  enabled)) !=
-				    EXPAND_RULE_SUCCESS) {
-					return retval;
-				}
-			}
-		}
-		ebitmap_for_each_bit(ttypes, tnode, j) {
-			if (!ebitmap_node_get_bit(tnode, j))
-				continue;
-			if (source_rule->specified & AVRULE_AV) {
-				if ((retval =
-				     expand_avrule_helper(handle,
-							  source_rule->
-							  specified, cond, i, j,
-							  source_rule->perms,
-							  dest_avtab,
-							  enabled)) !=
-				    EXPAND_RULE_SUCCESS) {
-					return retval;
-				}
-			} else {
-				if ((retval =
-				     expand_terule_helper(handle, p,
-							  typemap,
-							  source_rule->
-							  specified, cond,
-							  other, i, j,
-							  source_rule->perms,
-							  dest_avtab,
-							  enabled)) !=
-				    EXPAND_RULE_SUCCESS) {
-					return retval;
-				}
-			}
-		}
-	}
-
-	return EXPAND_RULE_SUCCESS;
-}
-
-/*
- * Expand a rule into a given avtab - checking for conflicting type
- * rules in the destination policy.  Return EXPAND_RULE_SUCCESS on 
- * success, EXPAND_RULE_CONFLICT if the rule conflicts with something
- * (and hence was not added), or EXPAND_RULE_ERROR on error.
- */
-static int convert_and_expand_rule(sepol_handle_t * handle,
-				   policydb_t * dest_pol, uint32_t * typemap,
-				   avrule_t * source_rule, avtab_t * dest_avtab,
-				   cond_av_list_t ** cond,
-				   cond_av_list_t ** other, int enabled,
-				   int do_neverallow)
-{
-	int retval;
-	ebitmap_t stypes, ttypes;
-	unsigned char alwaysexpand;
-
-	if (!do_neverallow && source_rule->specified & AVRULE_NEVERALLOW)
-		return EXPAND_RULE_SUCCESS;
-
-	ebitmap_init(&stypes);
-	ebitmap_init(&ttypes);
-
-	/* Force expansion for type rules and for self rules. */
-	alwaysexpand = ((source_rule->specified & AVRULE_TYPE) ||
-			(source_rule->flags & RULE_SELF));
-
-	if (expand_convert_type_set
-	    (dest_pol, typemap, &source_rule->stypes, &stypes, alwaysexpand))
-		return EXPAND_RULE_ERROR;
-	if (expand_convert_type_set
-	    (dest_pol, typemap, &source_rule->ttypes, &ttypes, alwaysexpand))
-		return EXPAND_RULE_ERROR;
-
-	retval = expand_rule_helper(handle, dest_pol, typemap,
-				    source_rule, dest_avtab,
-				    cond, other, enabled, &stypes, &ttypes);
-	ebitmap_destroy(&stypes);
-	ebitmap_destroy(&ttypes);
-	return retval;
-}
-
-static int cond_avrule_list_copy(policydb_t * dest_pol, avrule_t * source_rules,
-				 avtab_t * dest_avtab, cond_av_list_t ** list,
-				 cond_av_list_t ** other, uint32_t * typemap,
-				 int enabled, expand_state_t * state)
-{
-	avrule_t *cur;
-
-	cur = source_rules;
-	while (cur) {
-		if (convert_and_expand_rule(state->handle, dest_pol,
-					    typemap, cur, dest_avtab,
-					    list, other, enabled,
-					    0) != EXPAND_RULE_SUCCESS) {
-			return -1;
-		}
-
-		cur = cur->next;
-	}
-
-	return 0;
-}
-
-static int cond_node_map_bools(expand_state_t * state, cond_node_t * cn)
-{
-	cond_expr_t *cur;
-	unsigned int i;
-
-	cur = cn->expr;
-	while (cur) {
-		if (cur->bool)
-			cur->bool = state->boolmap[cur->bool - 1];
-		cur = cur->next;
-	}
-
-	for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++)
-		cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1];
-
-	if (cond_normalize_expr(state->out, cn)) {
-		ERR(state->handle, "Error while normalizing conditional");
-		return -1;
-	}
-
-	return 0;
-}
-
-/* copy the nodes in *reverse* order -- the result is that the last
- * given conditional appears first in the policy, so as to match the
- * behavior of the upstream compiler */
-static int cond_node_copy(expand_state_t * state, cond_node_t * cn)
-{
-	cond_node_t *new_cond, *tmp;
-
-	if (cn == NULL) {
-		return 0;
-	}
-	if (cond_node_copy(state, cn->next)) {
-		return -1;
-	}
-	if (cond_normalize_expr(state->base, cn)) {
-		ERR(state->handle, "Error while normalizing conditional");
-		return -1;
-	}
-
-	/* create a new temporary conditional node with the booleans
-	 * mapped */
-	tmp = cond_node_create(state->base, cn);
-	if (!tmp) {
-		ERR(state->handle, "Out of memory");
-		return -1;
-	}
-
-	if (cond_node_map_bools(state, tmp)) {
-		ERR(state->handle, "Error mapping booleans");
-		return -1;
-	}
-
-	new_cond = cond_node_search(state->out, state->out->cond_list, tmp);
-	if (!new_cond) {
-		cond_node_destroy(tmp);
-		free(tmp);
-		ERR(state->handle, "Out of memory!");
-		return -1;
-	}
-	cond_node_destroy(tmp);
-	free(tmp);
-
-	if (cond_avrule_list_copy
-	    (state->out, cn->avtrue_list, &state->out->te_cond_avtab,
-	     &new_cond->true_list, &new_cond->false_list, state->typemap,
-	     new_cond->cur_state, state))
-		return -1;
-	if (cond_avrule_list_copy
-	    (state->out, cn->avfalse_list, &state->out->te_cond_avtab,
-	     &new_cond->false_list, &new_cond->true_list, state->typemap,
-	     !new_cond->cur_state, state))
-		return -1;
-
-	return 0;
-}
-
-static int context_copy(context_struct_t * dst, context_struct_t * src,
-			expand_state_t * state)
-{
-	dst->user = src->user;
-	dst->role = src->role;
-	dst->type = state->typemap[src->type - 1];
-	return mls_context_cpy(dst, src);
-}
-
-static int ocontext_copy(expand_state_t * state)
-{
-	unsigned int i, j;
-	ocontext_t *c, *n, *l;
-
-	for (i = 0; i < OCON_NUM; i++) {
-		l = NULL;
-		for (c = state->base->ocontexts[i]; c; c = c->next) {
-			n = malloc(sizeof(ocontext_t));
-			if (!n) {
-				ERR(state->handle, "Out of memory!");
-				return -1;
-			}
-			memset(n, 0, sizeof(ocontext_t));
-			if (l) {
-				l->next = n;
-			} else {
-				state->out->ocontexts[i] = n;
-			}
-			l = n;
-			if (context_copy(&n->context[0], &c->context[0], state)) {
-				ERR(state->handle, "Out of memory!");
-				return -1;
-			}
-			switch (i) {
-			case OCON_ISID:
-				n->sid[0] = c->sid[0];
-				break;
-			case OCON_FS:	/* FALLTHROUGH */
-			case OCON_NETIF:
-				n->u.name = strdup(c->u.name);
-				if (!n->u.name) {
-					ERR(state->handle, "Out of memory!");
-					return -1;
-				}
-				if (context_copy
-				    (&n->context[1], &c->context[1], state)) {
-					ERR(state->handle, "Out of memory!");
-					return -1;
-				}
-				break;
-			case OCON_PORT:
-				n->u.port.protocol = c->u.port.protocol;
-				n->u.port.low_port = c->u.port.low_port;
-				n->u.port.high_port = c->u.port.high_port;
-				break;
-			case OCON_NODE:
-				n->u.node.addr = c->u.node.addr;
-				n->u.node.mask = c->u.node.mask;
-				break;
-			case OCON_FSUSE:
-				n->v.behavior = c->v.behavior;
-				n->u.name = strdup(c->u.name);
-				if (!n->u.name) {
-					ERR(state->handle, "Out of memory!");
-					return -1;
-				}
-				break;
-			case OCON_NODE6:
-				for (j = 0; j < 4; j++)
-					n->u.node6.addr[j] = c->u.node6.addr[j];
-				for (j = 0; j < 4; j++)
-					n->u.node6.mask[j] = c->u.node6.mask[j];
-				break;
-			default:
-				/* shouldn't get here */
-				assert(0);
-			}
-		}
-	}
-	return 0;
-}
-
-static int genfs_copy(expand_state_t * state)
-{
-	ocontext_t *c, *newc, *l;
-	genfs_t *genfs, *newgenfs, *end;
-
-	end = NULL;
-	for (genfs = state->base->genfs; genfs; genfs = genfs->next) {
-		newgenfs = malloc(sizeof(genfs_t));
-		if (!newgenfs) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		memset(newgenfs, 0, sizeof(genfs_t));
-		newgenfs->fstype = strdup(genfs->fstype);
-		if (!newgenfs->fstype) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-
-		l = NULL;
-		for (c = genfs->head; c; c = c->next) {
-			newc = malloc(sizeof(ocontext_t));
-			if (!newc) {
-				ERR(state->handle, "Out of memory!");
-				return -1;
-			}
-			memset(newc, 0, sizeof(ocontext_t));
-			newc->u.name = strdup(c->u.name);
-			if (!newc->u.name) {
-				ERR(state->handle, "Out of memory!");
-				return -1;
-			}
-			newc->v.sclass = c->v.sclass;
-			context_copy(&newc->context[0], &c->context[0], state);
-			if (l)
-				l->next = newc;
-			else
-				newgenfs->head = newc;
-			l = newc;
-		}
-		if (!end) {
-			state->out->genfs = newgenfs;
-		} else {
-			end->next = newgenfs;
-		}
-		end = newgenfs;
-	}
-	return 0;
-}
-
-static int type_attr_map(hashtab_key_t key
-			 __attribute__ ((unused)), hashtab_datum_t datum,
-			 void *ptr)
-{
-	type_datum_t *type;
-	expand_state_t *state = ptr;
-	policydb_t *p = state->out;
-	unsigned int i;
-	ebitmap_node_t *tnode;
-
-	type = (type_datum_t *) datum;
-	if (type->flavor == TYPE_ATTRIB) {
-		if (ebitmap_cpy(&p->attr_type_map[type->s.value - 1],
-				&type->types)) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
-		}
-		ebitmap_for_each_bit(&type->types, tnode, i) {
-			if (!ebitmap_node_get_bit(tnode, i))
-				continue;
-			if (ebitmap_set_bit(&p->type_attr_map[i],
-					    type->s.value - 1, 1)) {
-				ERR(state->handle, "Out of memory!");
-				return -1;
-			}
-		}
-	}
-	return 0;
-}
-
-static void type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
-			 __attribute__ ((unused)))
-{
-	free(key);
-	type_datum_destroy((type_datum_t *) datum);
-	free(datum);
-}
-
-static int type_attr_remove(hashtab_key_t key
-			    __attribute__ ((unused)), hashtab_datum_t datum,
-			    void *args)
-{
-	type_datum_t *typdatum;
-	policydb_t *p;
-
-	typdatum = (type_datum_t *) datum;
-	p = (policydb_t *) args;
-	if (typdatum->flavor == TYPE_ATTRIB) {
-		p->type_val_to_struct[typdatum->s.value - 1] = NULL;
-		p->p_type_val_to_name[typdatum->s.value - 1] = NULL;
-		return 1;
-	}
-	return 0;
-}
-
-int convert_type_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * typemap)
-{
-	unsigned int i;
-	ebitmap_node_t *tnode;
-	ebitmap_init(dst);
-
-	ebitmap_for_each_bit(src, tnode, i) {
-		if (!ebitmap_node_get_bit(tnode, i))
-			continue;
-		if (!typemap[i])
-			continue;
-		if (ebitmap_set_bit(dst, typemap[i] - 1, 1))
-			return -1;
-	}
-	return 0;
-}
-
-/* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy.
- * this should not be called until after all the blocks have been processed and the attributes in target policy
- * are complete. */
-int expand_convert_type_set(policydb_t * p, uint32_t * typemap,
-			    type_set_t * set, ebitmap_t * types,
-			    unsigned char alwaysexpand)
-{
-	type_set_t tmpset;
-
-	type_set_init(&tmpset);
-
-	if (convert_type_ebitmap(&set->types, &tmpset.types, typemap))
-		return -1;
-
-	if (convert_type_ebitmap(&set->negset, &tmpset.negset, typemap))
-		return -1;
-
-	tmpset.flags = set->flags;
-
-	if (type_set_expand(&tmpset, types, p, alwaysexpand))
-		return -1;
-
-	type_set_destroy(&tmpset);
-
-	return 0;
-}
-
-/* Expand a rule into a given avtab - checking for conflicting type
- * rules.  Return 1 on success, 0 if the rule conflicts with something
- * (and hence was not added), or -1 on error. */
-int expand_rule(sepol_handle_t * handle,
-		policydb_t * source_pol,
-		avrule_t * source_rule, avtab_t * dest_avtab,
-		cond_av_list_t ** cond, cond_av_list_t ** other, int enabled)
-{
-	int retval;
-	ebitmap_t stypes, ttypes;
-
-	if (source_rule->specified & AVRULE_NEVERALLOW)
-		return 1;
-
-	ebitmap_init(&stypes);
-	ebitmap_init(&ttypes);
-
-	if (type_set_expand(&source_rule->stypes, &stypes, source_pol, 1))
-		return -1;
-	if (type_set_expand(&source_rule->ttypes, &ttypes, source_pol, 1))
-		return -1;
-	retval = expand_rule_helper(handle, source_pol, NULL,
-				    source_rule, dest_avtab,
-				    cond, other, enabled, &stypes, &ttypes);
-	ebitmap_destroy(&stypes);
-	ebitmap_destroy(&ttypes);
-	return retval;
-}
-
-int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * p)
-{
-	unsigned int i;
-	ebitmap_node_t *rnode;
-
-	ebitmap_init(r);
-
-	if (x->flags & ROLE_STAR) {
-		for (i = 0; i < p->p_roles.nprim++; i++)
-			if (ebitmap_set_bit(r, i, 1))
-				return -1;
-		return 0;
-	}
-
-	ebitmap_for_each_bit(&x->roles, rnode, i) {
-		if (ebitmap_node_get_bit(rnode, i)) {
-			if (ebitmap_set_bit(r, i, 1))
-				return -1;
-		}
-	}
-
-	/* if role is to be complimented, invert the entire bitmap here */
-	if (x->flags & ROLE_COMP) {
-		for (i = 0; i < ebitmap_length(r); i++) {
-			if (ebitmap_get_bit(r, i)) {
-				if (ebitmap_set_bit(r, i, 0))
-					return -1;
-			} else {
-				if (ebitmap_set_bit(r, i, 1))
-					return -1;
-			}
-		}
-	}
-	return 0;
-}
-
-/* Expand a type set into an ebitmap containing the types. This
- * handles the negset, attributes, and flags.
- * Attribute expansion depends on several factors:
- * - if alwaysexpand is 1, then they will be expanded,
- * - if the type set has a negset or flags, then they will be expanded,
- * - otherwise, they will not be expanded.
- */
-int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p,
-		    unsigned char alwaysexpand)
-{
-	unsigned int i;
-	ebitmap_t types, neg_types;
-	ebitmap_node_t *tnode;
-
-	ebitmap_init(&types);
-	ebitmap_init(t);
-
-	if (alwaysexpand || ebitmap_length(&set->negset) || set->flags) {
-		/* First go through the types and OR all the attributes to types */
-		ebitmap_for_each_bit(&set->types, tnode, i) {
-			if (ebitmap_node_get_bit(tnode, i)) {
-				if (p->type_val_to_struct[i]->flavor ==
-				    TYPE_ATTRIB) {
-					if (ebitmap_union
-					    (&types,
-					     &p->type_val_to_struct[i]->
-					     types)) {
-						return -1;
-					}
-				} else {
-					if (ebitmap_set_bit(&types, i, 1)) {
-						return -1;
-					}
-				}
-			}
-		}
-	} else {
-		/* No expansion of attributes, just copy the set as is. */
-		if (ebitmap_cpy(&types, &set->types))
-			return -1;
-	}
-
-	/* Now do the same thing for negset */
-	ebitmap_init(&neg_types);
-	ebitmap_for_each_bit(&set->negset, tnode, i) {
-		if (ebitmap_node_get_bit(tnode, i)) {
-			if (p->type_val_to_struct[i] &&
-			    p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) {
-				if (ebitmap_union
-				    (&neg_types,
-				     &p->type_val_to_struct[i]->types)) {
-					return -1;
-				}
-			} else {
-				if (ebitmap_set_bit(&neg_types, i, 1)) {
-					return -1;
-				}
-			}
-		}
-	}
-
-	if (set->flags & TYPE_STAR) {
-		/* set all types not in neg_types */
-		for (i = 0; i < p->p_types.nprim; i++) {
-			if (ebitmap_get_bit(&neg_types, i))
-				continue;
-			if (p->type_val_to_struct[i] &&
-			    p->type_val_to_struct[i]->flavor == TYPE_ATTRIB)
-				continue;
-			if (ebitmap_set_bit(t, i, 1))
-				return -1;
-		}
-		goto out;
-	}
-
-	ebitmap_for_each_bit(&types, tnode, i) {
-		if (ebitmap_node_get_bit(tnode, i)
-		    && (!ebitmap_get_bit(&neg_types, i)))
-			if (ebitmap_set_bit(t, i, 1))
-				return -1;
-	}
-
-	if (set->flags & TYPE_COMP) {
-		for (i = 0; i < p->p_types.nprim; i++) {
-			if (p->type_val_to_struct[i] &&
-			    p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) {
-				assert(!ebitmap_get_bit(t, i));
-				continue;
-			}
-			if (ebitmap_get_bit(t, i)) {
-				if (ebitmap_set_bit(t, i, 0))
-					return -1;
-			} else {
-				if (ebitmap_set_bit(t, i, 1))
-					return -1;
-			}
-		}
-	}
-
-      out:
-
-	ebitmap_destroy(&types);
-	ebitmap_destroy(&neg_types);
-
-	return 0;
-}
-
-static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap,
-			   avrule_t * source_rule)
-{
-	ebitmap_t stypes, ttypes;
-	avrule_t *avrule;
-	class_perm_node_t *cur_perm, *new_perm, *tail_perm;
-
-	ebitmap_init(&stypes);
-	ebitmap_init(&ttypes);
-
-	if (expand_convert_type_set
-	    (dest_pol, typemap, &source_rule->stypes, &stypes, 1))
-		return -1;
-	if (expand_convert_type_set
-	    (dest_pol, typemap, &source_rule->ttypes, &ttypes, 1))
-		return -1;
-
-	avrule = (avrule_t *) malloc(sizeof(avrule_t));
-	if (!avrule)
-		return -1;
-
-	avrule_init(avrule);
-	avrule->specified = AVRULE_NEVERALLOW;
-	avrule->line = source_rule->line;
-	avrule->flags = source_rule->flags;
-
-	if (ebitmap_cpy(&avrule->stypes.types, &stypes))
-		goto err;
-
-	if (ebitmap_cpy(&avrule->ttypes.types, &ttypes))
-		goto err;
-
-	cur_perm = source_rule->perms;
-	tail_perm = NULL;
-	while (cur_perm) {
-		new_perm =
-		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
-		if (!new_perm)
-			goto err;
-		class_perm_node_init(new_perm);
-		new_perm->class = cur_perm->class;
-		assert(new_perm->class);
-
-		/* once we have modules with permissions we'll need to map the permissions (and classes) */
-		new_perm->data = cur_perm->data;
-
-		if (!avrule->perms)
-			avrule->perms = new_perm;
-
-		if (tail_perm)
-			tail_perm->next = new_perm;
-		tail_perm = new_perm;
-		cur_perm = cur_perm->next;
-	}
-
-	/* just prepend the avrule to the first branch; it'll never be
-	   written to disk */
-	if (!dest_pol->global->branch_list->avrules)
-		dest_pol->global->branch_list->avrules = avrule;
-	else {
-		avrule->next = dest_pol->global->branch_list->avrules;
-		dest_pol->global->branch_list->avrules = avrule;
-	}
-
-	ebitmap_destroy(&stypes);
-	ebitmap_destroy(&ttypes);
-
-	return 0;
-
-      err:
-	ebitmap_destroy(&stypes);
-	ebitmap_destroy(&ttypes);
-	ebitmap_destroy(&avrule->stypes.types);
-	ebitmap_destroy(&avrule->ttypes.types);
-	cur_perm = avrule->perms;
-	while (cur_perm) {
-		tail_perm = cur_perm->next;
-		free(cur_perm);
-		cur_perm = tail_perm;
-	}
-	free(avrule);
-	return -1;
-}
-
-/* 
- * Expands the avrule blocks for a policy. RBAC rules are copied. Neverallow
- * rules are copied or expanded as per the settings in the state object; all
- * other AV rules are expanded.  If neverallow rules are expanded, they are not
- * copied, otherwise they are copied for later use by the assertion checker.
- */
-static int copy_and_expand_avrule_block(expand_state_t * state)
-{
-	avrule_block_t *curblock;
-	int retval = -1;
-
-	for (curblock = state->base->global; curblock != NULL;
-	     curblock = curblock->next) {
-		avrule_decl_t *decl = curblock->enabled;
-		avrule_t *cur_avrule;
-
-		if (decl == NULL) {
-			/* nothing was enabled within this block */
-			continue;
-		}
-
-		/* copy role allows and role trans */
-		if (copy_role_allows(state, decl->role_allow_rules) != 0 ||
-		    copy_role_trans(state, decl->role_tr_rules) != 0) {
-			goto cleanup;
-		}
-
-		/* expand the range transition rules */
-		if (expand_range_trans(state, decl->range_tr_rules))
-			goto cleanup;
-
-		/* copy rules */
-		cur_avrule = decl->avrules;
-		while (cur_avrule != NULL) {
-			if (!(state->expand_neverallow)
-			    && cur_avrule->specified & AVRULE_NEVERALLOW) {
-				/* copy this over directly so that assertions are checked later */
-				if (copy_neverallow
-				    (state->out, state->typemap, cur_avrule))
-					ERR(state->handle,
-					    "Error while copying neverallow.");
-			} else {
-				if (cur_avrule->specified & AVRULE_NEVERALLOW) {
-					state->out->unsupported_format = 1;
-				}
-				if (convert_and_expand_rule
-				    (state->handle, state->out, state->typemap,
-				     cur_avrule, &state->out->te_avtab, NULL,
-				     NULL, 0,
-				     state->expand_neverallow) !=
-				    EXPAND_RULE_SUCCESS) {
-					goto cleanup;
-				}
-			}
-			cur_avrule = cur_avrule->next;
-		}
-
-		/* copy conditional rules */
-		if (cond_node_copy(state, decl->cond_list))
-			goto cleanup;
-	}
-
-	retval = 0;
-
-      cleanup:
-	return retval;
-}
-
-/* 
- * This function allows external users of the library (such as setools) to
- * expand only the avrules and optionally perform expansion of neverallow rules
- * or expand into the same policy for analysis purposes.
- */
-int expand_module_avrules(sepol_handle_t * handle, policydb_t * base,
-			  policydb_t * out, uint32_t * typemap,
-			  uint32_t * boolmap, int verbose,
-			  int expand_neverallow)
-{
-	expand_state_t state;
-
-	expand_state_init(&state);
-
-	state.base = base;
-	state.out = out;
-	state.typemap = typemap;
-	state.boolmap = boolmap;
-	state.handle = handle;
-	state.verbose = verbose;
-	state.expand_neverallow = expand_neverallow;
-
-	return copy_and_expand_avrule_block(&state);
-}
-
-/* Linking should always be done before calling expand, even if
- * there is only a base since all optionals are dealt with at link time
- * the base passed in should be indexed and avrule blocks should be 
- * enabled.
- */
-int expand_module(sepol_handle_t * handle,
-		  policydb_t * base, policydb_t * out, int verbose, int check)
-{
-	int retval = -1;
-	unsigned int i;
-	expand_state_t state;
-	avrule_block_t *curblock;
-
-	expand_state_init(&state);
-
-	state.verbose = verbose;
-	state.typemap = NULL;
-	state.base = base;
-	state.out = out;
-	state.handle = handle;
-
-	if (base->policy_type != POLICY_BASE) {
-		ERR(handle, "Target of expand was not a base policy.");
-		return -1;
-	}
-
-	state.out->policy_type = POLICY_KERN;
-	state.out->policyvers = POLICYDB_VERSION_MAX;
-
-	/* Copy mls state from base to out */
-	out->mls = base->mls;
-
-	if ((state.typemap =
-	     (uint32_t *) calloc(state.base->p_types.nprim,
-				 sizeof(uint32_t))) == NULL) {
-		ERR(handle, "Out of memory!");
-		goto cleanup;
-	}
-
-	state.boolmap = (uint32_t *)calloc(state.base->p_bools.nprim, sizeof(uint32_t));
-	if (!state.boolmap) {
-		ERR(handle, "Out of memory!");
-		goto cleanup;
-	}
-
-	/* order is important - types must be first */
-
-	/* copy types */
-	if (hashtab_map(state.base->p_types.table, type_copy_callback, &state)) {
-		goto cleanup;
-	}
-
-	/* convert attribute type sets */
-	if (hashtab_map
-	    (state.base->p_types.table, attr_convert_callback, &state)) {
-		goto cleanup;
-	}
-
-	/* copy commons */
-	if (hashtab_map
-	    (state.base->p_commons.table, common_copy_callback, &state)) {
-		goto cleanup;
-	}
-
-	/* copy classes, note, this does not copy constraints, constraints can't be
-	 * copied until after all the blocks have been processed and attributes are complete */
-	if (hashtab_map
-	    (state.base->p_classes.table, class_copy_callback, &state)) {
-		goto cleanup;
-	}
-
-	/* copy aliases */
-	if (hashtab_map(state.base->p_types.table, alias_copy_callback, &state))
-		goto cleanup;
-
-	/* index here so that type indexes are available for role_copy_callback */
-	if (policydb_index_others(handle, out, verbose)) {
-		ERR(handle, "Error while indexing out symbols");
-		goto cleanup;
-	}
-
-	/* copy roles */
-	if (hashtab_map(state.base->p_roles.table, role_copy_callback, &state))
-		goto cleanup;
-
-	/* copy MLS's sensitivity level and categories - this needs to be done
-	 * before expanding users (they need to be indexed too) */
-	if (hashtab_map(state.base->p_levels.table, sens_copy_callback, &state))
-		goto cleanup;
-	if (hashtab_map(state.base->p_cats.table, cats_copy_callback, &state))
-		goto cleanup;
-	if (policydb_index_others(handle, out, verbose)) {
-		ERR(handle, "Error while indexing out symbols");
-		goto cleanup;
-	}
-
-	/* copy users */
-	if (hashtab_map(state.base->p_users.table, user_copy_callback, &state))
-		goto cleanup;
-
-	/* copy bools */
-	if (hashtab_map(state.base->p_bools.table, bool_copy_callback, &state))
-		goto cleanup;
-
-	if (policydb_index_classes(out)) {
-		ERR(handle, "Error while indexing out classes");
-		goto cleanup;
-	}
-	if (policydb_index_others(handle, out, verbose)) {
-		ERR(handle, "Error while indexing out symbols");
-		goto cleanup;
-	}
-
-	/* loop through all decls and union attributes, roles, users */
-	for (curblock = state.base->global; curblock != NULL;
-	     curblock = curblock->next) {
-		avrule_decl_t *decl = curblock->enabled;
-
-		if (decl == NULL) {
-			/* nothing was enabled within this block */
-			continue;
-		}
-
-		/* convert attribute type sets */
-		if (hashtab_map
-		    (decl->p_types.table, attr_convert_callback, &state)) {
-			goto cleanup;
-		}
-
-		/* copy roles */
-		if (hashtab_map
-		    (decl->p_roles.table, role_copy_callback, &state))
-			goto cleanup;
-
-		/* copy users */
-		if (hashtab_map
-		    (decl->p_users.table, user_copy_callback, &state))
-			goto cleanup;
-
-	}
-
-	if (copy_and_expand_avrule_block(&state) < 0) {
-		ERR(handle, "Error during expand");
-		goto cleanup;
-	}
-
-	/* copy constraints */
-	if (hashtab_map
-	    (state.base->p_classes.table, constraint_copy_callback, &state)) {
-		goto cleanup;
-	}
-
-	cond_optimize_lists(state.out->cond_list);
-	evaluate_conds(state.out);
-
-	/* copy ocontexts */
-	if (ocontext_copy(&state))
-		goto cleanup;
-
-	/* copy genfs */
-	if (genfs_copy(&state))
-		goto cleanup;
-
-	/* Build the type<->attribute maps and remove attributes. */
-	state.out->attr_type_map = malloc(state.out->p_types.nprim *
-					  sizeof(ebitmap_t));
-	state.out->type_attr_map = malloc(state.out->p_types.nprim *
-					  sizeof(ebitmap_t));
-	if (!state.out->attr_type_map || !state.out->type_attr_map) {
-		ERR(handle, "Out of memory!");
-		goto cleanup;
-	}
-	for (i = 0; i < state.out->p_types.nprim; i++) {
-		ebitmap_init(&state.out->type_attr_map[i]);
-		ebitmap_init(&state.out->attr_type_map[i]);
-		/* add the type itself as the degenerate case */
-		if (ebitmap_set_bit(&state.out->type_attr_map[i], i, 1)) {
-			ERR(handle, "Out of memory!");
-			goto cleanup;
-		}
-	}
-	if (hashtab_map(state.out->p_types.table, type_attr_map, &state))
-		goto cleanup;
-	hashtab_map_remove_on_error(state.out->p_types.table,
-				    type_attr_remove, type_destroy, state.out);
-	if (check) {
-		if (hierarchy_check_constraints(handle, state.out))
-			goto cleanup;
-
-		if (check_assertions
-		    (handle, state.out,
-		     state.out->global->branch_list->avrules))
-			 goto cleanup;
-	}
-
-	retval = 0;
-
-      cleanup:
-	free(state.typemap);
-	free(state.boolmap);
-	return retval;
-}
-
-static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d)
-{
-	avtab_ptr_t node;
-	avtab_datum_t *avd;
-	int rc;
-
-	node = avtab_search_node(a, k);
-	if (!node) {
-		rc = avtab_insert(a, k, d);
-		if (rc)
-			ERR(NULL, "Out of memory!");
-		return rc;
-	}
-
-	if ((k->specified & AVTAB_ENABLED) !=
-	    (node->key.specified & AVTAB_ENABLED)) {
-		node = avtab_insert_nonunique(a, k, d);
-		if (!node) {
-			ERR(NULL, "Out of memory!");
-			return -1;
-		}
-		return 0;
-	}
-
-	avd = &node->datum;
-	switch (k->specified & ~AVTAB_ENABLED) {
-	case AVTAB_ALLOWED:
-	case AVTAB_AUDITALLOW:
-		avd->data |= d->data;
-		break;
-	case AVTAB_AUDITDENY:
-		avd->data &= d->data;
-		break;
-	default:
-		ERR(NULL, "Type conflict!");
-		return -1;
-	}
-
-	return 0;
-}
-
-struct expand_avtab_data {
-	avtab_t *expa;
-	policydb_t *p;
-
-};
-
-static int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args)
-{
-	struct expand_avtab_data *ptr = args;
-	avtab_t *expa = ptr->expa;
-	policydb_t *p = ptr->p;
-	type_datum_t *stype = p->type_val_to_struct[k->source_type - 1];
-	type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1];
-	ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1];
-	ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1];
-	ebitmap_node_t *snode, *tnode;
-	unsigned int i, j;
-	avtab_key_t newkey;
-	int rc;
-
-	newkey.target_class = k->target_class;
-	newkey.specified = k->specified;
-
-	if (stype && ttype) {
-		/* Both are individual types, no expansion required. */
-		return expand_avtab_insert(expa, k, d);
-	}
-
-	if (stype) {
-		/* Source is an individual type, target is an attribute. */
-		newkey.source_type = k->source_type;
-		ebitmap_for_each_bit(tattr, tnode, j) {
-			if (!ebitmap_node_get_bit(tnode, j))
-				continue;
-			newkey.target_type = j + 1;
-			rc = expand_avtab_insert(expa, &newkey, d);
-			if (rc)
-				return -1;
-		}
-		return 0;
-	}
-
-	if (ttype) {
-		/* Target is an individual type, source is an attribute. */
-		newkey.target_type = k->target_type;
-		ebitmap_for_each_bit(sattr, snode, i) {
-			if (!ebitmap_node_get_bit(snode, i))
-				continue;
-			newkey.source_type = i + 1;
-			rc = expand_avtab_insert(expa, &newkey, d);
-			if (rc)
-				return -1;
-		}
-		return 0;
-	}
-
-	/* Both source and target type are attributes. */
-	ebitmap_for_each_bit(sattr, snode, i) {
-		if (!ebitmap_node_get_bit(snode, i))
-			continue;
-		ebitmap_for_each_bit(tattr, tnode, j) {
-			if (!ebitmap_node_get_bit(tnode, j))
-				continue;
-			newkey.source_type = i + 1;
-			newkey.target_type = j + 1;
-			rc = expand_avtab_insert(expa, &newkey, d);
-			if (rc)
-				return -1;
-		}
-	}
-
-	return 0;
-}
-
-int expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa)
-{
-	struct expand_avtab_data data;
-
-	data.expa = expa;
-	data.p = p;
-	return avtab_map(a, expand_avtab_node, &data);
-}
-
-static int expand_cond_insert(cond_av_list_t ** l,
-			      avtab_t * expa,
-			      avtab_key_t * k, avtab_datum_t * d)
-{
-	avtab_ptr_t node;
-	avtab_datum_t *avd;
-	cond_av_list_t *nl;
-
-	node = avtab_search_node(expa, k);
-	if (!node ||
-	    (k->specified & AVTAB_ENABLED) !=
-	    (node->key.specified & AVTAB_ENABLED)) {
-		node = avtab_insert_nonunique(expa, k, d);
-		if (!node) {
-			ERR(NULL, "Out of memory!");
-			return -1;
-		}
-		node->parse_context = (void *)1;
-		nl = (cond_av_list_t *) malloc(sizeof(*nl));
-		if (!nl) {
-			ERR(NULL, "Out of memory!");
-			return -1;
-		}
-		memset(nl, 0, sizeof(*nl));
-		nl->node = node;
-		nl->next = *l;
-		*l = nl;
-		return 0;
-	}
-
-	avd = &node->datum;
-	switch (k->specified & ~AVTAB_ENABLED) {
-	case AVTAB_ALLOWED:
-	case AVTAB_AUDITALLOW:
-		avd->data |= d->data;
-		break;
-	case AVTAB_AUDITDENY:
-		avd->data &= d->data;
-		break;
-	default:
-		ERR(NULL, "Type conflict!");
-		return -1;
-	}
-
-	return 0;
-}
-
-int expand_cond_av_node(policydb_t * p,
-			avtab_ptr_t node,
-			cond_av_list_t ** newl, avtab_t * expa)
-{
-	avtab_key_t *k = &node->key;
-	avtab_datum_t *d = &node->datum;
-	type_datum_t *stype = p->type_val_to_struct[k->source_type - 1];
-	type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1];
-	ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1];
-	ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1];
-	ebitmap_node_t *snode, *tnode;
-	unsigned int i, j;
-	avtab_key_t newkey;
-	int rc;
-
-	newkey.target_class = k->target_class;
-	newkey.specified = k->specified;
-
-	if (stype && ttype) {
-		/* Both are individual types, no expansion required. */
-		return expand_cond_insert(newl, expa, k, d);
-	}
-
-	if (stype) {
-		/* Source is an individual type, target is an attribute. */
-		newkey.source_type = k->source_type;
-		ebitmap_for_each_bit(tattr, tnode, j) {
-			if (!ebitmap_node_get_bit(tnode, j))
-				continue;
-			newkey.target_type = j + 1;
-			rc = expand_cond_insert(newl, expa, &newkey, d);
-			if (rc)
-				return -1;
-		}
-		return 0;
-	}
-
-	if (ttype) {
-		/* Target is an individual type, source is an attribute. */
-		newkey.target_type = k->target_type;
-		ebitmap_for_each_bit(sattr, snode, i) {
-			if (!ebitmap_node_get_bit(snode, i))
-				continue;
-			newkey.source_type = i + 1;
-			rc = expand_cond_insert(newl, expa, &newkey, d);
-			if (rc)
-				return -1;
-		}
-		return 0;
-	}
-
-	/* Both source and target type are attributes. */
-	ebitmap_for_each_bit(sattr, snode, i) {
-		if (!ebitmap_node_get_bit(snode, i))
-			continue;
-		ebitmap_for_each_bit(tattr, tnode, j) {
-			if (!ebitmap_node_get_bit(tnode, j))
-				continue;
-			newkey.source_type = i + 1;
-			newkey.target_type = j + 1;
-			rc = expand_cond_insert(newl, expa, &newkey, d);
-			if (rc)
-				return -1;
-		}
-	}
-
-	return 0;
-}
-
-int expand_cond_av_list(policydb_t * p, cond_av_list_t * l,
-			cond_av_list_t ** newl, avtab_t * expa)
-{
-	cond_av_list_t *cur;
-	avtab_ptr_t node;
-	int rc;
-
-	*newl = NULL;
-	for (cur = l; cur; cur = cur->next) {
-		node = cur->node;
-		rc = expand_cond_av_node(p, node, newl, expa);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}

-- 

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [POLICYREP] [Patch 2/5] This patch removes files that existed solely to support modular policies.
  2007-08-16 15:53 [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Mark Goldman
  2007-08-16 15:53 ` [POLICYREP] [Patch 1/5] << Part 1 >> This patch removes files that existed solely to support modular policies Mark Goldman
@ 2007-08-16 15:53 ` Mark Goldman
  2007-08-16 15:53 ` [POLICYREP] [Patch 3/5] << part 1 >> This patch does all the functional work of removing the module support code Mark Goldman
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Goldman @ 2007-08-16 15:53 UTC (permalink / raw)
  To: selinux

<< part 2 >>
---
 libsepol/include/sepol/policydb/expand.h |   78 	0 +	78 -	0 !
 libsepol/include/sepol/policydb/link.h   |   20 	0 +	20 -	0 !
 libsepol/include/sepol/policydb/module.h |   48 	0 +	48 -	0 !
 libsepol/src/link.c                      | 2239 	0 +	2239 -	0 !
 libsepol/src/module.c                    |  952 	0 +	952 -	0 !
 5 files changed, 3337 deletions(-)

--- foo.orig/libsepol/src/link.c
+++ /dev/null
@@ -1,2239 +0,0 @@
-/* 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_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");
-				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");
-				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;
-
-	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) {
-		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 and types field will be copied
-		 * during role_fix_callback() */
-		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->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;
-		}
-	} 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->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->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;
-
-	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->state = booldatum->state;
-		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;
-
-	}
-
-	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;
-		}
-		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;
-		}
-	}
-
-	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;
-		}
-		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;
-		}
-	}
-
-	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 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;
-	}
-
-	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->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;
-
-	}
-	/* 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;
-
-	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);
-	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->class =
-			    module->map[SYM_CLASSES][cur_perm->class - 1];
-			assert(new_perm->class);
-
-			if (new_rule->specified & AVRULE_AV) {
-				for (i = 0;
-				     i <
-				     module->perm_map_len[cur_perm->class - 1];
-				     i++) {
-					if (!(cur_perm->data & (1U << i)))
-						continue;
-					new_perm->data |=
-					    (1U <<
-					     (module->
-					      perm_map[cur_perm->class - 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 {
-				tail_perm->next = new_perm;
-			}
-			tail_perm = new_perm;
-			cur_perm = cur_perm->next;
-		}
-		new_rule->line = cur->line;
-
-		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;
-
-	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;
-		}
-
-		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_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, alias_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_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");
-				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) {
-			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;
-			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;
-			}
-			if (scope->scope == SCOPE_REQ)
-				return 0;
-
-			fparg.valuep = perm_value;
-			fparg.key = NULL;
-
-			hashtab_map(cladatum->permissions.table, find_perm,
-				    &fparg);
-			if (fparg.key == NULL && cladatum->comdatum != NULL)
-				hashtab_map(cladatum->comdatum->permissions.
-					    table, find_perm, &fparg);
-			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;
-
-	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) {
-			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;
-				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;
-	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;
-		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) {
-				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;
-}
-
-/* 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;
-	}
-
-	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;
-}
--- foo.orig/libsepol/src/module.c
+++ /dev/null
@@ -1,952 +0,0 @@
-/* Author: Karl MacMillan <kmacmillan@tresys.com>
- *         Jason Tang     <jtang@tresys.com>
- *         Chris PeBenito <cpebenito@tresys.com>
- *
- * Copyright (C) 2004-2005 Tresys Technology, LLC
- *
- *  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 "policydb_internal.h"
-#include "module_internal.h"
-#include <sepol/policydb/link.h>
-#include <sepol/policydb/expand.h>
-#include <sepol/policydb/module.h>
-#include "debug.h"
-#include "private.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-
-#define SEPOL_PACKAGE_SECTION_FC 0xf97cff90
-#define SEPOL_PACKAGE_SECTION_SEUSER 0x97cff91
-#define SEPOL_PACKAGE_SECTION_USER_EXTRA 0x97cff92
-#define SEPOL_PACKAGE_SECTION_NETFILTER 0x97cff93
-
-static int policy_file_seek(struct policy_file *fp, size_t offset)
-{
-	switch (fp->type) {
-	case PF_USE_STDIO:
-		if (offset > LONG_MAX) {
-			errno = EFAULT;
-			return -1;
-		}
-		return fseek(fp->fp, (long)offset, SEEK_SET);
-	case PF_USE_MEMORY:
-		if (offset > fp->size) {
-			errno = EFAULT;
-			return -1;
-		}
-		fp->data -= fp->size - fp->len;
-		fp->data += offset;
-		fp->len = fp->size - offset;
-		return 0;
-	default:
-		return 0;
-	}
-}
-
-static size_t policy_file_length(struct policy_file *fp)
-{
-	long prev_offset, end_offset;
-	switch (fp->type) {
-	case PF_USE_STDIO:
-		prev_offset = ftell(fp->fp);
-		fseek(fp->fp, 0L, SEEK_END);
-		end_offset = ftell(fp->fp);
-		fseek(fp->fp, prev_offset, SEEK_SET);
-		return end_offset;
-	case PF_USE_MEMORY:
-		return fp->size;
-	default:
-		return 0;
-	}
-}
-
-static int module_package_init(sepol_module_package_t * p)
-{
-	memset(p, 0, sizeof(sepol_module_package_t));
-	if (sepol_policydb_create(&p->policy))
-		return -1;
-
-	p->version = 1;
-	return 0;
-}
-
-static int set_char(char **field, char *data, size_t len)
-{
-	if (*field) {
-		free(*field);
-		*field = NULL;
-	}
-	if (len) {
-		*field = malloc(len);
-		if (!*field)
-			return -1;
-		memcpy(*field, data, len);
-	}
-	return 0;
-}
-
-int sepol_module_package_create(sepol_module_package_t ** p)
-{
-	*p = calloc(1, sizeof(sepol_module_package_t));
-	if (!(*p))
-		return -1;
-	return module_package_init(*p);
-}
-
-hidden_def(sepol_module_package_create)
-
-/* Deallocates all memory associated with a module package, including
- * the pointer itself.  Does nothing if p is NULL.
- */
-void sepol_module_package_free(sepol_module_package_t * p)
-{
-	if (p == NULL)
-		return;
-
-	sepol_policydb_free(p->policy);
-	free(p->file_contexts);
-	free(p->seusers);
-	free(p->user_extra);
-	free(p->netfilter_contexts);
-	free(p);
-}
-
-hidden_def(sepol_module_package_free)
-
-char *sepol_module_package_get_file_contexts(sepol_module_package_t * p)
-{
-	return p->file_contexts;
-}
-
-size_t sepol_module_package_get_file_contexts_len(sepol_module_package_t * p)
-{
-	return p->file_contexts_len;
-}
-
-char *sepol_module_package_get_seusers(sepol_module_package_t * p)
-{
-	return p->seusers;
-}
-
-size_t sepol_module_package_get_seusers_len(sepol_module_package_t * p)
-{
-	return p->seusers_len;
-}
-
-char *sepol_module_package_get_user_extra(sepol_module_package_t * p)
-{
-	return p->user_extra;
-}
-
-size_t sepol_module_package_get_user_extra_len(sepol_module_package_t * p)
-{
-	return p->user_extra_len;
-}
-
-char *sepol_module_package_get_netfilter_contexts(sepol_module_package_t * p)
-{
-	return p->netfilter_contexts;
-}
-
-size_t sepol_module_package_get_netfilter_contexts_len(sepol_module_package_t *
-						       p)
-{
-	return p->netfilter_contexts_len;
-}
-
-int sepol_module_package_set_file_contexts(sepol_module_package_t * p,
-					   char *data, size_t len)
-{
-	if (set_char(&p->file_contexts, data, len))
-		return -1;
-
-	p->file_contexts_len = len;
-	return 0;
-}
-
-int sepol_module_package_set_seusers(sepol_module_package_t * p,
-				     char *data, size_t len)
-{
-	if (set_char(&p->seusers, data, len))
-		return -1;
-
-	p->seusers_len = len;
-	return 0;
-}
-
-int sepol_module_package_set_user_extra(sepol_module_package_t * p,
-					char *data, size_t len)
-{
-	if (set_char(&p->user_extra, data, len))
-		return -1;
-
-	p->user_extra_len = len;
-	return 0;
-}
-
-int sepol_module_package_set_netfilter_contexts(sepol_module_package_t * p,
-						char *data, size_t len)
-{
-	if (set_char(&p->netfilter_contexts, data, len))
-		return -1;
-
-	p->netfilter_contexts_len = len;
-	return 0;
-}
-
-sepol_policydb_t *sepol_module_package_get_policy(sepol_module_package_t * p)
-{
-	return p->policy;
-}
-
-/* Append each of the file contexts from each module to the base
- * policy's file context.  'base_context' will be reallocated to a
- * larger size (and thus it is an in/out reference
- * variable). 'base_fc_len' is the length of base's file context; it
- * too is a reference variable.  Return 0 on success, -1 if out of
- * memory. */
-static int link_file_contexts(sepol_module_package_t * base,
-			      sepol_module_package_t ** modules,
-			      int num_modules)
-{
-	size_t fc_len;
-	int i;
-	char *s;
-
-	fc_len = base->file_contexts_len;
-	for (i = 0; i < num_modules; i++) {
-		fc_len += modules[i]->file_contexts_len;
-	}
-
-	if ((s = (char *)realloc(base->file_contexts, fc_len)) == NULL) {
-		return -1;
-	}
-	base->file_contexts = s;
-	for (i = 0; i < num_modules; i++) {
-		memcpy(base->file_contexts + base->file_contexts_len,
-		       modules[i]->file_contexts,
-		       modules[i]->file_contexts_len);
-		base->file_contexts_len += modules[i]->file_contexts_len;
-	}
-	return 0;
-}
-
-/* Append each of the netfilter contexts from each module to the base
- * policy's netfilter context.  'base_context' will be reallocated to a
- * larger size (and thus it is an in/out reference
- * variable). 'base_nc_len' is the length of base's netfilter contexts; it
- * too is a reference variable.  Return 0 on success, -1 if out of
- * memory. */
-static int link_netfilter_contexts(sepol_module_package_t * base,
-				   sepol_module_package_t ** modules,
-				   int num_modules)
-{
-	size_t base_nc_len;
-	int i;
-	char *base_context;
-
-	base_nc_len = base->netfilter_contexts_len;
-	for (i = 0; i < num_modules; i++) {
-		base_nc_len += modules[i]->netfilter_contexts_len;
-	}
-
-	if ((base_context =
-	     (char *)realloc(base->netfilter_contexts, base_nc_len)) == NULL) {
-		return -1;
-	}
-	base->netfilter_contexts = base_context;
-	for (i = 0; i < num_modules; i++) {
-		memcpy(base->netfilter_contexts + base->netfilter_contexts_len,
-		       modules[i]->netfilter_contexts,
-		       modules[i]->netfilter_contexts_len);
-		base->netfilter_contexts_len +=
-		    modules[i]->netfilter_contexts_len;
-	}
-	return 0;
-}
-
-/* Links the module packages into the base.  Returns 0 on success, -1
- * if a requirement was not met, or -2 for all other errors. */
-int sepol_link_packages(sepol_handle_t * handle,
-			sepol_module_package_t * base,
-			sepol_module_package_t ** modules, int num_modules,
-			int verbose)
-{
-	policydb_t **mod_pols = NULL;
-	int i, retval;
-
-	if ((mod_pols = calloc(num_modules, sizeof(*mod_pols))) == NULL) {
-		ERR(handle, "Out of memory!");
-		return -2;
-	}
-	for (i = 0; i < num_modules; i++) {
-		mod_pols[i] = &modules[i]->policy->p;
-	}
-
-	retval = link_modules(handle, &base->policy->p, mod_pols, num_modules,
-			      verbose);
-	free(mod_pols);
-	if (retval == -3) {
-		return -1;
-	} else if (retval < 0) {
-		return -2;
-	}
-
-	if (link_file_contexts(base, modules, num_modules) == -1) {
-		ERR(handle, "Out of memory!");
-		return -2;
-	}
-
-	if (link_netfilter_contexts(base, modules, num_modules) == -1) {
-		ERR(handle, "Out of memory!");
-		return -2;
-	}
-
-	return 0;
-}
-
-/* buf must be large enough - no checks are performed */
-#define _read_helper_bufsize BUFSIZ
-static int read_helper(char *buf, struct policy_file *file, uint32_t bytes)
-{
-	uint32_t offset, nel, read_len;
-	void *tmp;
-
-	offset = 0;
-	nel = bytes;
-
-	while (nel) {
-		if (nel < _read_helper_bufsize)
-			read_len = nel;
-		else
-			read_len = _read_helper_bufsize;
-		tmp = next_entry(file, read_len);
-		if (!tmp)
-			return -1;
-		memcpy(&buf[offset], tmp, read_len);
-		offset += read_len;
-		nel -= read_len;
-	}
-	return 0;
-}
-
-#define MAXSECTIONS 100
-
-/* Get the section offsets from a package file, offsets will be malloc'd to
- * the appropriate size and the caller must free() them */
-static int module_package_read_offsets(sepol_module_package_t * mod,
-				       struct policy_file *file,
-				       size_t ** offsets, uint32_t * sections)
-{
-	uint32_t *buf, nsec;
-	unsigned i;
-
-	buf = next_entry(file, sizeof(uint32_t) * 3);
-	if (!buf) {
-		ERR(file->handle, "module package header truncated");
-		return -1;
-	}
-	if (le32_to_cpu(buf[0]) != SEPOL_MODULE_PACKAGE_MAGIC) {
-		ERR(file->handle,
-		    "wrong magic number for module package:  expected %u, got %u",
-		    SEPOL_MODULE_PACKAGE_MAGIC, le32_to_cpu(buf[0]));
-		return -1;
-	}
-
-	mod->version = le32_to_cpu(buf[1]);
-	nsec = *sections = le32_to_cpu(buf[2]);
-
-	if (nsec > MAXSECTIONS) {
-		ERR(file->handle, "too many sections (%u) in module package",
-		    nsec);
-		return -1;
-	}
-
-	*offsets = (size_t *) malloc((nsec + 1) * sizeof(size_t));
-	if (!*offsets) {
-		ERR(file->handle, "out of memory");
-		return -1;
-	}
-
-	buf = next_entry(file, sizeof(uint32_t) * nsec);
-	if (!buf) {
-		ERR(file->handle, "module package offset array truncated");
-		return -1;
-	}
-
-	for (i = 0; i < nsec; i++) {
-		(*offsets)[i] = le32_to_cpu(buf[i]);
-		if (i && (*offsets)[i] < (*offsets)[i - 1]) {
-			ERR(file->handle, "offsets are not increasing (at %u, "
-			    "offset %zu -> %zu", i, (*offsets)[i - 1],
-			    (*offsets)[i]);
-			return -1;
-		}
-	}
-
-	(*offsets)[nsec] = policy_file_length(file);
-	return 0;
-}
-
-/* Flags for which sections have been seen during parsing of module package. */
-#define SEEN_MOD 1
-#define SEEN_FC  2
-#define SEEN_SEUSER 4
-#define SEEN_USER_EXTRA 8
-#define SEEN_NETFILTER 16
-
-int sepol_module_package_read(sepol_module_package_t * mod,
-			      struct sepol_policy_file *spf, int verbose)
-{
-	struct policy_file *file = &spf->pf;
-	uint32_t *buf, nsec;
-	size_t *offsets, len;
-	int retval = -1;
-	unsigned i, seen = 0;
-
-	if (module_package_read_offsets(mod, file, &offsets, &nsec))
-		return -1;
-
-	/* we know the section offsets, seek to them and read in the data */
-
-	for (i = 0; i < nsec; i++) {
-
-		if (policy_file_seek(file, offsets[i])) {
-			ERR(file->handle, "error seeking to offset %zu for "
-			    "module package section %u", offsets[i], i);
-			goto cleanup;
-		}
-
-		len = offsets[i + 1] - offsets[i];
-
-		if (len < sizeof(uint32_t)) {
-			ERR(file->handle, "module package section %u "
-			    "has too small length %zu", i, len);
-			goto cleanup;
-		}
-
-		/* read the magic number, so that we know which function to call */
-		buf = next_entry(file, sizeof(uint32_t));
-		if (!buf) {
-			ERR(file->handle,
-			    "module package section %u truncated, lacks magic number",
-			    i);
-			goto cleanup;
-		}
-
-		switch (le32_to_cpu(buf[0])) {
-		case SEPOL_PACKAGE_SECTION_FC:
-			if (seen & SEEN_FC) {
-				ERR(file->handle,
-				    "found multiple file contexts sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-
-			mod->file_contexts_len = len - sizeof(uint32_t);
-			mod->file_contexts =
-			    (char *)malloc(mod->file_contexts_len);
-			if (!mod->file_contexts) {
-				ERR(file->handle, "out of memory");
-				goto cleanup;
-			}
-			if (read_helper
-			    (mod->file_contexts, file,
-			     mod->file_contexts_len)) {
-				ERR(file->handle,
-				    "invalid file contexts section at section %u",
-				    i);
-				free(mod->file_contexts);
-				mod->file_contexts = NULL;
-				goto cleanup;
-			}
-			seen |= SEEN_FC;
-			break;
-		case SEPOL_PACKAGE_SECTION_SEUSER:
-			if (seen & SEEN_SEUSER) {
-				ERR(file->handle,
-				    "found multiple seuser sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-
-			mod->seusers_len = len - sizeof(uint32_t);
-			mod->seusers = (char *)malloc(mod->seusers_len);
-			if (!mod->seusers) {
-				ERR(file->handle, "out of memory");
-				goto cleanup;
-			}
-			if (read_helper(mod->seusers, file, mod->seusers_len)) {
-				ERR(file->handle,
-				    "invalid seuser section at section %u", i);
-				free(mod->seusers);
-				mod->seusers = NULL;
-				goto cleanup;
-			}
-			seen |= SEEN_SEUSER;
-			break;
-		case SEPOL_PACKAGE_SECTION_USER_EXTRA:
-			if (seen & SEEN_USER_EXTRA) {
-				ERR(file->handle,
-				    "found multiple user_extra sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-
-			mod->user_extra_len = len - sizeof(uint32_t);
-			mod->user_extra = (char *)malloc(mod->user_extra_len);
-			if (!mod->user_extra) {
-				ERR(file->handle, "out of memory");
-				goto cleanup;
-			}
-			if (read_helper
-			    (mod->user_extra, file, mod->user_extra_len)) {
-				ERR(file->handle,
-				    "invalid user_extra section at section %u",
-				    i);
-				free(mod->user_extra);
-				mod->user_extra = NULL;
-				goto cleanup;
-			}
-			seen |= SEEN_USER_EXTRA;
-			break;
-		case SEPOL_PACKAGE_SECTION_NETFILTER:
-			if (seen & SEEN_NETFILTER) {
-				ERR(file->handle,
-				    "found multiple netfilter contexts sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-
-			mod->netfilter_contexts_len = len - sizeof(uint32_t);
-			mod->netfilter_contexts =
-			    (char *)malloc(mod->netfilter_contexts_len);
-			if (!mod->netfilter_contexts) {
-				ERR(file->handle, "out of memory");
-				goto cleanup;
-			}
-			if (read_helper
-			    (mod->netfilter_contexts, file,
-			     mod->netfilter_contexts_len)) {
-				ERR(file->handle,
-				    "invalid netfilter contexts section at section %u",
-				    i);
-				free(mod->netfilter_contexts);
-				mod->netfilter_contexts = NULL;
-				goto cleanup;
-			}
-			seen |= SEEN_NETFILTER;
-			break;
-		case POLICYDB_MOD_MAGIC:
-			if (seen & SEEN_MOD) {
-				ERR(file->handle,
-				    "found multiple module sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-
-			/* seek back to where the magic number was */
-			if (policy_file_seek(file, offsets[i]))
-				goto cleanup;
-
-			retval = policydb_read(&mod->policy->p, file, verbose);
-			if (retval < 0) {
-				ERR(file->handle,
-				    "invalid module in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			seen |= SEEN_MOD;
-			break;
-		default:
-			/* unknown section, ignore */
-			ERR(file->handle,
-			    "unknown magic number at section %u, offset: %zx, number: %ux ",
-			    i, offsets[i], le32_to_cpu(buf[0]));
-			break;
-		}
-	}
-
-	if ((seen & SEEN_MOD) == 0) {
-		ERR(file->handle, "missing module in module package");
-		goto cleanup;
-	}
-
-	free(offsets);
-	return 0;
-
-      cleanup:
-	free(offsets);
-	return retval;
-}
-
-int sepol_module_package_info(struct sepol_policy_file *spf, int *type,
-			      char **name, char **version)
-{
-	struct policy_file *file = &spf->pf;
-	sepol_module_package_t *mod = NULL;
-	uint32_t *buf, len, nsec;
-	size_t *offsets = NULL;
-	unsigned i, seen = 0;
-
-	if (sepol_module_package_create(&mod))
-		return -1;
-
-	if (module_package_read_offsets(mod, file, &offsets, &nsec)) {
-		goto cleanup;
-	}
-
-	for (i = 0; i < nsec; i++) {
-
-		if (policy_file_seek(file, offsets[i])) {
-			ERR(file->handle, "error seeking to offset "
-			    "%zu for module package section %u", offsets[i], i);
-			goto cleanup;
-		}
-
-		len = offsets[i + 1] - offsets[i];
-
-		if (len < sizeof(uint32_t)) {
-			ERR(file->handle,
-			    "module package section %u has too small length %u",
-			    i, len);
-			goto cleanup;
-		}
-
-		/* read the magic number, so that we know which function to call */
-		buf = next_entry(file, sizeof(uint32_t) * 2);
-		if (!buf) {
-			ERR(file->handle,
-			    "module package section %u truncated, lacks magic number",
-			    i);
-			goto cleanup;
-		}
-
-		switch (le32_to_cpu(buf[0])) {
-		case SEPOL_PACKAGE_SECTION_FC:
-			/* skip file contexts */
-			if (seen & SEEN_FC) {
-				ERR(file->handle,
-				    "found multiple file contexts sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			seen |= SEEN_FC;
-			break;
-		case SEPOL_PACKAGE_SECTION_SEUSER:
-			/* skip seuser */
-			if (seen & SEEN_SEUSER) {
-				ERR(file->handle,
-				    "found seuser sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			seen |= SEEN_SEUSER;
-			break;
-		case SEPOL_PACKAGE_SECTION_USER_EXTRA:
-			/* skip user_extra */
-			if (seen & SEEN_USER_EXTRA) {
-				ERR(file->handle,
-				    "found user_extra sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			seen |= SEEN_USER_EXTRA;
-			break;
-		case SEPOL_PACKAGE_SECTION_NETFILTER:
-			/* skip netfilter contexts */
-			if (seen & SEEN_NETFILTER) {
-				ERR(file->handle,
-				    "found multiple netfilter contexts sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			seen |= SEEN_NETFILTER;
-			break;
-		case POLICYDB_MOD_MAGIC:
-			if (seen & SEEN_MOD) {
-				ERR(file->handle,
-				    "found multiple module sections in module package (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			len = le32_to_cpu(buf[1]);
-			if (len != strlen(POLICYDB_MOD_STRING)) {
-				ERR(file->handle,
-				    "module string length is wrong (at section %u)",
-				    i);
-				goto cleanup;
-			}
-
-			/* skip id */
-			buf = next_entry(file, len);
-			if (!buf) {
-				ERR(file->handle,
-				    "cannot get module string (at section %u)",
-				    i);
-				goto cleanup;
-			}
-
-			buf = next_entry(file, sizeof(uint32_t) * 5);
-			if (!buf) {
-				ERR(file->handle,
-				    "cannot get module header (at section %u)",
-				    i);
-				goto cleanup;
-			}
-
-			*type = le32_to_cpu(buf[0]);
-			/* if base - we're done */
-			if (*type == POLICY_BASE) {
-				*name = NULL;
-				*version = NULL;
-				seen |= SEEN_MOD;
-				break;
-			} else if (*type != POLICY_MOD) {
-				ERR(file->handle,
-				    "module has invalid type %d (at section %u)",
-				    *type, i);
-				goto cleanup;
-			}
-
-			/* read the name and version */
-			buf = next_entry(file, sizeof(uint32_t));
-			if (!buf) {
-				ERR(file->handle,
-				    "cannot get module name len (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			len = le32_to_cpu(buf[0]);
-			buf = next_entry(file, len);
-			if (!buf) {
-				ERR(file->handle,
-				    "cannot get module name string (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			*name = malloc(len + 1);
-			if (!*name) {
-				ERR(file->handle, "out of memory");
-				goto cleanup;
-			}
-			memcpy(*name, buf, len);
-			(*name)[len] = '\0';
-			buf = next_entry(file, sizeof(uint32_t));
-			if (!buf) {
-				ERR(file->handle,
-				    "cannot get module version len (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			len = le32_to_cpu(buf[0]);
-			buf = next_entry(file, len);
-			if (!buf) {
-				ERR(file->handle,
-				    "cannot get module version string (at section %u)",
-				    i);
-				goto cleanup;
-			}
-			*version = malloc(len + 1);
-			if (!*version) {
-				ERR(file->handle, "out of memory");
-				goto cleanup;
-			}
-			memcpy(*version, buf, len);
-			(*version)[len] = '\0';
-			seen |= SEEN_MOD;
-			break;
-		default:
-			break;
-		}
-
-	}
-
-	if ((seen & SEEN_MOD) == 0) {
-		ERR(file->handle, "missing module in module package");
-		goto cleanup;
-	}
-
-	sepol_module_package_free(mod);
-	free(offsets);
-	return 0;
-
-      cleanup:
-	sepol_module_package_free(mod);
-	free(offsets);
-	return -1;
-}
-
-static int write_helper(char *data, size_t len, struct policy_file *file)
-{
-	int idx = 0;
-	size_t len2;
-
-	while (len) {
-		if (len > BUFSIZ)
-			len2 = BUFSIZ;
-		else
-			len2 = len;
-
-		if (put_entry(&data[idx], 1, len2, file) != len2) {
-			return -1;
-		}
-		len -= len2;
-		idx += len2;
-	}
-	return 0;
-}
-
-int sepol_module_package_write(sepol_module_package_t * p,
-			       struct sepol_policy_file *spf)
-{
-	struct policy_file *file = &spf->pf;
-	policy_file_t polfile;
-	uint32_t buf[5], offsets[5], len, nsec = 0;
-	int i;
-
-	if (p->policy) {
-		/* compute policy length */
-		polfile.type = PF_LEN;
-		polfile.data = NULL;
-		polfile.len = 0;
-		polfile.handle = file->handle;
-		if (policydb_write(&p->policy->p, &polfile))
-			return -1;
-		len = polfile.len;
-		if (!polfile.len)
-			return -1;
-		nsec++;
-
-	} else {
-		/* We don't support writing a package without a module at this point */
-		return -1;
-	}
-
-	/* seusers and user_extra only supported in base at the moment */
-	if ((p->seusers || p->user_extra)
-	    && (p->policy->p.policy_type != SEPOL_POLICY_BASE)) {
-		ERR(file->handle,
-		    "seuser and user_extra sections only supported in base");
-		return -1;
-	}
-
-	if (p->file_contexts)
-		nsec++;
-
-	if (p->seusers)
-		nsec++;
-
-	if (p->user_extra)
-		nsec++;
-
-	if (p->netfilter_contexts)
-		nsec++;
-
-	buf[0] = cpu_to_le32(SEPOL_MODULE_PACKAGE_MAGIC);
-	buf[1] = cpu_to_le32(p->version);
-	buf[2] = cpu_to_le32(nsec);
-	if (put_entry(buf, sizeof(uint32_t), 3, file) != 3)
-		return -1;
-
-	/* calculate offsets */
-	offsets[0] = (nsec + 3) * sizeof(uint32_t);
-	buf[0] = cpu_to_le32(offsets[0]);
-
-	i = 1;
-	if (p->file_contexts) {
-		offsets[i] = offsets[i - 1] + len;
-		buf[i] = cpu_to_le32(offsets[i]);
-		/* add a uint32_t to compensate for the magic number */
-		len = p->file_contexts_len + sizeof(uint32_t);
-		i++;
-	}
-	if (p->seusers) {
-		offsets[i] = offsets[i - 1] + len;
-		buf[i] = cpu_to_le32(offsets[i]);
-		len = p->seusers_len + sizeof(uint32_t);
-		i++;
-	}
-	if (p->user_extra) {
-		offsets[i] = offsets[i - 1] + len;
-		buf[i] = cpu_to_le32(offsets[i]);
-		len = p->user_extra_len + sizeof(uint32_t);
-		i++;
-	}
-	if (p->netfilter_contexts) {
-		offsets[i] = offsets[i - 1] + len;
-		buf[i] = cpu_to_le32(offsets[i]);
-		len = p->netfilter_contexts_len + sizeof(uint32_t);
-		i++;
-	}
-	if (put_entry(buf, sizeof(uint32_t), nsec, file) != nsec)
-		return -1;
-
-	/* write sections */
-
-	if (policydb_write(&p->policy->p, file))
-		return -1;
-
-	if (p->file_contexts) {
-		buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_FC);
-		if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
-			return -1;
-		if (write_helper(p->file_contexts, p->file_contexts_len, file))
-			return -1;
-	}
-	if (p->seusers) {
-		buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_SEUSER);
-		if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
-			return -1;
-		if (write_helper(p->seusers, p->seusers_len, file))
-			return -1;
-
-	}
-	if (p->user_extra) {
-		buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_USER_EXTRA);
-		if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
-			return -1;
-		if (write_helper(p->user_extra, p->user_extra_len, file))
-			return -1;
-	}
-	if (p->netfilter_contexts) {
-		buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_NETFILTER);
-		if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
-			return -1;
-		if (write_helper
-		    (p->netfilter_contexts, p->netfilter_contexts_len, file))
-			return -1;
-	}
-	return 0;
-}
-
-int sepol_link_modules(sepol_handle_t * handle,
-		       sepol_policydb_t * base,
-		       sepol_policydb_t ** modules, size_t len, int verbose)
-{
-	return link_modules(handle, &base->p, (policydb_t **) modules, len,
-			    verbose);
-}
-
-int sepol_expand_module(sepol_handle_t * handle,
-			sepol_policydb_t * base,
-			sepol_policydb_t * out, int verbose, int check)
-{
-	return expand_module(handle, &base->p, &out->p, verbose, check);
-}
--- foo.orig/libsepol/include/sepol/policydb/expand.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Authors: Jason Tang <jtang@tresys.com>
- *	    Joshua Brindle <jbrindle@tresys.com>
- *          Karl MacMillan <kmacmillan@tresys.com>
- *
- * A set of utility functions that aid policy decision when dealing
- * with hierarchal items.
- *
- * Copyright (C) 2005 Tresys Technology, LLC
- *
- *  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
- */
-
-#ifndef _SEPOL_POLICYDB_EXPAND_H
-#define _SEPOL_POLICYDB_EXPAND_H
-
-#include <stddef.h>
-#include <sepol/handle.h>
-#include <sepol/policydb/conditional.h>
-
-/*
- * Expand only the avrules for a module. It is valid for this function
- * to expand base into itself (i.e.  base == out); the typemap for
- * this special case should map type[i] to i+1.  Likewise the boolmap
- * should map bool[i] to i + 1.  This function optionally expands
- * neverallow rules. If neverallow rules are expanded, there is no
- * need to copy them and doing so could cause duplicate entries when
- * base == out.  If the neverallow rules are not expanded, they are
- * just copied to the destination policy so that assertion checking
- * can be performed after expand.  No assertion or hierarchy checking
- * is performed by this function.
- */
-extern int expand_module_avrules(sepol_handle_t * handle, policydb_t * base,
-				 policydb_t * out, uint32_t * typemap, uint32_t * boolmap,
-				 int verbose, int expand_neverallow);
-/*
- * Expand all parts of a module. Neverallow rules are not expanded (only
- * copied). It is not valid to expand base into itself. If check is non-zero,
- * performs hierarchy and assertion checking.
- */
-extern int expand_module(sepol_handle_t * handle,
-			 policydb_t * base, policydb_t * out,
-			 int verbose, int check);
-extern int convert_type_ebitmap(ebitmap_t * src, ebitmap_t * dst,
-				uint32_t * typemap);
-extern int expand_convert_type_set(policydb_t * p, uint32_t * typemap,
-				   type_set_t * set, ebitmap_t * types,
-				   unsigned char alwaysexpand);
-extern int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p,
-			   unsigned char alwaysexpand);
-extern int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * p);
-extern int mls_semantic_level_expand(mls_semantic_level_t *sl, mls_level_t *l,
-                                     policydb_t *p, sepol_handle_t *h);
-extern int mls_semantic_range_expand(mls_semantic_range_t *sr, mls_range_t *r,
-                                     policydb_t *p, sepol_handle_t *h);
-extern int expand_rule(sepol_handle_t * handle,
-		       policydb_t * source_pol,
-		       avrule_t * source_rule, avtab_t * dest_avtab,
-		       cond_av_list_t ** cond, cond_av_list_t ** other,
-		       int enabled);
-
-extern int expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa);
-
-extern int expand_cond_av_list(policydb_t * p, cond_av_list_t * l,
-			       cond_av_list_t ** newl, avtab_t * expa);
-
-#endif
--- foo.orig/libsepol/include/sepol/policydb/link.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Authors: Jason Tang <jtang@tresys.com>
- *	    Joshua Brindle <jbrindle@tresys.com>
- *          Karl MacMillan <kmacmillan@mentalrootkit.com>
- */
-
-#ifndef _SEPOL_POLICYDB_LINK_H
-#define _SEPOL_POLICYDB_LINK_H
-
-#include <sepol/handle.h>
-#include <sepol/errcodes.h>
-#include <sepol/policydb/policydb.h>
-
-
-#include <stddef.h>
-
-extern int link_modules(sepol_handle_t * handle,
-			policydb_t * b, policydb_t ** mods, int len,
-			int verbose);
-
-#endif
--- foo.orig/libsepol/include/sepol/policydb/module.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Author: Karl MacMillan <kmacmillan@tresys.com>
- *
- * Copyright (C) 2004-2005 Tresys Technology, LLC
- *
- *  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
- */
-
-#ifndef _SEPOL_POLICYDB_MODULE_H_
-#define _SEPOL_POLICYDB_MODULE_H_
-
-#include <stdlib.h>
-#include <stddef.h>
-
-#include <sepol/module.h>
-
-#include <sepol/policydb/policydb.h>
-#include <sepol/policydb/conditional.h>
-
-#define SEPOL_MODULE_PACKAGE_MAGIC 0xf97cff8f
-
-struct sepol_module_package {
-	sepol_policydb_t *policy;
-	uint32_t version;
-	char *file_contexts;
-	size_t file_contexts_len;
-	char *seusers;
-	size_t seusers_len;
-	char *user_extra;
-	size_t user_extra_len;
-	char *netfilter_contexts;
-	size_t netfilter_contexts_len;
-};
-
-extern int sepol_module_package_init(sepol_module_package_t * p);
-
-#endif

-- 

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [POLICYREP] [Patch 3/5] << part 1 >> This patch does all the functional work of removing the module support code.
  2007-08-16 15:53 [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Mark Goldman
  2007-08-16 15:53 ` [POLICYREP] [Patch 1/5] << Part 1 >> This patch removes files that existed solely to support modular policies Mark Goldman
  2007-08-16 15:53 ` [POLICYREP] [Patch 2/5] " Mark Goldman
@ 2007-08-16 15:53 ` Mark Goldman
  2007-08-16 15:53 ` [POLICYREP] [Patch 4/5] " Mark Goldman
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Goldman @ 2007-08-16 15:53 UTC (permalink / raw)
  To: selinux

Various unnecessary structs were removed.

At the end of this patch, libsepol is able to load policies, but does not
know about modules.

dispol operates as expected when using libsepol at the end of this patch.

---
 libsepol/src/policydb.c | 1512 	240 +	1272 -	0 !
 1 file changed, 240 insertions(+), 1272 deletions(-)

--- foo.orig/libsepol/src/policydb.c
+++ foo/libsepol/src/policydb.c
@@ -44,7 +44,6 @@
 #include <stdlib.h>
 
 #include <sepol/policydb/policydb.h>
-#include <sepol/policydb/expand.h>
 #include <sepol/policydb/conditional.h>
 #include <sepol/policydb/avrule_block.h>
 #include <sepol/policydb/util.h>
@@ -57,82 +56,40 @@
 /* These need to be updated if SYM_NUM or OCON_NUM changes */
 static struct policydb_compat_info policydb_compat[] = {
 	{
-	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_BASE,
 	 .sym_num = SYM_NUM - 3,
 	 .ocon_num = OCON_FSUSE + 1,
 	 },
 	{
-	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_BOOL,
 	 .sym_num = SYM_NUM - 2,
 	 .ocon_num = OCON_FSUSE + 1,
 	 },
 	{
-	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_IPV6,
 	 .sym_num = SYM_NUM - 2,
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
 	{
-	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_NLCLASS,
 	 .sym_num = SYM_NUM - 2,
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
 	{
-	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_MLS,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
 	{
-	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_AVTAB,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
 	{
-	 .type = POLICY_KERN,
 	 .version = POLICYDB_VERSION_RANGETRANS,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
-	{
-	 .type = POLICY_BASE,
-	 .version = MOD_POLICYDB_VERSION_BASE,
-	 .sym_num = SYM_NUM,
-	 .ocon_num = OCON_NODE6 + 1,
-	 },
-	{
-	 .type = POLICY_BASE,
-	 .version = MOD_POLICYDB_VERSION_MLS,
-	 .sym_num = SYM_NUM,
-	 .ocon_num = OCON_NODE6 + 1,
-	 },
-	{
-	 .type = POLICY_BASE,
-	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
-	 .sym_num = SYM_NUM,
-	 .ocon_num = OCON_NODE6 + 1,
-	 },
-	{
-	 .type = POLICY_MOD,
-	 .version = MOD_POLICYDB_VERSION_BASE,
-	 .sym_num = SYM_NUM,
-	 .ocon_num = 0,
-	 },
-	{
-	 .type = POLICY_MOD,
-	 .version = MOD_POLICYDB_VERSION_MLS,
-	 .sym_num = SYM_NUM,
-	 .ocon_num = 0,
-	 },
-	{
-	 .type = POLICY_MOD,
-	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
-	 .sym_num = SYM_NUM,
-	 .ocon_num = 0},
 };
 
 #if 0
@@ -157,15 +114,13 @@ static unsigned int symtab_sizes[SYM_NUM
 	16,
 };
 
-struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
-						    unsigned int type)
+struct policydb_compat_info *policydb_lookup_compat(unsigned int version)
 {
 	unsigned int i;
 	struct policydb_compat_info *info = NULL;
 
 	for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) {
-		if (policydb_compat[i].version == version &&
-		    policydb_compat[i].type == type) {
+		if (policydb_compat[i].version == version) {
 			info = &policydb_compat[i];
 			break;
 		}
@@ -173,37 +128,11 @@ struct policydb_compat_info *policydb_lo
 	return info;
 }
 
-void type_set_init(type_set_t * x)
-{
-	memset(x, 0, sizeof(type_set_t));
-	ebitmap_init(&x->types);
-	ebitmap_init(&x->negset);
-}
-
-void type_set_destroy(type_set_t * x)
-{
-	if (x != NULL) {
-		ebitmap_destroy(&x->types);
-		ebitmap_destroy(&x->negset);
-	}
-}
-
-void role_set_init(role_set_t * x)
-{
-	memset(x, 0, sizeof(role_set_t));
-	ebitmap_init(&x->roles);
-}
-
-void role_set_destroy(role_set_t * x)
-{
-	ebitmap_destroy(&x->roles);
-}
-
 void role_datum_init(role_datum_t * x)
 {
 	memset(x, 0, sizeof(role_datum_t));
 	ebitmap_init(&x->dominates);
-	type_set_init(&x->types);
+	ebitmap_init(&x->types);
 	ebitmap_init(&x->cache);
 }
 
@@ -211,7 +140,7 @@ void role_datum_destroy(role_datum_t * x
 {
 	if (x != NULL) {
 		ebitmap_destroy(&x->dominates);
-		type_set_destroy(&x->types);
+		ebitmap_destroy(&x->types);
 		ebitmap_destroy(&x->cache);
 	}
 }
@@ -232,7 +161,7 @@ void type_datum_destroy(type_datum_t * x
 void user_datum_init(user_datum_t * x)
 {
 	memset(x, 0, sizeof(user_datum_t));
-	role_set_init(&x->roles);
+	ebitmap_init(&x->roles);
 	mls_semantic_range_init(&x->range);
 	mls_semantic_level_init(&x->dfltlevel);
 	ebitmap_init(&x->cache);
@@ -243,7 +172,7 @@ void user_datum_init(user_datum_t * x)
 void user_datum_destroy(user_datum_t * x)
 {
 	if (x != NULL) {
-		role_set_destroy(&x->roles);
+		ebitmap_destroy(&x->roles);
 		mls_semantic_range_destroy(&x->range);
 		mls_semantic_level_destroy(&x->dfltlevel);
 		ebitmap_destroy(&x->cache);
@@ -275,131 +204,8 @@ void cat_datum_destroy(cat_datum_t * x _
 	return;
 }
 
-void class_perm_node_init(class_perm_node_t * x)
-{
-	memset(x, 0, sizeof(class_perm_node_t));
-}
-
-void avrule_init(avrule_t * x)
-{
-	memset(x, 0, sizeof(avrule_t));
-	type_set_init(&x->stypes);
-	type_set_init(&x->ttypes);
-}
-
-void avrule_destroy(avrule_t * x)
-{
-	class_perm_node_t *cur, *next;
-
-	if (x == NULL) {
-		return;
-	}
-	type_set_destroy(&x->stypes);
-	type_set_destroy(&x->ttypes);
-
-	next = x->perms;
-	while (next) {
-		cur = next;
-		next = cur->next;
-		free(cur);
-	}
-}
-
-void role_trans_rule_init(role_trans_rule_t * x)
-{
-	memset(x, 0, sizeof(*x));
-	role_set_init(&x->roles);
-	type_set_init(&x->types);
-}
-
-void role_trans_rule_destroy(role_trans_rule_t * x)
-{
-	if (x != NULL) {
-		role_set_destroy(&x->roles);
-		type_set_destroy(&x->types);
-	}
-}
-
-void role_trans_rule_list_destroy(role_trans_rule_t * x)
-{
-	while (x != NULL) {
-		role_trans_rule_t *next = x->next;
-		role_trans_rule_destroy(x);
-		free(x);
-		x = next;
-	}
-}
-
-void role_allow_rule_init(role_allow_rule_t * x)
-{
-	memset(x, 0, sizeof(role_allow_rule_t));
-	role_set_init(&x->roles);
-	role_set_init(&x->new_roles);
-}
-
-void role_allow_rule_destroy(role_allow_rule_t * x)
-{
-	role_set_destroy(&x->roles);
-	role_set_destroy(&x->new_roles);
-}
-
-void role_allow_rule_list_destroy(role_allow_rule_t * x)
-{
-	while (x != NULL) {
-		role_allow_rule_t *next = x->next;
-		role_allow_rule_destroy(x);
-		free(x);
-		x = next;
-	}
-}
-
-void range_trans_rule_init(range_trans_rule_t * x)
-{
-	type_set_init(&x->stypes);
-	type_set_init(&x->ttypes);
-	ebitmap_init(&x->tclasses);
-	mls_semantic_range_init(&x->trange);
-	x->next = NULL;
-}
-
-void range_trans_rule_destroy(range_trans_rule_t * x)
-{
-	type_set_destroy(&x->stypes);
-	type_set_destroy(&x->ttypes);
-	ebitmap_destroy(&x->tclasses);
-	mls_semantic_range_destroy(&x->trange);
-}
-
-void range_trans_rule_list_destroy(range_trans_rule_t * x)
-{
-	while (x != NULL) {
-		range_trans_rule_t *next = x->next;
-		range_trans_rule_destroy(x);
-		free(x);
-		x = next;
-	}
-}
-
-void avrule_list_destroy(avrule_t * x)
-{
-	avrule_t *next, *cur;
-
-	if (!x)
-		return;
-
-	next = x;
-	while (next) {
-		cur = next;
-		next = next->next;
-		avrule_destroy(cur);
-		free(cur);
-	}
-}
-
 /* 
- * Initialize the role table by implicitly adding role 'object_r'.  If
- * the policy is a module, set object_r's scope to be SCOPE_REQ,
- * otherwise set it to SCOPE_DECL.
+ * Initialize the role table by implicitly adding role 'object_r'.
  */
 static int roles_init(policydb_t * p)
 {
@@ -418,10 +224,7 @@ static int roles_init(policydb_t * p)
 		goto out_free_role;
 	}
 	strcpy(key, OBJECT_R);
-	rc = symtab_insert(p, SYM_ROLES, key, role,
-			   (p->policy_type ==
-			    POLICY_MOD ? SCOPE_REQ : SCOPE_DECL), 1,
-			   &role->s.value);
+	rc = symtab_insert(p, SYM_ROLES, key, role, 1, &role->s.value);
 	if (rc)
 		goto out_free_key;
 	if (role->s.value != OBJECT_R_VAL) {
@@ -454,18 +257,6 @@ int policydb_init(policydb_t * p)
 			goto out_free_symtab;
 	}
 
-	/* initialize the module stuff */
-	for (i = 0; i < SYM_NUM; i++) {
-		if (symtab_init(&p->scope[i], symtab_sizes[i])) {
-			goto out_free_symtab;
-		}
-	}
-	if ((p->global = avrule_block_create()) == NULL ||
-	    (p->global->branch_list = avrule_decl_create(1)) == NULL) {
-		goto out_free_symtab;
-	}
-	p->decl_val_to_struct = NULL;
-
 	rc = avtab_init(&p->te_avtab);
 	if (rc)
 		goto out_free_symtab;
@@ -486,15 +277,19 @@ int policydb_init(policydb_t * p)
       out_free_symtab:
 	for (i = 0; i < SYM_NUM; i++) {
 		hashtab_destroy(p->symtab[i].table);
-		hashtab_destroy(p->scope[i].table);
 	}
-	avrule_block_list_destroy(p->global);
 	goto out;
 }
 
+/* NOTE: Cacheing may or may not make sense when the new policyrep gets
+ * here.  These functions may just go away.  Currently this function only
+ * gets called from inside libsepol.
+ *  - mgoldman@tresys.com 2007-06-21
+ */
 int policydb_role_cache(hashtab_key_t key
-			__attribute__ ((unused)), hashtab_datum_t datum,
-			void *arg)
+			__attribute__ ((unused)), hashtab_datum_t datum
+			__attribute__ ((unused)), void *arg
+			__attribute__ ((unused)))
 {
 	policydb_t *p;
 	role_datum_t *role;
@@ -503,16 +298,23 @@ int policydb_role_cache(hashtab_key_t ke
 	p = (policydb_t *) arg;
 
 	ebitmap_destroy(&role->cache);
-	if (type_set_expand(&role->types, &role->cache, p, 1)) {
+	ebitmap_init(&role->cache);
+	if (ebitmap_cpy(&role->cache, &role->types)) {
 		return -1;
 	}
 
 	return 0;
 }
 
+/* NOTE: Cacheing may or may not make sense when the new policyrep gets
+ * here.  These functions may just go away.  Currently this function only
+ * gets called from inside libsepol.
+ *  - mgoldman@tresys.com 2007-06-21
+ */
 int policydb_user_cache(hashtab_key_t key
-			__attribute__ ((unused)), hashtab_datum_t datum,
-			void *arg)
+			__attribute__ ((unused)), hashtab_datum_t datum
+			__attribute__ ((unused)), void *arg
+			__attribute__ ((unused)))
 {
 	policydb_t *p;
 	user_datum_t *user;
@@ -521,28 +323,11 @@ int policydb_user_cache(hashtab_key_t ke
 	p = (policydb_t *) arg;
 
 	ebitmap_destroy(&user->cache);
-	if (role_set_expand(&user->roles, &user->cache, p)) {
+	ebitmap_init(&user->cache);
+	if (ebitmap_cpy(&user->cache, &user->roles)) {
 		return -1;
 	}
 
-	/* we do not expand user's MLS info in kernel policies because the
-	 * semantic representation is not present and we do not expand user's
-	 * MLS info in module policies because all of the necessary mls
-	 * information is not present */
-	if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) {
-		mls_range_destroy(&user->exp_range);
-		if (mls_semantic_range_expand(&user->range,
-					      &user->exp_range, p, NULL)) {
-			return -1;
-		}
-
-		mls_level_destroy(&user->exp_dfltlevel);
-		if (mls_semantic_level_expand(&user->dfltlevel,
-					      &user->exp_dfltlevel, p, NULL)) {
-			return -1;
-		}
-	}
-
 	return 0;
 }
 
@@ -723,37 +508,6 @@ int policydb_index_bools(policydb_t * p)
 	return 0;
 }
 
-int policydb_index_decls(policydb_t * p)
-{
-	avrule_block_t *curblock;
-	avrule_decl_t *decl;
-	int num_decls = 0;
-
-	free(p->decl_val_to_struct);
-
-	for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
-		for (decl = curblock->branch_list; decl != NULL;
-		     decl = decl->next) {
-			num_decls++;
-		}
-	}
-
-	p->decl_val_to_struct =
-	    calloc(num_decls, sizeof(*(p->decl_val_to_struct)));
-	if (!p->decl_val_to_struct) {
-		return -1;
-	}
-
-	for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
-		for (decl = curblock->branch_list; decl != NULL;
-		     decl = decl->next) {
-			p->decl_val_to_struct[decl->decl_id - 1] = decl;
-		}
-	}
-
-	return 0;
-}
-
 /*
  * Define the other val_to_name and val_to_struct arrays
  * in a policy database structure.  
@@ -986,15 +740,6 @@ void policydb_destroy(policydb_t * p)
 		free(p->user_val_to_struct);
 	if (p->type_val_to_struct)
 		free(p->type_val_to_struct);
-	free(p->decl_val_to_struct);
-
-	for (i = 0; i < SYM_NUM; i++) {
-		hashtab_map(p->scope[i].table, scope_destroy, 0);
-		hashtab_destroy(p->scope[i].table);
-	}
-	avrule_block_list_destroy(p->global);
-	free(p->name);
-	free(p->version);
 
 	avtab_destroy(&p->te_avtab);
 
@@ -1085,18 +830,6 @@ void symtabs_destroy(symtab_t * symtab)
 	}
 }
 
-int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
-		  __attribute__ ((unused)))
-{
-	scope_datum_t *cur = (scope_datum_t *) datum;
-	free(key);
-	if (cur != NULL) {
-		free(cur->decl_ids);
-	}
-	free(cur);
-	return 0;
-}
-
 hashtab_destroy_func_t get_symtab_destroy_func(int sym_num)
 {
 	if (sym_num < 0 || sym_num >= SYM_NUM) {
@@ -1134,16 +867,13 @@ int policydb_load_isids(policydb_t * p, 
 }
 
 /* Declare a symbol for a certain avrule_block context.  Insert it
- * into a symbol table for a policy.  This function will handle
- * inserting the appropriate scope information in addition to
- * inserting the symbol into the hash table.
- *
+ * into a symbol table for a policy.
+ * 
  * arguments:
- *   policydb_t *pol       module policy to modify
+ *   policydb_t *pol       policy to modify
  *   uint32_t sym          the symbole table for insertion (SYM_*)
  *   hashtab_key_t key     the key for the symbol - not cloned
  *   hashtab_datum_t data  the data for the symbol - not cloned
- *   scope                 scope of this symbol, either SCOPE_REQ or SCOPE_DECL
  *   avrule_decl_id        identifier for this symbol's encapsulating declaration
  *   value (out)           assigned value to the symbol (if value is not NULL)
  *
@@ -1152,17 +882,14 @@ int policydb_load_isids(policydb_t * p, 
  *   1                     success, but symbol already existed as a requirement
  *                         (datum was not inserted and needs to be free()d)
  *   -1                    general error
- *   -2                    scope conflicted
  *   -ENOMEM               memory error
  *   error codes from hashtab_insert
  */
 int symtab_insert(policydb_t * pol, uint32_t sym,
 		  hashtab_key_t key, hashtab_datum_t datum,
-		  uint32_t scope, uint32_t avrule_decl_id, uint32_t * value)
+		  uint32_t avrule_decl_id __attribute__((unused)), uint32_t * value)
 {
 	int rc, retval = 0;
-	unsigned int i;
-	scope_datum_t *scope_datum;
 
 	/* check if the symbol is already there.  multiple
 	 * declarations of non-roles/non-users are illegal, but
@@ -1176,174 +903,16 @@ int symtab_insert(policydb_t * pol, uint
 		 * (i.e. aliases) */
 		if (value)
 			*value = ++pol->symtab[sym].nprim;
-	} else if (rc == SEPOL_EEXIST && scope == SCOPE_REQ) {
-		retval = 1;	/* symbol not added -- need to free() later */
-	} else if (rc == SEPOL_EEXIST && scope == SCOPE_DECL) {
-		if (sym == SYM_ROLES || sym == SYM_USERS) {
-			/* allow multiple declarations for these two */
-			retval = 1;
-		} else {
-			/* duplicate declarations not allowed for all else */
-			return -2;
-		}
 	} else {
 		return rc;
 	}
 
-	/* get existing scope information; if there is not one then
-	 * create it */
-	scope_datum =
-	    (scope_datum_t *) hashtab_search(pol->scope[sym].table, key);
-	if (scope_datum == NULL) {
-		hashtab_key_t key2 = strdup((char *)key);
-		if (!key2)
-			return -ENOMEM;
-		if ((scope_datum = malloc(sizeof(*scope_datum))) == NULL) {
-			free(key2);
-			return -ENOMEM;
-		}
-		scope_datum->scope = scope;
-		scope_datum->decl_ids = NULL;
-		scope_datum->decl_ids_len = 0;
-		if ((rc =
-		     hashtab_insert(pol->scope[sym].table, key2,
-				    scope_datum)) != 0) {
-			free(key2);
-			free(scope_datum);
-			return rc;
-		}
-	} else if (scope_datum->scope == SCOPE_DECL) {
-		/* disallow multiple declarations for non-roles/users */
-		if (sym != SYM_ROLES && sym != SYM_USERS) {
-			return -2;
-		}
-	} else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) {
-		/* appending to required symbol only allowed for roles/users */
-		if (sym == SYM_ROLES || sym == SYM_USERS) {
-			scope_datum->scope = SCOPE_DECL;
-		} else {
-			return -2;
-		}
-
-	} else if (scope_datum->scope != scope) {
-		/* scope does not match */
-		return -2;
-	}
-
-	/* search through the pre-existing list to avoid adding duplicates */
-	for (i = 0; i < scope_datum->decl_ids_len; i++) {
-		if (scope_datum->decl_ids[i] == avrule_decl_id) {
-			/* already there, so don't modify its scope */
-			return retval;
-		}
-	}
-
-	if (add_i_to_a(avrule_decl_id,
-		       &scope_datum->decl_ids_len,
-		       &scope_datum->decl_ids) == -1) {
-		return -ENOMEM;
-	}
-
 	return retval;
 }
 
-int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b)
-{
-	type_set_init(dst);
-
-	if (ebitmap_or(&dst->types, &a->types, &b->types)) {
-		return -1;
-	}
-	if (ebitmap_or(&dst->negset, &a->negset, &b->negset)) {
-		return -1;
-	}
-
-	dst->flags |= a->flags;
-	dst->flags |= b->flags;
-
-	return 0;
-}
-
-int type_set_cpy(type_set_t * dst, type_set_t * src)
-{
-	type_set_init(dst);
-
-	dst->flags = src->flags;
-	if (ebitmap_cpy(&dst->types, &src->types))
-		return -1;
-	if (ebitmap_cpy(&dst->negset, &src->negset))
-		return -1;
-
-	return 0;
-}
-
-int type_set_or_eq(type_set_t * dst, type_set_t * other)
-{
-	int ret;
-	type_set_t tmp;
-
-	if (type_set_or(&tmp, dst, other))
-		return -1;
-	type_set_destroy(dst);
-	ret = type_set_cpy(dst, &tmp);
-	type_set_destroy(&tmp);
-
-	return ret;
-}
-
-int role_set_get_role(role_set_t * x, uint32_t role)
-{
-	if (x->flags & ROLE_STAR)
-		return 1;
-
-	if (ebitmap_get_bit(&x->roles, role - 1)) {
-		if (x->flags & ROLE_COMP)
-			return 0;
-		else
-			return 1;
-	} else {
-		if (x->flags & ROLE_COMP)
-			return 1;
-		else
-			return 0;
-	}
-}
-
 /***********************************************************************/
 /* everything below is for policy reads */
 
-/* The following are read functions for module structures */
-
-static int role_set_read(role_set_t * r, struct policy_file *fp)
-{
-	uint32_t *buf;
-	if (ebitmap_read(&r->roles, fp))
-		return -1;
-	buf = next_entry(fp, sizeof(uint32_t));
-	if (!buf)
-		return -1;
-	r->flags = le32_to_cpu(buf[0]);
-
-	return 0;
-}
-
-static int type_set_read(type_set_t * t, struct policy_file *fp)
-{
-	uint32_t *buf;
-
-	if (ebitmap_read(&t->types, fp))
-		return -1;
-	if (ebitmap_read(&t->negset, fp))
-		return -1;
-
-	buf = next_entry(fp, sizeof(uint32_t));
-	if (!buf)
-		return -1;
-	t->flags = le32_to_cpu(buf[0]);
-
-	return 0;
-}
-
 /*
  * Read a MLS range structure from a policydb binary 
  * representation file.
@@ -1397,155 +966,43 @@ static int mls_read_range_helper(mls_ran
 }
 
 /*
- * Read a semantic MLS level structure from a policydb binary 
- * representation file.
+ * Read and validate a security context structure
+ * from a policydb binary representation file.
  */
-static int mls_read_semantic_level_helper(mls_semantic_level_t * l,
-					  struct policy_file *fp)
+static int context_read_and_validate(context_struct_t * c,
+				     policydb_t * p, struct policy_file *fp)
 {
-	uint32_t *buf, ncat;
-	unsigned int i;
-	mls_semantic_cat_t *cat;
-
-	mls_semantic_level_init(l);
+	uint32_t *buf;
 
-	buf = next_entry(fp, sizeof(uint32_t) * 2);
+	buf = next_entry(fp, sizeof(uint32_t) * 3);
 	if (!buf) {
-		ERR(fp->handle, "truncated level");
-		goto bad;
+		ERR(fp->handle, "context truncated");
+		return -1;
 	}
-	l->sens = le32_to_cpu(buf[0]);
-
-	ncat = le32_to_cpu(buf[1]);
-	for (i = 0; i < ncat; i++) {
-		cat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
-		if (!cat) {
-			ERR(fp->handle, "out of memory");
-			goto bad;
-		}
-
-		mls_semantic_cat_init(cat);
-		cat->next = l->cat;
-		l->cat = cat;
-
-		buf = next_entry(fp, sizeof(uint32_t) * 2);
-		if (!buf) {
-			ERR(fp->handle, "error reading level categories");
-			goto bad;
+	c->user = le32_to_cpu(buf[0]);
+	c->role = le32_to_cpu(buf[1]);
+	c->type = le32_to_cpu(buf[2]);
+	if ((p->policyvers >= POLICYDB_VERSION_MLS)
+	    ) {
+		if (mls_read_range_helper(&c->range, fp)) {
+			ERR(fp->handle, "error reading MLS range "
+			    "of context");
+			return -1;
 		}
-		cat->low = le32_to_cpu(buf[0]);
-		cat->high = le32_to_cpu(buf[1]);
 	}
 
+	if (!policydb_context_isvalid(p, c)) {
+		ERR(fp->handle, "invalid security context");
+		context_destroy(c);
+		return -1;
+	}
 	return 0;
-
-      bad:
-	return -EINVAL;
 }
 
 /*
- * Read a semantic MLS range structure from a policydb binary 
- * representation file.
- */
-static int mls_read_semantic_range_helper(mls_semantic_range_t * r,
-					  struct policy_file *fp)
-{
-	int rc;
-
-	rc = mls_read_semantic_level_helper(&r->level[0], fp);
-	if (rc)
-		return rc;
-
-	rc = mls_read_semantic_level_helper(&r->level[1], fp);
-
-	return rc;
-}
-
-static int mls_level_to_semantic(mls_level_t * l, mls_semantic_level_t * sl)
-{
-	unsigned int i;
-	ebitmap_node_t *cnode;
-	mls_semantic_cat_t *open_cat = NULL;
-
-	mls_semantic_level_init(sl);
-	sl->sens = l->sens;
-	ebitmap_for_each_bit(&l->cat, cnode, i) {
-		if (ebitmap_node_get_bit(cnode, i)) {
-			if (open_cat)
-				continue;
-			open_cat = (mls_semantic_cat_t *)
-			    malloc(sizeof(mls_semantic_cat_t));
-			if (!open_cat)
-				return -1;
-
-			mls_semantic_cat_init(open_cat);
-			open_cat->low = i + 1;
-			open_cat->next = sl->cat;
-			sl->cat = open_cat;
-		} else {
-			if (!open_cat)
-				continue;
-			open_cat->high = i;
-			open_cat = NULL;
-		}
-	}
-	if (open_cat)
-		open_cat->high = i;
-
-	return 0;
-}
-
-static int mls_range_to_semantic(mls_range_t * r, mls_semantic_range_t * sr)
-{
-	if (mls_level_to_semantic(&r->level[0], &sr->level[0]))
-		return -1;
-
-	if (mls_level_to_semantic(&r->level[1], &sr->level[1]))
-		return -1;
-
-	return 0;
-}
-
-/*
- * Read and validate a security context structure
- * from a policydb binary representation file.
- */
-static int context_read_and_validate(context_struct_t * c,
-				     policydb_t * p, struct policy_file *fp)
-{
-	uint32_t *buf;
-
-	buf = next_entry(fp, sizeof(uint32_t) * 3);
-	if (!buf) {
-		ERR(fp->handle, "context truncated");
-		return -1;
-	}
-	c->user = le32_to_cpu(buf[0]);
-	c->role = le32_to_cpu(buf[1]);
-	c->type = le32_to_cpu(buf[2]);
-	if ((p->policy_type == POLICY_KERN
-	     && p->policyvers >= POLICYDB_VERSION_MLS)
-	    || (p->policy_type == POLICY_BASE
-		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS)) {
-		if (mls_read_range_helper(&c->range, fp)) {
-			ERR(fp->handle, "error reading MLS range "
-			    "of context");
-			return -1;
-		}
-	}
-
-	if (!policydb_context_isvalid(p, c)) {
-		ERR(fp->handle, "invalid security context");
-		context_destroy(c);
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * The following *_read functions are used to
- * read the symbol data from a policy database
- * binary representation file.
+ * The following *_read functions are used to
+ * read the symbol data from a policy database
+ * binary representation file.
  */
 
 static int perm_read(policydb_t * p
@@ -1635,7 +1092,8 @@ static int common_read(policydb_t * p, h
 	return -1;
 }
 
-static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep,
+static int read_cons_helper(policydb_t * p __attribute__ ((unused)),
+			    constraint_node_t ** nodep,
 			    unsigned int ncons,
 			    int allowxtarget, struct policy_file *fp)
 {
@@ -1709,9 +1167,6 @@ static int read_cons_helper(policydb_t *
 				depth++;
 				if (ebitmap_read(&e->names, fp))
 					return -1;
-				if (p->policy_type != POLICY_KERN &&
-				    type_set_read(e->type_names, fp))
-					return -1;
 				break;
 			default:
 				return -1;
@@ -1787,10 +1242,8 @@ static int class_read(policydb_t * p, ha
 	if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp))
 		goto bad;
 
-	if ((p->policy_type == POLICY_KERN
-	     && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
-	    || (p->policy_type == POLICY_BASE
-		&& p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) {
+	if ((p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
+	    ) {
 		/* grab the validatetrans rules */
 		buf = next_entry(fp, sizeof(uint32_t));
 		if (!buf)
@@ -1842,13 +1295,8 @@ static int role_read(policydb_t * p
 	if (ebitmap_read(&role->dominates, fp))
 		goto bad;
 
-	if (p->policy_type == POLICY_KERN) {
-		if (ebitmap_read(&role->types.types, fp))
-			goto bad;
-	} else {
-		if (type_set_read(&role->types, fp))
-			goto bad;
-	}
+	if (ebitmap_read(&role->types, fp))
+		goto bad;
 
 	if (strcmp(key, OBJECT_R) == 0) {
 		if (role->s.value != OBJECT_R_VAL) {
@@ -1884,22 +1332,13 @@ static int type_read(policydb_t * p
 	if (!typdatum)
 		return -1;
 
-	if (p->policy_type == POLICY_KERN) {
-		buf = next_entry(fp, sizeof(uint32_t) * 3);
-	} else {
-		buf = next_entry(fp, sizeof(uint32_t) * 4);
-	}
+	buf = next_entry(fp, sizeof(uint32_t) * 3);
 	if (!buf)
 		goto bad;
 
 	len = le32_to_cpu(buf[0]);
 	typdatum->s.value = le32_to_cpu(buf[1]);
 	typdatum->primary = le32_to_cpu(buf[2]);
-	if (p->policy_type != POLICY_KERN) {
-		typdatum->flavor = le32_to_cpu(buf[3]);
-		if (ebitmap_read(&typdatum->types, fp))
-			goto bad;
-	}
 
 	buf = next_entry(fp, len);
 	if (!buf)
@@ -2274,46 +1713,15 @@ static int user_read(policydb_t * p, has
 	memcpy(key, buf, len);
 	key[len] = 0;
 
-	if (p->policy_type == POLICY_KERN) {
-		if (ebitmap_read(&usrdatum->roles.roles, fp))
-			goto bad;
-	} else {
-		if (role_set_read(&usrdatum->roles, fp))
-			goto bad;
-	}
+	if (ebitmap_read(&usrdatum->roles, fp))
+		goto bad;
 
-	/* users were not allowed in mls modules before version
-	 * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been
-	 * required - the mls fields will be empty.  user declarations in
-	 * non-mls modules will also have empty mls fields */
-	if ((p->policy_type == POLICY_KERN
-	     && p->policyvers >= POLICYDB_VERSION_MLS)
-	    || (p->policy_type == POLICY_MOD
-		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
-		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)
-	    || (p->policy_type == POLICY_BASE
-		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
-		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)) {
+	if ((p->policyvers >= POLICYDB_VERSION_MLS)
+	    ) {
 		if (mls_read_range_helper(&usrdatum->exp_range, fp))
 			goto bad;
 		if (mls_read_level(&usrdatum->exp_dfltlevel, fp))
 			goto bad;
-		if (p->policy_type != POLICY_KERN) {
-			if (mls_range_to_semantic(&usrdatum->exp_range,
-						  &usrdatum->range))
-				goto bad;
-			if (mls_level_to_semantic(&usrdatum->exp_dfltlevel,
-						  &usrdatum->dfltlevel))
-				goto bad;
-		}
-	} else if ((p->policy_type == POLICY_MOD
-		    && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)
-		   || (p->policy_type == POLICY_BASE
-		       && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)) {
-		if (mls_read_semantic_range_helper(&usrdatum->range, fp))
-			goto bad;
-		if (mls_read_semantic_level_helper(&usrdatum->dfltlevel, fp))
-			goto bad;
 	}
 
 	if (hashtab_insert(h, key, usrdatum))
@@ -2414,80 +1822,12 @@ static int (*read_f[SYM_NUM]) (policydb_
 common_read, class_read, role_read, type_read, user_read,
 	    cond_read_bool, sens_read, cat_read,};
 
-/************** module reading functions below **************/
-
-static avrule_t *avrule_read(policydb_t * p
-			     __attribute__ ((unused)), struct policy_file *fp)
-{
-	unsigned int i;
-	uint32_t *buf, len;
-	class_perm_node_t *cur, *tail = NULL;
-	avrule_t *avrule;
-
-	avrule = (avrule_t *) malloc(sizeof(avrule_t));
-	if (!avrule)
-		return NULL;
-
-	avrule_init(avrule);
-
-	buf = next_entry(fp, sizeof(uint32_t) * 2);
-	if (!buf)
-		goto bad;
-
-	(avrule)->specified = le32_to_cpu(buf[0]);
-	(avrule)->flags = le32_to_cpu(buf[1]);
-
-	if (type_set_read(&avrule->stypes, fp))
-		goto bad;
-
-	if (type_set_read(&avrule->ttypes, fp))
-		goto bad;
-
-	buf = next_entry(fp, sizeof(uint32_t));
-	if (!buf)
-		goto bad;
-	len = le32_to_cpu(buf[0]);
-
-	for (i = 0; i < len; i++) {
-		cur = (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
-		if (!cur)
-			goto bad;
-		class_perm_node_init(cur);
-
-		buf = next_entry(fp, sizeof(uint32_t) * 2);
-		if (!buf) {
-			free(cur);
-			goto bad;
-		}
-
-		cur->class = le32_to_cpu(buf[0]);
-		cur->data = le32_to_cpu(buf[1]);
-
-		if (!tail) {
-			avrule->perms = cur;
-		} else {
-			tail->next = cur;
-		}
-		tail = cur;
-	}
-
-	return avrule;
-      bad:
-	if (avrule) {
-		avrule_destroy(avrule);
-		free(avrule);
-	}
-	return NULL;
-}
-
 static int range_read(policydb_t * p, struct policy_file *fp)
 {
 	uint32_t *buf, nel;
 	range_trans_t *rt, *lrt;
-	range_trans_rule_t *rtr, *lrtr = NULL;
 	unsigned int i;
-	int new_rangetr = (p->policy_type == POLICY_KERN &&
-			   p->policyvers >= POLICYDB_VERSION_RANGETRANS);
+	int new_rangetr = (p->policyvers >= POLICYDB_VERSION_RANGETRANS);
 
 	buf = next_entry(fp, sizeof(uint32_t));
 	if (!buf)
@@ -2519,417 +1859,9 @@ static int range_read(policydb_t * p, st
 		lrt = rt;
 	}
 
-	/* if this is a kernel policy, we are done - otherwise we need to
-	 * convert these structs to range_trans_rule_ts */
-	if (p->policy_type == POLICY_KERN)
-		return 0;
-
-	/* create range_trans_rules_ts that correspond to the range_trans_ts
-	 * that were just read in from an older policy */
-	for (rt = p->range_tr; rt; rt = rt->next) {
-		rtr = malloc(sizeof(range_trans_rule_t));
-		if (!rtr) {
-			return -1;
-		}
-		range_trans_rule_init(rtr);
-
-		if (lrtr)
-			lrtr->next = rtr;
-		else
-			p->global->enabled->range_tr_rules = rtr;
-
-		if (ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1))
-			return -1;
-
-		if (ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1))
-			return -1;
-
-		if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1))
-			return -1;
-
-		if (mls_range_to_semantic(&rt->target_range, &rtr->trange))
-			return -1;
-
-		lrtr = rtr;
-	}
-
-	/* now destroy the range_trans_ts */
-	lrt = NULL;
-	for (rt = p->range_tr; rt; rt = rt->next) {
-		if (lrt) {
-			ebitmap_destroy(&lrt->target_range.level[0].cat);
-			ebitmap_destroy(&lrt->target_range.level[1].cat);
-			free(lrt);
-		}
-		lrt = rt;
-	}
-	if (lrt) {
-		ebitmap_destroy(&lrt->target_range.level[0].cat);
-		ebitmap_destroy(&lrt->target_range.level[1].cat);
-		free(lrt);
-	}
-	p->range_tr = NULL;
-
-	return 0;
-}
-
-int avrule_read_list(policydb_t * p, avrule_t ** avrules,
-		     struct policy_file *fp)
-{
-	unsigned int i;
-	avrule_t *cur, *tail;
-	uint32_t *buf, len;
-
-	*avrules = tail = NULL;
-
-	buf = next_entry(fp, sizeof(uint32_t));
-	if (!buf) {
-		return -1;
-	}
-	len = le32_to_cpu(buf[0]);
-
-	for (i = 0; i < len; i++) {
-		cur = avrule_read(p, fp);
-		if (!cur) {
-			return -1;
-		}
-
-		if (!tail) {
-			*avrules = cur;
-		} else {
-			tail->next = cur;
-		}
-		tail = cur;
-	}
-
-	return 0;
-}
-
-static int role_trans_rule_read(role_trans_rule_t ** r, struct policy_file *fp)
-{
-	uint32_t *buf, nel;
-	unsigned int i;
-	role_trans_rule_t *tr, *ltr;
-
-	buf = next_entry(fp, sizeof(uint32_t));
-	if (!buf)
-		return -1;
-	nel = le32_to_cpu(buf[0]);
-	ltr = NULL;
-	for (i = 0; i < nel; i++) {
-		tr = malloc(sizeof(role_trans_rule_t));
-		if (!tr) {
-			return -1;
-		}
-		role_trans_rule_init(tr);
-
-		if (ltr) {
-			ltr->next = tr;
-		} else {
-			*r = tr;
-		}
-
-		if (role_set_read(&tr->roles, fp))
-			return -1;
-
-		if (type_set_read(&tr->types, fp))
-			return -1;
-
-		buf = next_entry(fp, sizeof(uint32_t));
-		if (!buf)
-			return -1;
-		tr->new_role = le32_to_cpu(buf[0]);
-		ltr = tr;
-	}
-
 	return 0;
 }
 
-static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp)
-{
-	unsigned int i;
-	uint32_t *buf, nel;
-	role_allow_rule_t *ra, *lra;
-
-	buf = next_entry(fp, sizeof(uint32_t));
-	if (!buf)
-		return -1;
-	nel = le32_to_cpu(buf[0]);
-	lra = NULL;
-	for (i = 0; i < nel; i++) {
-		ra = malloc(sizeof(role_allow_rule_t));
-		if (!ra) {
-			return -1;
-		}
-		role_allow_rule_init(ra);
-
-		if (lra) {
-			lra->next = ra;
-		} else {
-			*r = ra;
-		}
-
-		if (role_set_read(&ra->roles, fp))
-			return -1;
-
-		if (role_set_read(&ra->new_roles, fp))
-			return -1;
-
-		lra = ra;
-	}
-	return 0;
-}
-
-static int range_trans_rule_read(range_trans_rule_t ** r,
-				 struct policy_file *fp)
-{
-	uint32_t *buf, nel;
-	unsigned int i;
-	range_trans_rule_t *rt, *lrt = NULL;
-
-	buf = next_entry(fp, sizeof(uint32_t));
-	if (!buf)
-		return -1;
-	nel = le32_to_cpu(buf[0]);
-	for (i = 0; i < nel; i++) {
-		rt = malloc(sizeof(range_trans_rule_t));
-		if (!rt) {
-			return -1;
-		}
-		range_trans_rule_init(rt);
-
-		if (lrt)
-			lrt->next = rt;
-		else
-			*r = rt;
-
-		if (type_set_read(&rt->stypes, fp))
-			return -1;
-
-		if (type_set_read(&rt->ttypes, fp))
-			return -1;
-
-		if (ebitmap_read(&rt->tclasses, fp))
-			return -1;
-
-		if (mls_read_semantic_range_helper(&rt->trange, fp))
-			return -1;
-
-		lrt = rt;
-	}
-
-	return 0;
-}
-
-static int scope_index_read(scope_index_t * scope_index,
-			    unsigned int num_scope_syms, struct policy_file *fp)
-{
-	unsigned int i;
-	uint32_t *buf;
-	for (i = 0; i < num_scope_syms; i++) {
-		if (ebitmap_read(scope_index->scope + i, fp) == -1) {
-			return -1;
-		}
-	}
-	if ((buf = next_entry(fp, sizeof(uint32_t))) == NULL) {
-		return -1;
-	}
-	scope_index->class_perms_len = le32_to_cpu(buf[0]);
-	if (scope_index->class_perms_len == 0) {
-		scope_index->class_perms_map = NULL;
-		return 0;
-	}
-	if ((scope_index->class_perms_map =
-	     calloc(scope_index->class_perms_len,
-		    sizeof(*scope_index->class_perms_map))) == NULL) {
-		return -1;
-	}
-	for (i = 0; i < scope_index->class_perms_len; i++) {
-		if (ebitmap_read(scope_index->class_perms_map + i, fp) == -1) {
-			return -1;
-		}
-	}
-	return 0;
-}
-
-static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl,
-			    unsigned int num_scope_syms, struct policy_file *fp)
-{
-	uint32_t *buf, nprim, nel;
-	unsigned int i, j;
-	if ((buf = next_entry(fp, sizeof(uint32_t) * 2)) == NULL) {
-		return -1;
-	}
-	decl->decl_id = le32_to_cpu(buf[0]);
-	decl->enabled = le32_to_cpu(buf[1]);
-	if (cond_read_list(p, &decl->cond_list, fp) == -1 ||
-	    avrule_read_list(p, &decl->avrules, fp) == -1 ||
-	    role_trans_rule_read(&decl->role_tr_rules, fp) == -1 ||
-	    role_allow_rule_read(&decl->role_allow_rules, fp) == -1) {
-		return -1;
-	}
-	if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
-	    range_trans_rule_read(&decl->range_tr_rules, fp) == -1) {
-		return -1;
-	}
-	if (scope_index_read(&decl->required, num_scope_syms, fp) == -1 ||
-	    scope_index_read(&decl->declared, num_scope_syms, fp) == -1) {
-		return -1;
-	}
-
-	for (i = 0; i < num_scope_syms; i++) {
-		if ((buf = next_entry(fp, sizeof(uint32_t) * 2)) == NULL) {
-			return -1;
-		}
-		nprim = le32_to_cpu(buf[0]);
-		nel = le32_to_cpu(buf[1]);
-		for (j = 0; j < nel; j++) {
-			if (read_f[i] (p, decl->symtab[i].table, fp)) {
-				return -1;
-			}
-		}
-		decl->symtab[i].nprim = nprim;
-	}
-	return 0;
-}
-
-static int avrule_block_read(policydb_t * p,
-			     avrule_block_t ** block,
-			     unsigned int num_scope_syms,
-			     struct policy_file *fp)
-{
-	avrule_block_t *last_block = NULL, *curblock;
-	uint32_t *buf, num_blocks, nel;
-
-	if ((buf = next_entry(fp, sizeof(uint32_t))) == NULL) {
-		return -1;
-	}
-	num_blocks = le32_to_cpu(buf[0]);
-	nel = num_blocks;
-	while (num_blocks > 0) {
-		avrule_decl_t *last_decl = NULL, *curdecl;
-		uint32_t num_decls;
-		if ((curblock = calloc(1, sizeof(*curblock))) == NULL) {
-			return -1;
-		}
-
-		if ((buf = next_entry(fp, sizeof(uint32_t))) == NULL) {
-			free(curblock);
-			return -1;
-		}
-		/* if this is the first block its non-optional, else its optional */
-		if (num_blocks != nel)
-			curblock->flags |= AVRULE_OPTIONAL;
-
-		num_decls = le32_to_cpu(buf[0]);
-		while (num_decls > 0) {
-			if ((curdecl = avrule_decl_create(0)) == NULL) {
-				avrule_block_destroy(curblock);
-				return -1;
-			}
-			if (avrule_decl_read(p, curdecl, num_scope_syms, fp) ==
-			    -1) {
-				avrule_decl_destroy(curdecl);
-				avrule_block_destroy(curblock);
-				return -1;
-			}
-			if (curdecl->enabled) {
-				if (curblock->enabled != NULL) {
-					/* probably a corrupt file */
-					avrule_decl_destroy(curdecl);
-					avrule_block_destroy(curblock);
-					return -1;
-				}
-				curblock->enabled = curdecl;
-			}
-			/* one must be careful to reconstruct the
-			 * decl chain in its correct order */
-			if (curblock->branch_list == NULL) {
-				curblock->branch_list = curdecl;
-			} else {
-				last_decl->next = curdecl;
-			}
-			last_decl = curdecl;
-			num_decls--;
-		}
-
-		if (*block == NULL) {
-			*block = curblock;
-		} else {
-			last_block->next = curblock;
-		}
-		last_block = curblock;
-
-		num_blocks--;
-	}
-
-	return 0;
-}
-
-static int scope_read(policydb_t * p, int symnum, struct policy_file *fp)
-{
-	scope_datum_t *scope = NULL;
-	uint32_t *buf;
-	char *key = NULL;
-	size_t key_len;
-	unsigned int i;
-	hashtab_t h = p->scope[symnum].table;
-
-	if ((buf = next_entry(fp, sizeof(uint32_t))) == NULL) {
-		goto cleanup;
-	}
-	key_len = le32_to_cpu(buf[0]);
-	if ((buf = next_entry(fp, key_len)) == NULL) {
-		goto cleanup;
-	}
-	if ((key = malloc(key_len + 1)) == NULL) {
-		goto cleanup;
-	}
-	memcpy(key, buf, key_len);
-	key[key_len] = '\0';
-
-	/* ensure that there already exists a symbol with this key */
-	if (hashtab_search(p->symtab[symnum].table, key) == NULL) {
-		goto cleanup;
-	}
-
-	if ((scope = calloc(1, sizeof(*scope))) == NULL) {
-		goto cleanup;
-	}
-	if ((buf = next_entry(fp, sizeof(uint32_t) * 2)) == NULL) {
-		goto cleanup;
-	}
-	scope->scope = le32_to_cpu(buf[0]);
-	scope->decl_ids_len = le32_to_cpu(buf[1]);
-	assert(scope->decl_ids_len > 0);
-	if ((scope->decl_ids =
-	     malloc(scope->decl_ids_len * sizeof(uint32_t))) == NULL) {
-		goto cleanup;
-	}
-	if ((buf =
-	     next_entry(fp, sizeof(uint32_t) * scope->decl_ids_len)) == NULL) {
-		goto cleanup;
-	}
-	for (i = 0; i < scope->decl_ids_len; i++) {
-		scope->decl_ids[i] = le32_to_cpu(buf[i]);
-	}
-
-	if (strcmp(key, "object_r") == 0 && h == p->p_roles_scope.table) {
-		/* object_r was already added to this table in roles_init() */
-		scope_destroy(key, scope, NULL);
-	} else {
-		if (hashtab_insert(h, key, scope)) {
-			goto cleanup;
-		}
-	}
-
-	return 0;
-
-      cleanup:
-	scope_destroy(key, scope, NULL);
-	return -1;
-}
-
 /*
  * Read the configuration data from a policy database binary
  * representation file into a policy database structure.
@@ -2942,7 +1874,7 @@ int policydb_read(policydb_t * p, struct
 	size_t len, nprim, nel;
 	char *policydb_str, *target_str = NULL;
 	struct policydb_compat_info *info;
-	unsigned int policy_type, bufindex;
+	unsigned int bufindex;
 	ebitmap_node_t *tnode;
 
 	config = 0;
@@ -2955,15 +1887,11 @@ int policydb_read(policydb_t * p, struct
 		buf[i] = le32_to_cpu(buf[i]);
 
 	if (buf[0] == POLICYDB_MAGIC) {
-		policy_type = POLICY_KERN;
 		target_str = POLICYDB_STRING;
-	} else if (buf[0] == POLICYDB_MOD_MAGIC) {
-		policy_type = POLICY_MOD;
-		target_str = POLICYDB_MOD_STRING;
 	} else {
 		ERR(fp->handle, "policydb magic number %#08x does not "
-		    "match expected magic number %#08x or %#08x",
-		    buf[0], POLICYDB_MAGIC, POLICYDB_MOD_MAGIC);
+		    "match expected magic number %#08x",
+		    buf[0], POLICYDB_MAGIC);
 		return POLICYDB_ERROR;
 	}
 
@@ -2997,11 +1925,8 @@ int policydb_read(policydb_t * p, struct
 	free(policydb_str);
 	policydb_str = NULL;
 
-	/* Read the version, config, and table sizes (and policy type if it's a module). */
-	if (policy_type == POLICY_KERN)
-		nel = 4;
-	else
-		nel = 5;
+	/* Read the version, config, and table sizes. */
+	nel = 4;
 
 	buf = next_entry(fp, sizeof(uint32_t) * nel);
 	if (!buf)
@@ -3011,44 +1936,17 @@ int policydb_read(policydb_t * p, struct
 
 	bufindex = 0;
 
-	if (policy_type == POLICY_MOD) {
-		/* We know it's a module but not whether it's a base
-		   module or regular binary policy module.  buf[0]
-		   tells us which. */
-		policy_type = buf[bufindex];
-		if (policy_type != POLICY_MOD && policy_type != POLICY_BASE) {
-			ERR(fp->handle, "unknown module type: %#08x",
-			    policy_type);
-			return POLICYDB_ERROR;
-		}
-		bufindex++;
-	}
-
 	r_policyvers = buf[bufindex];
-	if (policy_type == POLICY_KERN) {
-		if (r_policyvers < POLICYDB_VERSION_MIN ||
-		    r_policyvers > POLICYDB_VERSION_MAX) {
-			ERR(fp->handle, "policydb version %d does not match "
-			    "my version range %d-%d", buf[bufindex],
-			    POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
-			return POLICYDB_ERROR;
-		}
-	} else if (policy_type == POLICY_BASE || policy_type == POLICY_MOD) {
-		if (r_policyvers < MOD_POLICYDB_VERSION_MIN ||
-		    r_policyvers > MOD_POLICYDB_VERSION_MAX) {
-			ERR(fp->handle, "policydb module version %d does "
-			    "not match my version range %d-%d",
-			    buf[bufindex], MOD_POLICYDB_VERSION_MIN,
-			    MOD_POLICYDB_VERSION_MAX);
-			return POLICYDB_ERROR;
-		}
-	} else {
-		assert(0);
+	if (r_policyvers < POLICYDB_VERSION_MIN ||
+	    r_policyvers > POLICYDB_VERSION_MAX) {
+		ERR(fp->handle, "policydb version %d does not match "
+		    "my version range %d-%d", buf[bufindex],
+		    POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
+		return POLICYDB_ERROR;
 	}
 	bufindex++;
 
 	/* Set the policy type and version from the read values. */
-	p->policy_type = policy_type;
 	p->policyvers = r_policyvers;
 
 	if (buf[bufindex] & POLICYDB_CONFIG_MLS) {
@@ -3059,7 +1957,7 @@ int policydb_read(policydb_t * p, struct
 
 	bufindex++;
 
-	info = policydb_lookup_compat(r_policyvers, policy_type);
+	info = policydb_lookup_compat(r_policyvers);
 	if (!info) {
 		ERR(fp->handle, "unable to find policy compat info "
 		    "for version %d", r_policyvers);
@@ -3075,79 +1973,31 @@ int policydb_read(policydb_t * p, struct
 		goto bad;
 	}
 
-	if (p->policy_type == POLICY_MOD) {
-		/* Get the module name and version */
-		if ((buf = next_entry(fp, sizeof(uint32_t))) == NULL) {
-			goto bad;
-		}
-		len = le32_to_cpu(buf[0]);
-		if ((buf = next_entry(fp, len)) == NULL) {
-			goto bad;
-		}
-		if ((p->name = malloc(len + 1)) == NULL) {
-			goto bad;
-		}
-		memcpy(p->name, buf, len);
-		p->name[len] = '\0';
-		if ((buf = next_entry(fp, sizeof(uint32_t))) == NULL) {
-			goto bad;
-		}
-		len = le32_to_cpu(buf[0]);
-		if ((buf = next_entry(fp, len)) == NULL) {
-			goto bad;
-		}
-		if ((p->version = malloc(len + 1)) == NULL) {
-			goto bad;
-		}
-		memcpy(p->version, buf, len);
-		p->version[len] = '\0';
-	}
-
 	for (i = 0; i < info->sym_num; i++) {
 		buf = next_entry(fp, sizeof(uint32_t) * 2);
-		if (!buf)
+		if (!buf){
 			goto bad;
+		}
 		nprim = le32_to_cpu(buf[0]);
 		nel = le32_to_cpu(buf[1]);
 		for (j = 0; j < nel; j++) {
-			if (read_f[i] (p, p->symtab[i].table, fp))
+			if (read_f[i] (p, p->symtab[i].table, fp)){
+				fprintf(stderr,"i = %d\tj = %d\n", i, j);
 				goto bad;
+			}
 		}
 
 		p->symtab[i].nprim = nprim;
 	}
 
-	if (policy_type == POLICY_KERN) {
-		if (avtab_read(&p->te_avtab, fp, r_policyvers))
-			goto bad;
-		if (r_policyvers >= POLICYDB_VERSION_BOOL)
-			if (cond_read_list(p, &p->cond_list, fp))
-				goto bad;
-		if (role_trans_read(&p->role_tr, fp))
-			goto bad;
-		if (role_allow_read(&p->role_allow, fp))
-			goto bad;
-	} else {
-		/* first read the AV rule blocks, then the scope tables */
-		avrule_block_destroy(p->global);
-		p->global = NULL;
-		if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) {
+	if (avtab_read(&p->te_avtab, fp, r_policyvers))
+		goto bad;
+	if (r_policyvers >= POLICYDB_VERSION_BOOL)
+		if (cond_read_list(p, &p->cond_list, fp))
 			goto bad;
-		}
-		for (i = 0; i < info->sym_num; i++) {
-			if ((buf = next_entry(fp, sizeof(uint32_t))) == NULL) {
-				goto bad;
-			}
-			nel = le32_to_cpu(buf[0]);
-			for (j = 0; j < nel; j++) {
-				if (scope_read(p, i, fp))
-					goto bad;
-			}
-		}
-
-	}
-
-	if (policydb_index_decls(p))
+	if (role_trans_read(&p->role_tr, fp))
+		goto bad;
+	if (role_allow_read(&p->role_allow, fp))
 		goto bad;
 
 	if (policydb_index_classes(p))
@@ -3164,43 +2014,36 @@ int policydb_read(policydb_t * p, struct
 		goto bad;
 	}
 
-	if ((p->policy_type == POLICY_KERN
-	     && p->policyvers >= POLICYDB_VERSION_MLS)
-	    || (p->policy_type == POLICY_BASE
-		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
-		&& p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) {
+	if ((p->policyvers >= POLICYDB_VERSION_MLS)
+	    ) {
 		if (range_read(p, fp)) {
 			goto bad;
 		}
 	}
 
-	if (policy_type == POLICY_KERN) {
-		p->type_attr_map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
-		p->attr_type_map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
-		if (!p->type_attr_map || !p->attr_type_map)
-			goto bad;
-		for (i = 0; i < p->p_types.nprim; i++) {
-			ebitmap_init(&p->type_attr_map[i]);
-			ebitmap_init(&p->attr_type_map[i]);
-		}
-		for (i = 0; i < p->p_types.nprim; i++) {
-			if (r_policyvers >= POLICYDB_VERSION_AVTAB) {
-				if (ebitmap_read(&p->type_attr_map[i], fp))
+	p->type_attr_map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
+	p->attr_type_map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
+	if (!p->type_attr_map || !p->attr_type_map)
+		goto bad;
+	for (i = 0; i < p->p_types.nprim; i++) {
+		ebitmap_init(&p->type_attr_map[i]);
+		ebitmap_init(&p->attr_type_map[i]);
+	}
+	for (i = 0; i < p->p_types.nprim; i++) {
+		if (r_policyvers >= POLICYDB_VERSION_AVTAB) {
+			if (ebitmap_read(&p->type_attr_map[i], fp))
+				goto bad;
+			ebitmap_for_each_bit(&p->type_attr_map[i], tnode, j) {
+				if (!ebitmap_node_get_bit(tnode, j)
+				    || i == j)
+					continue;
+				if (ebitmap_set_bit(&p->attr_type_map[j], i, 1))
 					goto bad;
-				ebitmap_for_each_bit(&p->type_attr_map[i],
-						     tnode, j) {
-					if (!ebitmap_node_get_bit(tnode, j)
-					    || i == j)
-						continue;
-					if (ebitmap_set_bit
-					    (&p->attr_type_map[j], i, 1))
-						goto bad;
-				}
 			}
-			/* add the type itself as the degenerate case */
-			if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
-				goto bad;
 		}
+		/* add the type itself as the degenerate case */
+		if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
+			goto bad;
 	}
 
 	return POLICYDB_SUCCESS;
@@ -3236,3 +2079,128 @@ int policydb_reindex_users(policydb_t * 
 
 	return 0;
 }
+
+struct expand_avtab_data {
+	avtab_t *expa;
+	policydb_t *p;
+
+};
+
+static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d)
+{
+	avtab_ptr_t node;
+	avtab_datum_t *avd;
+	int rc;
+
+	node = avtab_search_node(a, k);
+	if (!node) {
+		rc = avtab_insert(a, k, d);
+		if (rc)
+			fprintf(stderr, "Out of memory!");
+		return rc;
+	}
+
+	if ((k->specified & AVTAB_ENABLED) !=
+	    (node->key.specified & AVTAB_ENABLED)) {
+		node = avtab_insert_nonunique(a, k, d);
+		if (!node) {
+			fprintf(stderr, "Out of memory!");
+			return -1;
+		}
+		return 0;
+	}
+
+	avd = &node->datum;
+	switch (k->specified & ~AVTAB_ENABLED) {
+	case AVTAB_ALLOWED:
+	case AVTAB_AUDITALLOW:
+		avd->data |= d->data;
+		break;
+	case AVTAB_AUDITDENY:
+		avd->data &= d->data;
+		break;
+	default:
+		fprintf(stderr, "Type conflict!");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args)
+{
+	struct expand_avtab_data *ptr = args;
+	avtab_t *expa = ptr->expa;
+	policydb_t *p = ptr->p;
+	type_datum_t *stype = p->type_val_to_struct[k->source_type - 1];
+	type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1];
+	ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1];
+	ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1];
+	ebitmap_node_t *snode, *tnode;
+	unsigned int i, j;
+	avtab_key_t newkey;
+	int rc;
+
+	newkey.target_class = k->target_class;
+	newkey.specified = k->specified;
+
+	if (stype && ttype) {
+		/* Both are individual types, no expansion required. */
+		return expand_avtab_insert(expa, k, d);
+	}
+
+	if (stype) {
+		/* Source is an individual type, target is an attribute. */
+		newkey.source_type = k->source_type;
+		ebitmap_for_each_bit(tattr, tnode, j) {
+			if (!ebitmap_node_get_bit(tnode, j))
+				continue;
+			newkey.target_type = j + 1;
+			rc = expand_avtab_insert(expa, &newkey, d);
+			if (rc)
+				return -1;
+		}
+		return 0;
+	}
+
+	if (ttype) {
+		/* Target is an individual type, source is an attribute. */
+		newkey.target_type = k->target_type;
+		ebitmap_for_each_bit(sattr, snode, i) {
+			if (!ebitmap_node_get_bit(snode, i))
+				continue;
+			newkey.source_type = i + 1;
+			rc = expand_avtab_insert(expa, &newkey, d);
+			if (rc)
+				return -1;
+		}
+		return 0;
+	}
+
+	/* Both source and target type are attributes. */
+	ebitmap_for_each_bit(sattr, snode, i) {
+		if (!ebitmap_node_get_bit(snode, i))
+			continue;
+		ebitmap_for_each_bit(tattr, tnode, j) {
+			if (!ebitmap_node_get_bit(tnode, j))
+				continue;
+			newkey.source_type = i + 1;
+			newkey.target_type = j + 1;
+			rc = expand_avtab_insert(expa, &newkey, d);
+			if (rc)
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+int expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa)
+{
+	struct expand_avtab_data data;
+
+	data.expa = expa;
+	data.p = p; 
+	return avtab_map(a, expand_avtab_node, &data);
+}     
+

-- 

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [POLICYREP] [Patch 4/5] This patch does all the functional work of removing the module support code.
  2007-08-16 15:53 [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Mark Goldman
                   ` (2 preceding siblings ...)
  2007-08-16 15:53 ` [POLICYREP] [Patch 3/5] << part 1 >> This patch does all the functional work of removing the module support code Mark Goldman
@ 2007-08-16 15:53 ` Mark Goldman
  2007-08-16 15:53 ` [POLICYREP] [Patch 5/5] This patch moves dispol to libsepol utilities. No functional changes to dispol. Makefile was modified to build dispol Mark Goldman
  2007-09-18 14:28 ` [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Joshua Brindle
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Goldman @ 2007-08-16 15:53 UTC (permalink / raw)
  To: selinux

Various unnecessary structs were removed.

At the end of this patch, libsepol is able to load policies, but does not
know about modules.

dispol operates as expected when using libsepol at the end of this patch.

<< part 2 >>

---
 libsepol/include/sepol/policydb.h              |    7 	1 +	6 -	0 !
 libsepol/include/sepol/policydb/avrule_block.h |   10 	0 +	10 -	0 !
 libsepol/include/sepol/policydb/conditional.h  |    6 	3 +	3 -	0 !
 libsepol/include/sepol/policydb/constraint.h   |    2 	1 +	1 -	0 !
 libsepol/include/sepol/policydb/flask_types.h  |    1 	0 +	1 -	0 !
 libsepol/include/sepol/policydb/policydb.h     |  205 	6 +	199 -	0 !
 libsepol/include/sepol/users.h                 |    6 	0 +	6 -	0 !
 libsepol/src/assertion.c                       |  115 	0 +	115 -	0 !
 libsepol/src/avrule_block.c                    |  173 	0 +	173 -	0 !
 libsepol/src/conditional.c                     |  257 	140 +	117 -	0 !
 libsepol/src/constraint.c                      |    5 	2 +	3 -	0 !
 libsepol/src/genusers.c                        |    8 	4 +	4 -	0 !
 libsepol/src/hierarchy.c                       |   64 	36 +	28 -	0 !
 libsepol/src/libsepol.map                      |    4 	3 +	1 -	0 !
 libsepol/src/policydb_public.c                 |   29 	3 +	26 -	0 !
 libsepol/src/private.h                         |    5 	2 +	3 -	0 !
 libsepol/src/services.c                        |    7 	4 +	3 -	0 !
 libsepol/src/users.c                           |   18 	8 +	10 -	0 !
 libsepol/src/write.c                           |  570 	45 +	525 -	0 !
 19 files changed, 258 insertions(+), 1234 deletions(-)

--- foo.orig/libsepol/src/assertion.c
+++ foo/libsepol/src/assertion.c
@@ -22,121 +22,6 @@
 
 #include <sepol/policydb/avtab.h>
 #include <sepol/policydb/policydb.h>
-#include <sepol/policydb/expand.h>
 #include <sepol/policydb/util.h>
 
 #include "debug.h"
-
-static int check_assertion_helper(sepol_handle_t * handle,
-				  policydb_t * p,
-				  avtab_t * te_avtab, avtab_t * te_cond_avtab,
-				  unsigned int stype, unsigned int ttype,
-				  class_perm_node_t * perm, unsigned long line)
-{
-	avtab_key_t avkey;
-	avtab_ptr_t node;
-	class_perm_node_t *curperm;
-
-	for (curperm = perm; curperm != NULL; curperm = curperm->next) {
-		avkey.source_type = stype + 1;
-		avkey.target_type = ttype + 1;
-		avkey.target_class = curperm->class;
-		avkey.specified = AVTAB_ALLOWED;
-		for (node = avtab_search_node(te_avtab, &avkey);
-		     node != NULL;
-		     node = avtab_search_node_next(node, avkey.specified)) {
-			if (node->datum.data & curperm->data)
-				goto err;
-		}
-		for (node = avtab_search_node(te_cond_avtab, &avkey);
-		     node != NULL;
-		     node = avtab_search_node_next(node, avkey.specified)) {
-			if (node->datum.data & curperm->data)
-				goto err;
-		}
-	}
-
-	return 0;
-
-      err:
-	ERR(handle, "assertion on line %lu violated by allow %s %s:%s {%s };",
-	    line, p->p_type_val_to_name[stype], p->p_type_val_to_name[ttype],
-	    p->p_class_val_to_name[curperm->class - 1],
-	    sepol_av_to_string(p, curperm->class,
-			       node->datum.data & curperm->data));
-	return -1;
-}
-
-int check_assertions(sepol_handle_t * handle, policydb_t * p,
-		     avrule_t * avrules)
-{
-	avrule_t *a;
-	avtab_t te_avtab, te_cond_avtab;
-	ebitmap_node_t *snode, *tnode;
-	unsigned int i, j;
-	int errors = 0;
-
-	if (!avrules) {
-		/* Since assertions are stored in avrules, if it is NULL
-		   there won't be any to check. This also prevents an invalid
-		   free if the avtabs are never initialized */
-		return 0;
-	}
-
-	if (avrules) {
-		if (avtab_init(&te_avtab))
-			goto oom;
-		if (avtab_init(&te_cond_avtab)) {
-			avtab_destroy(&te_avtab);
-			goto oom;
-		}
-		if (expand_avtab(p, &p->te_avtab, &te_avtab) ||
-		    expand_avtab(p, &p->te_cond_avtab, &te_cond_avtab)) {
-			avtab_destroy(&te_avtab);
-			avtab_destroy(&te_cond_avtab);
-			goto oom;
-		}
-	}
-
-	for (a = avrules; a != NULL; a = a->next) {
-		ebitmap_t *stypes = &a->stypes.types;
-		ebitmap_t *ttypes = &a->ttypes.types;
-
-		if (!(a->specified & AVRULE_NEVERALLOW))
-			continue;
-
-		ebitmap_for_each_bit(stypes, snode, i) {
-			if (!ebitmap_node_get_bit(snode, i))
-				continue;
-			if (a->flags & RULE_SELF) {
-				if (check_assertion_helper
-				    (handle, p, &te_avtab, &te_cond_avtab, i, i,
-				     a->perms, a->line))
-					errors++;
-			}
-			ebitmap_for_each_bit(ttypes, tnode, j) {
-				if (!ebitmap_node_get_bit(tnode, j))
-					continue;
-				if (check_assertion_helper
-				    (handle, p, &te_avtab, &te_cond_avtab, i, j,
-				     a->perms, a->line))
-					errors++;
-			}
-		}
-	}
-
-	if (errors) {
-		ERR(handle, "%d assertion violations occured", errors);
-		avtab_destroy(&te_avtab);
-		avtab_destroy(&te_cond_avtab);
-		return -1;
-	}
-
-	avtab_destroy(&te_avtab);
-	avtab_destroy(&te_cond_avtab);
-	return 0;
-
-      oom:
-	ERR(handle, "Out of memory - unable to check assertions");
-	return -1;
-}
--- foo.orig/libsepol/src/avrule_block.c
+++ foo/libsepol/src/avrule_block.c
@@ -26,176 +26,3 @@
 
 #include <assert.h>
 #include <stdlib.h>
-
-/* It is anticipated that there be less declarations within an avrule
- * block than the global policy.  Thus the symbol table sizes are
- * smaller than those listed in policydb.c */
-static unsigned int symtab_sizes[SYM_NUM] = {
-	2,
-	4,
-	8,
-	32,
-	16,
-	4,
-	2,
-	2,
-};
-
-avrule_block_t *avrule_block_create(void)
-{
-	avrule_block_t *block;
-	if ((block = calloc(1, sizeof(*block))) == NULL) {
-		return NULL;
-	}
-	return block;
-}
-
-avrule_decl_t *avrule_decl_create(uint32_t decl_id)
-{
-	avrule_decl_t *decl;
-	int i;
-	if ((decl = calloc(1, sizeof(*decl))) == NULL) {
-		return NULL;
-	}
-	decl->decl_id = decl_id;
-	for (i = 0; i < SYM_NUM; i++) {
-		if (symtab_init(&decl->symtab[i], symtab_sizes[i])) {
-			avrule_decl_destroy(decl);
-			free(decl);
-			return NULL;
-		}
-	}
-
-	for (i = 0; i < SYM_NUM; i++) {
-		ebitmap_init(&decl->required.scope[i]);
-		ebitmap_init(&decl->declared.scope[i]);
-	}
-	return decl;
-}
-
-/* note that unlike the other destroy functions, this one does /NOT/
- * destroy the pointer itself */
-static void scope_index_destroy(scope_index_t * scope)
-{
-	unsigned int i;
-	if (scope == NULL) {
-		return;
-	}
-	for (i = 0; i < SYM_NUM; i++) {
-		ebitmap_destroy(scope->scope + i);
-	}
-	for (i = 0; i < scope->class_perms_len; i++) {
-		ebitmap_destroy(scope->class_perms_map + i);
-	}
-	free(scope->class_perms_map);
-}
-
-void avrule_decl_destroy(avrule_decl_t * x)
-{
-	if (x == NULL) {
-		return;
-	}
-	cond_list_destroy(x->cond_list);
-	avrule_list_destroy(x->avrules);
-	role_trans_rule_list_destroy(x->role_tr_rules);
-	role_allow_rule_list_destroy(x->role_allow_rules);
-	range_trans_rule_list_destroy(x->range_tr_rules);
-	scope_index_destroy(&x->required);
-	scope_index_destroy(&x->declared);
-	symtabs_destroy(x->symtab);
-	free(x->module_name);
-	free(x);
-}
-
-void avrule_block_destroy(avrule_block_t * x)
-{
-	avrule_decl_t *decl;
-	if (x == NULL) {
-		return;
-	}
-	decl = x->branch_list;
-	while (decl != NULL) {
-		avrule_decl_t *next_decl = decl->next;
-		avrule_decl_destroy(decl);
-		decl = next_decl;
-	}
-	free(x);
-}
-
-void avrule_block_list_destroy(avrule_block_t * x)
-{
-	while (x != NULL) {
-		avrule_block_t *next = x->next;
-		avrule_block_destroy(x);
-		x = next;
-	}
-}
-
-/* Get a conditional node from a avrule_decl with the same expression.
- * If that expression does not exist then create one. */
-cond_list_t *get_decl_cond_list(policydb_t * p, avrule_decl_t * decl,
-				cond_list_t * cond)
-{
-	cond_list_t *result;
-	int was_created;
-	result = cond_node_find(p, cond, decl->cond_list, &was_created);
-	if (result != NULL && was_created) {
-		result->next = decl->cond_list;
-		decl->cond_list = result;
-	}
-	return result;
-}
-
-/* Look up an identifier in a policy's scoping table.  If it is there,
- * marked as SCOPE_DECL, and any of its declaring block has been enabled,
- * then return 1.  Otherwise return 0. Can only be called after the 
- * decl_val_to_struct index has been created */
-int is_id_enabled(char *id, policydb_t * p, int symbol_table)
-{
-	scope_datum_t *scope =
-	    (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id);
-	uint32_t i;
-	if (scope == NULL) {
-		return 0;
-	}
-	if (scope->scope != SCOPE_DECL) {
-		return 0;
-	}
-	for (i = 0; i < scope->decl_ids_len; i++) {
-		avrule_decl_t *decl =
-		    p->decl_val_to_struct[scope->decl_ids[i] - 1];
-		if (decl != NULL && decl->enabled) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/* Check if a particular permission is present within the given class,
- * and that the class is enabled.  Returns 1 if both conditions are
- * true, 0 if neither could be found or if the class id disabled. */
-int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p)
-{
-	class_datum_t *cladatum;
-	perm_datum_t *perm;
-	if (!is_id_enabled(class_id, p, SYM_CLASSES)) {
-		return 0;
-	}
-	cladatum =
-	    (class_datum_t *) hashtab_search(p->p_classes.table, class_id);
-	if (cladatum == NULL) {
-		return 0;
-	}
-	perm = hashtab_search(cladatum->permissions.table, perm_id);
-	if (perm == NULL && cladatum->comdatum != 0) {
-		/* permission was not in this class.  before giving
-		 * up, check the class's parent */
-		perm =
-		    hashtab_search(cladatum->comdatum->permissions.table,
-				   perm_id);
-	}
-	if (perm == NULL) {
-		return 0;
-	}
-	return 1;
-}
--- foo.orig/libsepol/src/conditional.c
+++ foo/libsepol/src/conditional.c
@@ -336,109 +336,6 @@ static int evaluate_cond_node(policydb_t
 	return 0;
 }
 
-/* precompute and simplify an expression if possible.  If left with !expression, change 
- * to expression and switch t and f. precompute expression for expressions with limited
- * number of bools.
- */
-int cond_normalize_expr(policydb_t * p, cond_node_t * cn)
-{
-	cond_expr_t *ne, *e;
-	cond_av_list_t *tmp;
-	unsigned int i, j, orig_value[COND_MAX_BOOLS];
-	int k;
-	uint32_t test = 0x0;
-	avrule_t *tmp2;
-
-	cn->nbools = 0;
-
-	memset(cn->bool_ids, 0, sizeof(cn->bool_ids));
-	cn->expr_pre_comp = 0x0;
-
-	/* take care of !expr case */
-	ne = NULL;
-	e = cn->expr;
-
-	/* becuase it's RPN look at last element */
-	while (e->next != NULL) {
-		ne = e;
-		e = e->next;
-	}
-	if (e->expr_type == COND_NOT) {
-		if (ne) {
-			ne->next = NULL;
-		} else {	/* ne should never be NULL */
-			printf
-			    ("Found expr with no bools and only a ! - this should never happen.\n");
-			return -1;
-		}
-		/* swap the true and false lists */
-		tmp = cn->true_list;
-		cn->true_list = cn->false_list;
-		cn->false_list = tmp;
-		tmp2 = cn->avtrue_list;
-		cn->avtrue_list = cn->avfalse_list;
-		cn->avfalse_list = tmp2;
-
-		/* free the "not" node in the list */
-		free(e);
-	}
-
-	/* find all the bools in the expression */
-	for (e = cn->expr; e != NULL; e = e->next) {
-		switch (e->expr_type) {
-		case COND_BOOL:
-			i = 0;
-			/* see if we've already seen this bool */
-			if (!bool_present(e->bool, cn->bool_ids, cn->nbools)) {
-				/* count em all but only record up to COND_MAX_BOOLS */
-				if (cn->nbools < COND_MAX_BOOLS)
-					cn->bool_ids[cn->nbools++] = e->bool;
-				else
-					cn->nbools++;
-			}
-			break;
-		default:
-			break;
-		}
-	}
-
-	/* only precompute for exprs with <= COND_AX_BOOLS */
-	if (cn->nbools <= COND_MAX_BOOLS) {
-		/* save the default values for the bools so we can play with them */
-		for (i = 0; i < cn->nbools; i++) {
-			orig_value[i] =
-			    p->bool_val_to_struct[cn->bool_ids[i] - 1]->state;
-		}
-
-		/* loop through all possible combinations of values for bools in expression */
-		for (test = 0x0; test < (0x1U << cn->nbools); test++) {
-			/* temporarily set the value for all the bools in the
-			 * expression using the corr.  bit in test */
-			for (j = 0; j < cn->nbools; j++) {
-				p->bool_val_to_struct[cn->bool_ids[j] -
-						      1]->state =
-				    (test & (0x1 << j)) ? 1 : 0;
-			}
-			k = cond_evaluate_expr(p, cn->expr);
-			if (k == -1) {
-				printf
-				    ("While testing expression, expression result "
-				     "was undefined - this should never happen.\n");
-				return -1;
-			}
-			/* set the bit if expression evaluates true */
-			if (k)
-				cn->expr_pre_comp |= 0x1 << test;
-		}
-
-		/* restore bool default values */
-		for (i = 0; i < cn->nbools; i++)
-			p->bool_val_to_struct[cn->bool_ids[i] - 1]->state =
-			    orig_value[i];
-	}
-	return 0;
-}
-
 int evaluate_conds(policydb_t * p)
 {
 	int ret;
@@ -491,8 +388,6 @@ void cond_node_destroy(cond_node_t * nod
 		return;
 
 	cond_expr_destroy(node->expr);
-	avrule_list_destroy(node->avtrue_list);
-	avrule_list_destroy(node->avfalse_list);
 	cond_av_list_destroy(node->true_list);
 	cond_av_list_destroy(node->false_list);
 }
@@ -797,18 +692,11 @@ static int cond_read_node(policydb_t * p
 		last = expr;
 	}
 
-	if (p->policy_type == POLICY_KERN) {
-		if (cond_read_av_list(p, fp, &node->true_list, NULL) != 0)
-			goto err;
-		if (cond_read_av_list(p, fp, &node->false_list, node->true_list)
-		    != 0)
-			goto err;
-	} else {
-		if (avrule_read_list(p, &node->avtrue_list, fp))
-			goto err;
-		if (avrule_read_list(p, &node->avfalse_list, fp))
-			goto err;
-	}
+	if (cond_read_av_list(p, fp, &node->true_list, NULL) != 0)
+		goto err;
+	if (cond_read_av_list(p, fp, &node->false_list, node->true_list)
+	    != 0)
+		goto err;
 
 	return 0;
       err:
@@ -899,3 +787,138 @@ avtab_datum_t *cond_av_list_search(avtab
 	return NULL;
 
 }
+
+static int expand_cond_insert(cond_av_list_t ** l,
+			      avtab_t * expa,
+			      avtab_key_t * k, avtab_datum_t * d)
+{
+	avtab_ptr_t node;
+	avtab_datum_t *avd;
+	cond_av_list_t *nl;
+
+	node = avtab_search_node(expa, k);
+	if (!node ||
+	    (k->specified & AVTAB_ENABLED) !=
+	    (node->key.specified & AVTAB_ENABLED)) {
+		node = avtab_insert_nonunique(expa, k, d);
+		if (!node) {
+			fprintf(stderr, "Out of memory!");
+			return -1;
+		}
+		node->parse_context = (void *)1;
+		nl = (cond_av_list_t *) malloc(sizeof(*nl));
+		if (!nl) {
+			fprintf(stderr, "Out of memory!");
+			return -1;
+		}
+		memset(nl, 0, sizeof(*nl));
+		nl->node = node;
+		nl->next = *l;
+		*l = nl;
+		return 0;
+	}
+
+	avd = &node->datum;
+	switch (k->specified & ~AVTAB_ENABLED) {
+	case AVTAB_ALLOWED:
+	case AVTAB_AUDITALLOW:
+		avd->data |= d->data;
+		break;
+	case AVTAB_AUDITDENY:
+		avd->data &= d->data;
+		break;
+	default:
+		fprintf(stderr, "Type conflict!");
+		return -1;
+	}
+
+	return 0;
+}
+
+int expand_cond_av_node(policydb_t * p,
+			avtab_ptr_t node,
+			cond_av_list_t ** newl, avtab_t * expa)
+{
+	avtab_key_t *k = &node->key;
+	avtab_datum_t *d = &node->datum;
+	type_datum_t *stype = p->type_val_to_struct[k->source_type - 1];
+	type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1];
+	ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1];
+	ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1];
+	ebitmap_node_t *snode, *tnode;
+	unsigned int i, j;
+	avtab_key_t newkey;
+	int rc;
+
+	newkey.target_class = k->target_class;
+	newkey.specified = k->specified;
+
+	if (stype && ttype) {
+		/* Both are individual types, no expansion required. */
+		return expand_cond_insert(newl, expa, k, d);
+	}
+
+	if (stype) {
+		/* Source is an individual type, target is an attribute. */
+		newkey.source_type = k->source_type;
+		ebitmap_for_each_bit(tattr, tnode, j) {
+			if (!ebitmap_node_get_bit(tnode, j))
+				continue;
+			newkey.target_type = j + 1;
+			rc = expand_cond_insert(newl, expa, &newkey, d);
+			if (rc)
+				return -1;
+		}
+		return 0;
+	}
+
+	if (ttype) {
+		/* Target is an individual type, source is an attribute. */
+		newkey.target_type = k->target_type;
+		ebitmap_for_each_bit(sattr, snode, i) {
+			if (!ebitmap_node_get_bit(snode, i))
+				continue;
+			newkey.source_type = i + 1;
+			rc = expand_cond_insert(newl, expa, &newkey, d);
+			if (rc)
+				return -1;
+		}
+		return 0;
+	}
+
+	/* Both source and target type are attributes. */
+	ebitmap_for_each_bit(sattr, snode, i) {
+		if (!ebitmap_node_get_bit(snode, i))
+			continue;
+		ebitmap_for_each_bit(tattr, tnode, j) {
+			if (!ebitmap_node_get_bit(tnode, j))
+				continue;
+			newkey.source_type = i + 1;
+			newkey.target_type = j + 1;
+			rc = expand_cond_insert(newl, expa, &newkey, d);
+			if (rc)
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+int expand_cond_av_list(policydb_t * p, cond_av_list_t * l,
+			cond_av_list_t ** newl, avtab_t * expa)
+{
+	cond_av_list_t *cur;
+	avtab_ptr_t node;
+	int rc;
+
+	*newl = NULL;
+	for (cur = l; cur; cur = cur->next) {
+		node = cur->node;
+		rc = expand_cond_av_node(p, node, newl, expa);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
+
--- foo.orig/libsepol/src/constraint.c
+++ foo/libsepol/src/constraint.c
@@ -19,7 +19,6 @@
 
 #include <sepol/policydb/policydb.h>
 #include <sepol/policydb/constraint.h>
-#include <sepol/policydb/expand.h>
 #include <sepol/policydb/flask_types.h>
 
 #include <assert.h>
@@ -32,7 +31,7 @@ int constraint_expr_init(constraint_expr
 	if ((expr->type_names = malloc(sizeof(*expr->type_names))) == NULL) {
 		return -1;
 	}
-	type_set_init(expr->type_names);
+	ebitmap_init(expr->type_names);
 	return 0;
 }
 
@@ -40,7 +39,7 @@ void constraint_expr_destroy(constraint_
 {
 	if (expr != NULL) {
 		ebitmap_destroy(&expr->names);
-		type_set_destroy(expr->type_names);
+		ebitmap_destroy(expr->type_names);
 		free(expr->type_names);
 		free(expr);
 	}
--- foo.orig/libsepol/src/genusers.c
+++ foo/libsepol/src/genusers.c
@@ -72,8 +72,8 @@ static int load_users(struct policydb *p
 		usrdatum = hashtab_search(policydb->p_users.table, q);
 		if (usrdatum) {
 			/* Replacing an existing user definition. */
-			ebitmap_destroy(&usrdatum->roles.roles);
-			ebitmap_init(&usrdatum->roles.roles);
+			ebitmap_destroy(&usrdatum->roles);
+			ebitmap_init(&usrdatum->roles);
 		} else {
 			char *id = strdup(q);
 
@@ -88,7 +88,7 @@ static int load_users(struct policydb *p
 			}
 			memset(usrdatum, 0, sizeof(user_datum_t));
 			usrdatum->s.value = ++policydb->p_users.nprim;
-			ebitmap_init(&usrdatum->roles.roles);
+			ebitmap_init(&usrdatum->roles);
 			if (hashtab_insert(policydb->p_users.table,
 					   id, (hashtab_datum_t) usrdatum)) {
 				ERR(NULL, "out of memory");
@@ -145,7 +145,7 @@ static int load_users(struct policydb *p
 			ebitmap_for_each_bit(&roldatum->dominates, rnode, bit) {
 				if (ebitmap_node_get_bit(rnode, bit))
 					if (ebitmap_set_bit
-					    (&usrdatum->roles.roles, bit, 1)) {
+					    (&usrdatum->roles, bit, 1)) {
 						ERR(NULL, "out of memory");
 						free(buffer);
 						fclose(fp);
--- foo.orig/libsepol/src/hierarchy.c
+++ foo/libsepol/src/hierarchy.c
@@ -27,7 +27,6 @@
 #include <sepol/policydb/policydb.h>
 #include <sepol/policydb/conditional.h>
 #include <sepol/policydb/hierarchy.h>
-#include <sepol/policydb/expand.h>
 #include <sepol/policydb/util.h>
 
 #include "debug.h"
@@ -259,6 +258,13 @@ static int check_avtab_hierarchy_callbac
 	return 0;
 }
 
+/* NOTE: the code path that gets here will not get exercised until
+ * we finish with the new policy-representation.  Currently the only
+ * thing in the library that calls this (indirectly) is via the
+ * checkmodule program.  This will probably be overhauled significantly
+ * by the time policyrep is done.
+ * - mgoldman@tresys.com 2007-06-21
+ */
 static int check_cond_avtab_hierarchy(cond_list_t * cond_list,
 				      hierarchy_args_t * args)
 {
@@ -268,14 +274,22 @@ static int check_cond_avtab_hierarchy(co
 	avtab_t expa;
 	hierarchy_args_t *a = (hierarchy_args_t *) args;
 
+	ERR(args->handle, "%s:%d %s This function is broken until policyrep"
+	    " work is finished.\nIt is currently in an unused codepath "
+	    "and this message\nshould not be seen.\n", __FILE__, __LINE__,
+	    __func__);
+	return 1;
+
 	for (cur_node = cond_list; cur_node != NULL; cur_node = cur_node->next) {
 		if (avtab_init(&expa))
 			goto oom;
-		if (expand_cond_av_list
-		    (args->p, cur_node->true_list, &expl, &expa)) {
-			avtab_destroy(&expa);
-			goto oom;
-		}
+		/* FIXME: Broken until policyrep work is finished
+		   if (expand_cond_av_list
+		   (args->p, cur_node->true_list, &expl, &expa)) {
+		   avtab_destroy(&expa);
+		   goto oom;
+		   }
+		 */
 		args->opt_cond_list = expl;
 		for (cur_av = expl; cur_av != NULL; cur_av = cur_av->next) {
 			rc = check_avtab_hierarchy_callback(&cur_av->node->key,
@@ -288,11 +302,13 @@ static int check_cond_avtab_hierarchy(co
 		avtab_destroy(&expa);
 		if (avtab_init(&expa))
 			goto oom;
-		if (expand_cond_av_list
-		    (args->p, cur_node->false_list, &expl, &expa)) {
-			avtab_destroy(&expa);
-			goto oom;
-		}
+		/* FIXME: Broken until policyrep work is finished.
+		   if (expand_cond_av_list
+		   (args->p, cur_node->false_list, &expl, &expa)) {
+		   avtab_destroy(&expa);
+		   goto oom;
+		   }
+		 */
 		args->opt_cond_list = expl;
 		for (cur_av = expl; cur_av != NULL; cur_av = cur_av->next) {
 			rc = check_avtab_hierarchy_callback(&cur_av->node->key,
@@ -346,13 +362,13 @@ static int check_role_hierarchy_callback
 		return 0;
 	}
 
-	if (ebitmap_or(&eb, &r->types.types, &rp->types.types)) {
+	if (ebitmap_or(&eb, &r->types, &rp->types)) {
 		/* Memory error */
 		free(parent);
 		return -1;
 	}
 
-	if (!ebitmap_cmp(&eb, &rp->types.types)) {
+	if (!ebitmap_cmp(&eb, &rp->types)) {
 		/* This is a violation of the hiearchal constraint, return error condition */
 		ERR(a->handle, "Role hierarchy violation, %s exceeds %s",
 		    a->p->p_role_val_to_name[r->s.value - 1], parent);
@@ -368,17 +384,15 @@ static int check_role_hierarchy_callback
 int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p)
 {
 	hierarchy_args_t args;
-	avtab_t expa;
 
-	if (avtab_init(&expa))
-		goto oom;
-	if (expand_avtab(p, &p->te_avtab, &expa)) {
-		avtab_destroy(&expa);
-		goto oom;
-	}
+	ERR(handle, "%s:%d %s This function is broken until policyrep"
+	    " work is finished.\nIt is currently in an unused codepath "
+	    "and this message\nshould not be seen.\n", __FILE__, __LINE__,
+	    __func__);
+	return 1;
 
 	args.p = p;
-	args.expa = &expa;
+	args.expa = &p->te_avtab;
 	args.opt_cond_list = NULL;
 	args.handle = handle;
 	args.numerr = 0;
@@ -386,7 +400,7 @@ int hierarchy_check_constraints(sepol_ha
 	if (hashtab_map(p->p_types.table, check_type_hierarchy_callback, &args))
 		goto bad;
 
-	if (avtab_map(&expa, check_avtab_hierarchy_callback, &args))
+	if (avtab_map(&p->te_avtab, check_avtab_hierarchy_callback, &args))
 		goto bad;
 
 	if (check_cond_avtab_hierarchy(p->cond_list, &args))
@@ -401,14 +415,8 @@ int hierarchy_check_constraints(sepol_ha
 		goto bad;
 	}
 
-	avtab_destroy(&expa);
 	return 0;
 
       bad:
-	avtab_destroy(&expa);
-	return -1;
-
-      oom:
-	ERR(handle, "Out of memory");
 	return -1;
 }
--- foo.orig/libsepol/src/policydb_public.c
+++ foo/libsepol/src/policydb_public.c
@@ -95,41 +95,18 @@ int sepol_policy_kern_vers_max(void)
 	return POLICYDB_VERSION_MAX;
 }
 
-int sepol_policydb_set_typevers(sepol_policydb_t * sp, unsigned int type)
+int sepol_policydb_set_typevers(sepol_policydb_t * sp)
 {
 	struct policydb *p = &sp->p;
-	switch (type) {
-	case POLICY_KERN:
-		p->policyvers = POLICYDB_VERSION_MAX;
-		break;
-	case POLICY_BASE:
-	case POLICY_MOD:
-		p->policyvers = MOD_POLICYDB_VERSION_MAX;
-		break;
-	default:
-		return -1;
-	}
-	p->policy_type = type;
+	p->policyvers = POLICYDB_VERSION_MAX;
 	return 0;
 }
 
 int sepol_policydb_set_vers(sepol_policydb_t * sp, unsigned int vers)
 {
 	struct policydb *p = &sp->p;
-	switch (p->policy_type) {
-	case POLICY_KERN:
-		if (vers < POLICYDB_VERSION_MIN || vers > POLICYDB_VERSION_MAX)
-			return -1;
-		break;
-	case POLICY_BASE:
-	case POLICY_MOD:
-		if (vers < MOD_POLICYDB_VERSION_MIN
-		    || vers > MOD_POLICYDB_VERSION_MAX)
-			return -1;
-		break;
-	default:
+	if (vers < POLICYDB_VERSION_MIN || vers > POLICYDB_VERSION_MAX)
 		return -1;
-	}
 	p->policyvers = vers;
 	return 0;
 }
--- foo.orig/libsepol/src/services.c
+++ foo/libsepol/src/services.c
@@ -87,7 +87,8 @@ int sepol_set_policydb_from_file(FILE * 
 	struct policy_file pf;
 	pf.fp = fp;
 	pf.type = PF_USE_STDIO;
-	if (mypolicydb.policy_type)
+	// FIXME: We need to figure out a new test for destroying the db
+	if (0)
 		policydb_destroy(&mypolicydb);
 	if (policydb_init(&mypolicydb)) {
 		ERR(NULL, "Out of memory!");
@@ -1265,12 +1266,12 @@ int hidden sepol_get_user_sids(sepol_sec
 	}
 	memset(mysids, 0, maxnel * sizeof(sepol_security_id_t));
 
-	ebitmap_for_each_bit(&user->roles.roles, rnode, i) {
+	ebitmap_for_each_bit(&user->roles, rnode, i) {
 		if (!ebitmap_node_get_bit(rnode, i))
 			continue;
 		role = policydb->role_val_to_struct[i];
 		usercon.role = i + 1;
-		ebitmap_for_each_bit(&role->types.types, tnode, j) {
+		ebitmap_for_each_bit(&role->types, tnode, j) {
 			if (!ebitmap_node_get_bit(tnode, j))
 				continue;
 			usercon.type = j + 1;
--- foo.orig/libsepol/src/users.c
+++ foo/libsepol/src/users.c
@@ -8,7 +8,6 @@
 
 #include <sepol/policydb/policydb.h>
 #include <sepol/policydb/hashtab.h>
-#include <sepol/policydb/expand.h>
 #include "user_internal.h"
 #include "mls.h"
 
@@ -19,7 +18,7 @@ static int user_to_record(sepol_handle_t
 
 	const char *name = policydb->p_user_val_to_name[user_idx];
 	user_datum_t *usrdatum = policydb->user_val_to_struct[user_idx];
-	ebitmap_t *roles = &(usrdatum->roles.roles);
+	ebitmap_t *roles = &(usrdatum->roles);
 	ebitmap_node_t *rnode;
 	unsigned bit;
 
@@ -169,8 +168,7 @@ int sepol_user_modify(sepol_handle_t * h
 		/* Set the role and every role it dominates */
 		ebitmap_for_each_bit(&roldatum->dominates, rnode, bit) {
 			if (ebitmap_node_get_bit(rnode, bit)) {
-				if (ebitmap_set_bit
-				    (&(usrdatum->roles.roles), bit, 1))
+				if (ebitmap_set_bit(&(usrdatum->roles), bit, 1))
 					goto omem;
 			}
 		}
@@ -259,11 +257,11 @@ int sepol_user_modify(sepol_handle_t * h
 		name = NULL;
 
 		/* Expand roles */
-		if (role_set_expand
-		    (&usrdatum->roles, &usrdatum->cache, policydb)) {
-			ERR(handle, "unable to expand role set");
-			goto err;
-		}
+		/* NOTE: Deleted this section - it is unclear whether or not
+		 * expansion will be required when the policyrep work is
+		 * done. 
+		 *  - mgoldman@tresys.com
+		 */
 	}
 
 	free(roles);
@@ -278,7 +276,7 @@ int sepol_user_modify(sepol_handle_t * h
 	free(name);
 	free(roles);
 	if (new && usrdatum) {
-		role_set_destroy(&usrdatum->roles);
+		ebitmap_destroy(&usrdatum->roles);
 		free(usrdatum);
 	}
 	return STATUS_ERR;
--- foo.orig/libsepol/src/write.c
+++ foo/libsepol/src/write.c
@@ -38,7 +38,6 @@
 #include <sepol/policydb/avtab.h>
 #include <sepol/policydb/policydb.h>
 #include <sepol/policydb/conditional.h>
-#include <sepol/policydb/expand.h>
 #include <sepol/policydb/flask.h>
 
 #include "debug.h"
@@ -50,8 +49,6 @@ struct policy_data {
 	struct policydb *p;
 };
 
-static int avrule_write_list(avrule_t * avrules, struct policy_file *fp);
-
 static int ebitmap_write(ebitmap_t * e, struct policy_file *fp)
 {
 	ebitmap_node_t *n;
@@ -105,8 +102,7 @@ static int avtab_write_item(policydb_t *
 	uint32_t buf32[10], lookup, val;
 	size_t items, items2;
 	unsigned set;
-	unsigned int oldvers = (p->policy_type == POLICY_KERN
-				&& p->policyvers < POLICYDB_VERSION_AVTAB);
+	unsigned int oldvers = (p->policyvers < POLICYDB_VERSION_AVTAB);
 	unsigned int i;
 
 	if (oldvers) {
@@ -244,23 +240,13 @@ static int avtab_write(struct policydb *
 	avtab_ptr_t cur;
 	uint32_t nel;
 	size_t items;
-	unsigned int oldvers = (p->policy_type == POLICY_KERN
-				&& p->policyvers < POLICYDB_VERSION_AVTAB);
+	unsigned int oldvers = (p->policyvers < POLICYDB_VERSION_AVTAB);
 
 	if (oldvers) {
-		/* Old avtab format.
-		   First, we need to expand attributes.  Then, we need to
-		   merge similar entries, so we need to track merged nodes 
-		   and compute the final nel. */
-		if (avtab_init(&expa))
-			return POLICYDB_ERROR;
-		if (expand_avtab(p, a, &expa)) {
-			rc = -1;
-			goto out;
-		}
-		a = &expa;
-		avtab_reset_merged(a);
-		nel = a->nel;
+		fprintf(stderr, "%s:%d Error, this branch executed \n"
+			"code that dissappeared.\n", __FILE__, __LINE__);
+		rc = -1;
+		goto out;
 	} else {
 		/* New avtab format.  nel is good to go. */
 		nel = cpu_to_le32(a->nel);
@@ -308,55 +294,6 @@ static int avtab_write(struct policydb *
 }
 
 /*
- * Write a semantic MLS level structure to a policydb binary 
- * representation file.
- */
-static int mls_write_semantic_level_helper(mls_semantic_level_t * l,
-					   struct policy_file *fp)
-{
-	uint32_t buf[2], ncat = 0;
-	size_t items;
-	mls_semantic_cat_t *cat;
-
-	for (cat = l->cat; cat; cat = cat->next)
-		ncat++;
-
-	buf[0] = cpu_to_le32(l->sens);
-	buf[1] = cpu_to_le32(ncat);
-	items = put_entry(buf, sizeof(uint32_t), 2, fp);
-	if (items != 2)
-		return POLICYDB_ERROR;
-
-	for (cat = l->cat; cat; cat = cat->next) {
-		buf[0] = cpu_to_le32(cat->low);
-		buf[1] = cpu_to_le32(cat->high);
-		items = put_entry(buf, sizeof(uint32_t), 2, fp);
-		if (items != 2)
-			return POLICYDB_ERROR;
-	}
-
-	return POLICYDB_SUCCESS;
-}
-
-/*
- * Read a semantic MLS range structure to a policydb binary 
- * representation file.
- */
-static int mls_write_semantic_range_helper(mls_semantic_range_t * r,
-					   struct policy_file *fp)
-{
-	int rc;
-
-	rc = mls_write_semantic_level_helper(&r->level[0], fp);
-	if (rc)
-		return rc;
-
-	rc = mls_write_semantic_level_helper(&r->level[1], fp);
-
-	return rc;
-}
-
-/*
  * Write a MLS level structure to a policydb binary 
  * representation file.
  */
@@ -509,40 +446,6 @@ static int role_allow_write(role_allow_t
 	return POLICYDB_SUCCESS;
 }
 
-static int role_set_write(role_set_t * x, struct policy_file *fp)
-{
-	size_t items;
-	uint32_t buf[1];
-
-	if (ebitmap_write(&x->roles, fp))
-		return POLICYDB_ERROR;
-
-	buf[0] = cpu_to_le32(x->flags);
-	items = put_entry(buf, sizeof(uint32_t), 1, fp);
-	if (items != 1)
-		return POLICYDB_ERROR;
-
-	return POLICYDB_SUCCESS;
-}
-
-static int type_set_write(type_set_t * x, struct policy_file *fp)
-{
-	size_t items;
-	uint32_t buf[1];
-
-	if (ebitmap_write(&x->types, fp))
-		return POLICYDB_ERROR;
-	if (ebitmap_write(&x->negset, fp))
-		return POLICYDB_ERROR;
-
-	buf[0] = cpu_to_le32(x->flags);
-	items = put_entry(buf, sizeof(uint32_t), 1, fp);
-	if (items != 1)
-		return POLICYDB_ERROR;
-
-	return POLICYDB_SUCCESS;
-}
-
 static int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
 {
 	cond_bool_datum_t *booldatum;
@@ -583,16 +486,14 @@ static int cond_write_av_list(policydb_t
 	cond_av_list_t *cur_list, *new_list = NULL;
 	avtab_t expa;
 	uint32_t len, items;
-	unsigned int oldvers = (p->policy_type == POLICY_KERN
-				&& p->policyvers < POLICYDB_VERSION_AVTAB);
+	unsigned int oldvers = (p->policyvers < POLICYDB_VERSION_AVTAB);
 	int rc = -1;
 
 	if (oldvers) {
-		if (avtab_init(&expa))
-			return POLICYDB_ERROR;
-		if (expand_cond_av_list(p, list, &new_list, &expa))
-			goto out;
-		list = new_list;
+		fprintf(stderr, "%s:%d Error, this branch executed \n"
+			"code that dissappeared.\n", __FILE__, __LINE__);
+		rc = -1;
+		goto out;
 	}
 
 	len = 0;
@@ -658,17 +559,10 @@ static int cond_write_node(policydb_t * 
 			return POLICYDB_ERROR;
 	}
 
-	if (p->policy_type == POLICY_KERN) {
-		if (cond_write_av_list(p, node->true_list, fp) != 0)
-			return POLICYDB_ERROR;
-		if (cond_write_av_list(p, node->false_list, fp) != 0)
-			return POLICYDB_ERROR;
-	} else {
-		if (avrule_write_list(node->avtrue_list, fp))
-			return POLICYDB_ERROR;
-		if (avrule_write_list(node->avfalse_list, fp))
-			return POLICYDB_ERROR;
-	}
+	if (cond_write_av_list(p, node->true_list, fp) != 0)
+		return POLICYDB_ERROR;
+	if (cond_write_av_list(p, node->false_list, fp) != 0)
+		return POLICYDB_ERROR;
 
 	return POLICYDB_SUCCESS;
 }
@@ -712,10 +606,8 @@ static int context_write(struct policydb
 	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
 	if (items2 != items)
 		return POLICYDB_ERROR;
-	if ((p->policyvers >= POLICYDB_VERSION_MLS
-	     && p->policy_type == POLICY_KERN)
-	    || (p->policyvers >= MOD_POLICYDB_VERSION_MLS
-		&& p->policy_type == POLICY_BASE))
+	if ((p->policyvers >= POLICYDB_VERSION_MLS)
+	    )
 		if (mls_write_range_helper(&c->range, fp))
 			return POLICYDB_ERROR;
 
@@ -783,7 +675,7 @@ static int common_write(hashtab_key_t ke
 	return POLICYDB_SUCCESS;
 }
 
-static int write_cons_helper(policydb_t * p,
+static int write_cons_helper(policydb_t * p __attribute__ ((unused)),
 			     constraint_node_t * node, int allowxtarget,
 			     struct policy_file *fp)
 {
@@ -818,10 +710,6 @@ static int write_cons_helper(policydb_t 
 				if (ebitmap_write(&e->names, fp)) {
 					return POLICYDB_ERROR;
 				}
-				if (p->policy_type != POLICY_KERN &&
-				    type_set_write(e->type_names, fp)) {
-					return POLICYDB_ERROR;
-				}
 				break;
 			default:
 				break;
@@ -884,10 +772,8 @@ static int class_write(hashtab_key_t key
 	if (write_cons_helper(p, cladatum->constraints, 0, fp))
 		return POLICYDB_ERROR;
 
-	if ((p->policy_type == POLICY_KERN
-	     && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
-	    || (p->policy_type == POLICY_BASE
-		&& p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) {
+	if ((p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
+	    ) {
 		/* write out the validatetrans rule */
 		ncons = 0;
 		for (c = cladatum->validatetrans; c; c = c->next) {
@@ -911,7 +797,6 @@ static int role_write(hashtab_key_t key,
 	size_t items, items2, len;
 	struct policy_data *pd = ptr;
 	struct policy_file *fp = pd->fp;
-	struct policydb *p = pd->p;
 
 	role = (role_datum_t *) datum;
 
@@ -929,13 +814,8 @@ static int role_write(hashtab_key_t key,
 
 	if (ebitmap_write(&role->dominates, fp))
 		return POLICYDB_ERROR;
-	if (p->policy_type == POLICY_KERN) {
-		if (ebitmap_write(&role->types.types, fp))
-			return POLICYDB_ERROR;
-	} else {
-		if (type_set_write(&role->types, fp))
-			return POLICYDB_ERROR;
-	}
+	if (ebitmap_write(&role->types, fp))
+		return POLICYDB_ERROR;
 
 	return POLICYDB_SUCCESS;
 }
@@ -947,7 +827,6 @@ static int type_write(hashtab_key_t key,
 	size_t items, items2, len;
 	struct policy_data *pd = ptr;
 	struct policy_file *fp = pd->fp;
-	struct policydb *p = pd->p;
 
 	typdatum = (type_datum_t *) datum;
 
@@ -956,18 +835,10 @@ static int type_write(hashtab_key_t key,
 	buf[items++] = cpu_to_le32(len);
 	buf[items++] = cpu_to_le32(typdatum->s.value);
 	buf[items++] = cpu_to_le32(typdatum->primary);
-	if (p->policy_type != POLICY_KERN) {
-		buf[items++] = cpu_to_le32(typdatum->flavor);
-	}
 	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
 	if (items != items2)
 		return POLICYDB_ERROR;
 
-	if (p->policy_type != POLICY_KERN) {
-		if (ebitmap_write(&typdatum->types, fp))
-			return POLICYDB_ERROR;
-	}
-
 	items = put_entry(key, 1, len, fp);
 	if (items != len)
 		return POLICYDB_ERROR;
@@ -998,34 +869,15 @@ static int user_write(hashtab_key_t key,
 	if (items != len)
 		return POLICYDB_ERROR;
 
-	if (p->policy_type == POLICY_KERN) {
-		if (ebitmap_write(&usrdatum->roles.roles, fp))
-			return POLICYDB_ERROR;
-	} else {
-		if (role_set_write(&usrdatum->roles, fp))
-			return POLICYDB_ERROR;
-	}
+	if (ebitmap_write(&usrdatum->roles, fp))
+		return POLICYDB_ERROR;
 
-	if ((p->policyvers >= POLICYDB_VERSION_MLS
-	     && p->policy_type == POLICY_KERN)
-	    || (p->policyvers >= MOD_POLICYDB_VERSION_MLS
-		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS
-		&& p->policy_type == POLICY_MOD)
-	    || (p->policyvers >= MOD_POLICYDB_VERSION_MLS
-		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS
-		&& p->policy_type == POLICY_BASE)) {
+	if ((p->policyvers >= POLICYDB_VERSION_MLS)
+	    ) {
 		if (mls_write_range_helper(&usrdatum->exp_range, fp))
 			return POLICYDB_ERROR;
 		if (mls_write_level(&usrdatum->exp_dfltlevel, fp))
 			return POLICYDB_ERROR;
-	} else if ((p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS
-		    && p->policy_type == POLICY_MOD)
-		   || (p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS
-		       && p->policy_type == POLICY_BASE)) {
-		if (mls_write_semantic_range_helper(&usrdatum->range, fp))
-			return -1;
-		if (mls_write_semantic_level_helper(&usrdatum->dfltlevel, fp))
-			return -1;
 	}
 
 	return POLICYDB_SUCCESS;
@@ -1184,8 +1036,7 @@ static int range_write(policydb_t * p, s
 	size_t nel, items;
 	struct range_trans *rt;
 	uint32_t buf[2];
-	int new_rangetr = (p->policy_type == POLICY_KERN &&
-			   p->policyvers >= POLICYDB_VERSION_RANGETRANS);
+	int new_rangetr = (p->policyvers >= POLICYDB_VERSION_RANGETRANS);
 	int warning_issued = 0;
 
 	nel = 0;
@@ -1226,290 +1077,6 @@ static int range_write(policydb_t * p, s
 	return POLICYDB_SUCCESS;
 }
 
-/************** module writing functions below **************/
-
-static int avrule_write(avrule_t * avrule, struct policy_file *fp)
-{
-	size_t items, items2;
-	uint32_t buf[32], len;
-	class_perm_node_t *cur;
-
-	items = 0;
-	buf[items++] = cpu_to_le32(avrule->specified);
-	buf[items++] = cpu_to_le32(avrule->flags);
-	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
-	if (items2 != items)
-		return POLICYDB_ERROR;
-
-	if (type_set_write(&avrule->stypes, fp))
-		return POLICYDB_ERROR;
-
-	if (type_set_write(&avrule->ttypes, fp))
-		return POLICYDB_ERROR;
-
-	cur = avrule->perms;
-	len = 0;
-	while (cur) {
-		len++;
-		cur = cur->next;
-	}
-	items = 0;
-	buf[items++] = cpu_to_le32(len);
-	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
-	if (items2 != items)
-		return POLICYDB_ERROR;
-	cur = avrule->perms;
-	while (cur) {
-		items = 0;
-		buf[items++] = cpu_to_le32(cur->class);
-		buf[items++] = cpu_to_le32(cur->data);
-		items2 = put_entry(buf, sizeof(uint32_t), items, fp);
-		if (items2 != items)
-			return POLICYDB_ERROR;
-
-		cur = cur->next;
-	}
-
-	return POLICYDB_SUCCESS;
-}
-
-static int avrule_write_list(avrule_t * avrules, struct policy_file *fp)
-{
-	uint32_t buf[32], len;
-	avrule_t *avrule;
-
-	avrule = avrules;
-	len = 0;
-	while (avrule) {
-		len++;
-		avrule = avrule->next;
-	}
-
-	buf[0] = cpu_to_le32(len);
-	if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1)
-		return POLICYDB_ERROR;
-
-	avrule = avrules;
-	while (avrule) {
-		avrule_write(avrule, fp);
-		avrule = avrule->next;
-	}
-
-	return POLICYDB_SUCCESS;
-}
-
-static int role_trans_rule_write(role_trans_rule_t * t, struct policy_file *fp)
-{
-	int nel = 0;
-	size_t items;
-	uint32_t buf[1];
-	role_trans_rule_t *tr;
-
-	for (tr = t; tr; tr = tr->next)
-		nel++;
-	buf[0] = cpu_to_le32(nel);
-	items = put_entry(buf, sizeof(uint32_t), 1, fp);
-	if (items != 1)
-		return POLICYDB_ERROR;
-	for (tr = t; tr; tr = tr->next) {
-		if (role_set_write(&tr->roles, fp))
-			return POLICYDB_ERROR;
-		if (type_set_write(&tr->types, fp))
-			return POLICYDB_ERROR;
-		buf[0] = cpu_to_le32(tr->new_role);
-		items = put_entry(buf, sizeof(uint32_t), 1, fp);
-		if (items != 1)
-			return POLICYDB_ERROR;
-	}
-	return POLICYDB_SUCCESS;
-}
-
-static int role_allow_rule_write(role_allow_rule_t * r, struct policy_file *fp)
-{
-	int nel = 0;
-	size_t items;
-	uint32_t buf[1];
-	role_allow_rule_t *ra;
-
-	for (ra = r; ra; ra = ra->next)
-		nel++;
-	buf[0] = cpu_to_le32(nel);
-	items = put_entry(buf, sizeof(uint32_t), 1, fp);
-	if (items != 1)
-		return POLICYDB_ERROR;
-	for (ra = r; ra; ra = ra->next) {
-		if (role_set_write(&ra->roles, fp))
-			return POLICYDB_ERROR;
-		if (role_set_write(&ra->new_roles, fp))
-			return POLICYDB_ERROR;
-	}
-	return POLICYDB_SUCCESS;
-}
-
-static int range_trans_rule_write(range_trans_rule_t * t,
-				  struct policy_file *fp)
-{
-	int nel = 0;
-	size_t items;
-	uint32_t buf[1];
-	range_trans_rule_t *rt;
-
-	for (rt = t; rt; rt = rt->next)
-		nel++;
-	buf[0] = cpu_to_le32(nel);
-	items = put_entry(buf, sizeof(uint32_t), 1, fp);
-	if (items != 1)
-		return POLICYDB_ERROR;
-	for (rt = t; rt; rt = rt->next) {
-		if (type_set_write(&rt->stypes, fp))
-			return POLICYDB_ERROR;
-		if (type_set_write(&rt->ttypes, fp))
-			return POLICYDB_ERROR;
-		if (ebitmap_write(&rt->tclasses, fp))
-			return POLICYDB_ERROR;
-		if (mls_write_semantic_range_helper(&rt->trange, fp))
-			return POLICYDB_ERROR;
-	}
-	return POLICYDB_SUCCESS;
-}
-
-static int scope_index_write(scope_index_t * scope_index,
-			     unsigned int num_scope_syms,
-			     struct policy_file *fp)
-{
-	unsigned int i;
-	uint32_t buf[1];
-	for (i = 0; i < num_scope_syms; i++) {
-		if (ebitmap_write(scope_index->scope + i, fp) == -1) {
-			return POLICYDB_ERROR;
-		}
-	}
-	buf[0] = cpu_to_le32(scope_index->class_perms_len);
-	if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) {
-		return POLICYDB_ERROR;
-	}
-	for (i = 0; i < scope_index->class_perms_len; i++) {
-		if (ebitmap_write(scope_index->class_perms_map + i, fp) == -1) {
-			return POLICYDB_ERROR;
-		}
-	}
-	return POLICYDB_SUCCESS;
-}
-
-static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms,
-			     policydb_t * p, struct policy_file *fp)
-{
-	struct policy_data pd;
-	uint32_t buf[2];
-	int i;
-	buf[0] = cpu_to_le32(decl->decl_id);
-	buf[1] = cpu_to_le32(decl->enabled);
-	if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) {
-		return POLICYDB_ERROR;
-	}
-	if (cond_write_list(p, decl->cond_list, fp) == -1 ||
-	    avrule_write_list(decl->avrules, fp) == -1 ||
-	    role_trans_rule_write(decl->role_tr_rules, fp) == -1 ||
-	    role_allow_rule_write(decl->role_allow_rules, fp) == -1) {
-		return POLICYDB_ERROR;
-	}
-	if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
-	    range_trans_rule_write(decl->range_tr_rules, fp) == -1) {
-		return POLICYDB_ERROR;
-	}
-	if (scope_index_write(&decl->required, num_scope_syms, fp) == -1 ||
-	    scope_index_write(&decl->declared, num_scope_syms, fp) == -1) {
-		return POLICYDB_ERROR;
-	}
-	pd.fp = fp;
-	pd.p = p;
-	for (i = 0; i < num_scope_syms; i++) {
-		buf[0] = cpu_to_le32(decl->symtab[i].nprim);
-		buf[1] = cpu_to_le32(decl->symtab[i].table->nel);
-		if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) {
-			return POLICYDB_ERROR;
-		}
-		if (hashtab_map(decl->symtab[i].table, write_f[i], &pd)) {
-			return POLICYDB_ERROR;
-		}
-	}
-	return POLICYDB_SUCCESS;
-}
-
-static int avrule_block_write(avrule_block_t * block, int num_scope_syms,
-			      policydb_t * p, struct policy_file *fp)
-{
-	/* first write a count of the total number of blocks */
-	uint32_t buf[1], num_blocks = 0;
-	avrule_block_t *cur;
-	for (cur = block; cur != NULL; cur = cur->next) {
-		num_blocks++;
-	}
-	buf[0] = cpu_to_le32(num_blocks);
-	if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) {
-		return POLICYDB_ERROR;
-	}
-
-	/* now write each block */
-	for (cur = block; cur != NULL; cur = cur->next) {
-		uint32_t num_decls = 0;
-		avrule_decl_t *decl;
-		/* write a count of number of branches */
-		for (decl = cur->branch_list; decl != NULL; decl = decl->next) {
-			num_decls++;
-		}
-		buf[0] = cpu_to_le32(num_decls);
-		if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) {
-			return POLICYDB_ERROR;
-		}
-		for (decl = cur->branch_list; decl != NULL; decl = decl->next) {
-			if (avrule_decl_write(decl, num_scope_syms, p, fp) ==
-			    -1) {
-				return POLICYDB_ERROR;
-			}
-		}
-	}
-	return POLICYDB_SUCCESS;
-}
-
-static int scope_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
-{
-	scope_datum_t *scope = (scope_datum_t *) datum;
-	struct policy_data *pd = ptr;
-	struct policy_file *fp = pd->fp;
-	uint32_t static_buf[32], *dyn_buf = NULL, *buf;
-	size_t key_len = strlen(key);
-	unsigned int items = 2 + scope->decl_ids_len, i;
-
-	if (items >= (sizeof(static_buf) / 4)) {
-		/* too many things required, so dynamically create a
-		 * buffer.  this would have been easier with C99's
-		 * dynamic arrays... */
-		if ((dyn_buf = malloc(items * sizeof(*dyn_buf))) == NULL) {
-			return POLICYDB_ERROR;
-		}
-		buf = dyn_buf;
-	} else {
-		buf = static_buf;
-	}
-	buf[0] = cpu_to_le32(key_len);
-	if (put_entry(buf, sizeof(*buf), 1, fp) != 1 ||
-	    put_entry(key, 1, key_len, fp) != key_len) {
-		return POLICYDB_ERROR;
-	}
-	buf[0] = cpu_to_le32(scope->scope);
-	buf[1] = cpu_to_le32(scope->decl_ids_len);
-	for (i = 0; i < scope->decl_ids_len; i++) {
-		buf[2 + i] = cpu_to_le32(scope->decl_ids[i]);
-	}
-	if (put_entry(buf, sizeof(*buf), items, fp) != items) {
-		free(dyn_buf);
-		return POLICYDB_ERROR;
-	}
-	free(dyn_buf);
-	return POLICYDB_SUCCESS;
-}
-
 /*
  * Write the configuration data in a policy database
  * structure to a policy database binary representation
@@ -1536,15 +1103,9 @@ int policydb_write(policydb_t * p, struc
 
 	/* Write the magic number and string identifiers. */
 	items = 0;
-	if (p->policy_type == POLICY_KERN) {
-		buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
-		len = strlen(POLICYDB_STRING);
-		policydb_str = POLICYDB_STRING;
-	} else {
-		buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC);
-		len = strlen(POLICYDB_MOD_STRING);
-		policydb_str = POLICYDB_MOD_STRING;
-	}
+	buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
+	len = strlen(POLICYDB_STRING);
+	policydb_str = POLICYDB_STRING;
 	buf[items++] = cpu_to_le32(len);
 	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
 	if (items != items2)
@@ -1555,16 +1116,13 @@ int policydb_write(policydb_t * p, struc
 
 	/* Write the version, config, and table sizes. */
 	items = 0;
-	info = policydb_lookup_compat(p->policyvers, p->policy_type);
+	info = policydb_lookup_compat(p->policyvers);
 	if (!info) {
 		ERR(fp->handle, "compatibility lookup failed for policy "
 		    "version %d", p->policyvers);
 		return POLICYDB_ERROR;
 	}
 
-	if (p->policy_type != POLICY_KERN) {
-		buf[items++] = cpu_to_le32(p->policy_type);
-	}
 	buf[items++] = cpu_to_le32(p->policyvers);
 	buf[items++] = cpu_to_le32(config);
 	buf[items++] = cpu_to_le32(info->sym_num);
@@ -1574,25 +1132,6 @@ int policydb_write(policydb_t * p, struc
 	if (items != items2)
 		return POLICYDB_ERROR;
 
-	if (p->policy_type == POLICY_MOD) {
-		/* Write module name and version */
-		len = strlen(p->name);
-		buf[0] = cpu_to_le32(len);
-		items = put_entry(buf, sizeof(uint32_t), 1, fp);
-		if (items != 1)
-			return POLICYDB_ERROR;
-		items = put_entry(p->name, 1, len, fp);
-		if (items != len)
-			return POLICYDB_ERROR;
-		len = strlen(p->version);
-		buf[0] = cpu_to_le32(len);
-		items = put_entry(buf, sizeof(uint32_t), 1, fp);
-		if (items != 1)
-			return POLICYDB_ERROR;
-		items = put_entry(p->version, 1, len, fp);
-		if (items != len)
-			return POLICYDB_ERROR;
-	}
 	num_syms = info->sym_num;
 	for (i = 0; i < num_syms; i++) {
 		buf[0] = cpu_to_le32(p->symtab[i].nprim);
@@ -1604,52 +1143,33 @@ int policydb_write(policydb_t * p, struc
 			return POLICYDB_ERROR;
 	}
 
-	if (p->policy_type == POLICY_KERN) {
-		if (avtab_write(p, &p->te_avtab, fp))
-			return POLICYDB_ERROR;
-		if (p->policyvers < POLICYDB_VERSION_BOOL) {
-			if (p->p_bools.nprim)
-				WARN(fp->handle, "Discarding "
-				     "booleans and conditional rules");
-		} else {
-			if (cond_write_list(p, p->cond_list, fp))
-				return POLICYDB_ERROR;
-		}
-		if (role_trans_write(p->role_tr, fp))
-			return POLICYDB_ERROR;
-		if (role_allow_write(p->role_allow, fp))
-			return POLICYDB_ERROR;
+	if (avtab_write(p, &p->te_avtab, fp))
+		return POLICYDB_ERROR;
+	if (p->policyvers < POLICYDB_VERSION_BOOL) {
+		if (p->p_bools.nprim)
+			WARN(fp->handle, "Discarding "
+			     "booleans and conditional rules");
 	} else {
-		if (avrule_block_write(p->global, num_syms, p, fp) == -1) {
+		if (cond_write_list(p, p->cond_list, fp))
 			return POLICYDB_ERROR;
-		}
-
-		for (i = 0; i < num_syms; i++) {
-			buf[0] = cpu_to_le32(p->scope[i].table->nel);
-			if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) {
-				return POLICYDB_ERROR;
-			}
-			if (hashtab_map(p->scope[i].table, scope_write, &pd))
-				return POLICYDB_ERROR;
-		}
 	}
+	if (role_trans_write(p->role_tr, fp))
+		return POLICYDB_ERROR;
+	if (role_allow_write(p->role_allow, fp))
+		return POLICYDB_ERROR;
 
 	if (ocontext_write(info, p, fp) == -1 || genfs_write(p, fp) == -1) {
 		return POLICYDB_ERROR;
 	}
 
-	if ((p->policyvers >= POLICYDB_VERSION_MLS
-	     && p->policy_type == POLICY_KERN)
-	    || (p->policyvers >= MOD_POLICYDB_VERSION_MLS
-		&& p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS
-		&& p->policy_type == POLICY_BASE)) {
+	if ((p->policyvers >= POLICYDB_VERSION_MLS)
+	    ) {
 		if (range_write(p, fp)) {
 			return POLICYDB_ERROR;
 		}
 	}
 
-	if (p->policy_type == POLICY_KERN
-	    && p->policyvers >= POLICYDB_VERSION_AVTAB) {
+	if (p->policyvers >= POLICYDB_VERSION_AVTAB) {
 		for (i = 0; i < p->p_types.nprim; i++) {
 			if (ebitmap_write(&p->type_attr_map[i], fp) == -1)
 				return POLICYDB_ERROR;
--- foo.orig/libsepol/include/sepol/policydb/avrule_block.h
+++ foo/libsepol/include/sepol/policydb/avrule_block.h
@@ -22,16 +22,6 @@
 
 #include <sepol/policydb/policydb.h>
 
-extern avrule_block_t *avrule_block_create(void);
-extern void avrule_block_destroy(avrule_block_t * x);
-extern avrule_decl_t *avrule_decl_create(uint32_t decl_id);
-extern void avrule_decl_destroy(avrule_decl_t * x);
-extern void avrule_block_list_destroy(avrule_block_t * x);
-extern avrule_decl_t *get_avrule_decl(policydb_t * p, uint32_t decl_id);
-extern cond_list_t *get_decl_cond_list(policydb_t * p,
-				       avrule_decl_t * decl,
-				       cond_list_t * cond);
-extern int is_id_enabled(char *id, policydb_t * p, int symbol_table);
 extern int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p);
 
 #endif
--- foo.orig/libsepol/include/sepol/policydb/conditional.h
+++ foo/libsepol/include/sepol/policydb/conditional.h
@@ -77,9 +77,6 @@ typedef struct cond_node {
 	/* these true/false lists point into te_avtab when that is used */
 	cond_av_list_t *true_list;
 	cond_av_list_t *false_list;
-	/* and these are using during parsing and for modules */
-	avrule_t *avtrue_list;
-	avrule_t *avfalse_list;
 	/* these fields are not written to binary policy */
 	unsigned int nbools;
 	uint32_t bool_ids[COND_MAX_BOOLS];
@@ -112,6 +109,9 @@ extern avtab_datum_t *cond_av_list_searc
 
 extern void cond_av_list_destroy(cond_av_list_t * list);
 
+extern int expand_cond_av_list(policydb_t *p, cond_av_list_t *l,
+		cond_av_list_t ** newl, avtab_t * expa);
+
 extern void cond_optimize_lists(cond_list_t * cl);
 
 extern int cond_policydb_init(policydb_t * p);
--- foo.orig/libsepol/include/sepol/policydb/constraint.h
+++ foo/libsepol/include/sepol/policydb/constraint.h
@@ -56,7 +56,7 @@ typedef struct constraint_expr {
 	uint32_t op;		/* operator */
 
 	ebitmap_t names;	/* names */
-	struct type_set *type_names;
+	ebitmap_t *type_names;
 
 	struct constraint_expr *next;	/* next expression */
 } constraint_expr_t;
--- foo.orig/libsepol/include/sepol/policydb/flask_types.h
+++ foo/libsepol/include/sepol/policydb/flask_types.h
@@ -46,7 +46,6 @@ typedef uint16_t sepol_security_class_t;
 #define SEPOL_SECCLASS_NULL			0x0000	/* no class */
 
 #define SELINUX_MAGIC 0xf97cff8c
-#define SELINUX_MOD_MAGIC 0xf97cff8d
 
 typedef uint32_t sepol_security_id_t;
 #define SEPOL_SECSID_NULL 0
--- foo.orig/libsepol/include/sepol/policydb.h
+++ foo/libsepol/include/sepol/policydb.h
@@ -56,11 +56,6 @@ extern void sepol_policy_file_set_handle
 extern int sepol_policydb_create(sepol_policydb_t ** p);
 extern void sepol_policydb_free(sepol_policydb_t * p);
 
-/* Legal types of policies that the policydb can represent. */
-#define SEPOL_POLICY_KERN	0
-#define SEPOL_POLICY_BASE	1
-#define SEPOL_POLICY_MOD	2
-
 /*
  * Range of policy versions for the kernel policy type supported
  * by this library.
@@ -74,7 +69,7 @@ extern int sepol_policy_kern_vers_max(vo
  * policy type.  
  * Returns -1 if the policy type is not legal.
  */
-extern int sepol_policydb_set_typevers(sepol_policydb_t * p, unsigned int type);
+extern int sepol_policydb_set_typevers(sepol_policydb_t * p);
 
 /*
  * Set the policy version to a different value.
--- foo.orig/libsepol/include/sepol/policydb/policydb.h
+++ foo/libsepol/include/sepol/policydb/policydb.h
@@ -76,21 +76,7 @@
  * users, roles, types, sensitivities, categories, etc.
  */
 
-/* type set preserves data needed by modules such as *, ~ and attributes */
-typedef struct type_set {
-	ebitmap_t types;
-	ebitmap_t negset;
-#define TYPE_STAR 1
-#define TYPE_COMP 2
-	uint32_t flags;
-} type_set_t;
-
-typedef struct role_set {
-	ebitmap_t roles;
-#define ROLE_STAR 1
-#define ROLE_COMP 2
-	uint32_t flags;
-} role_set_t;
+
 
 /* Permission attributes */
 typedef struct perm_datum {
@@ -117,7 +103,7 @@ typedef struct class_datum {
 typedef struct role_datum {
 	symtab_datum_t s;
 	ebitmap_t dominates;	/* set of roles dominated by this role */
-	type_set_t types;	/* set of authorized types for role */
+	ebitmap_t types;	/* set of authorized types for role */
 	ebitmap_t cache;	/* This is an expanded set used for context validation during parsing */
 } role_datum_t;
 
@@ -148,7 +134,7 @@ typedef struct type_datum {
 /* User attributes */
 typedef struct user_datum {
 	symtab_datum_t s;
-	role_set_t roles;	/* set of authorized roles for user */
+	ebitmap_t roles;  /* set of authorized roles for user */
 	mls_semantic_range_t range;	/* MLS range (min. - max.) for user */
 	mls_semantic_level_t dfltlevel;	/* default login MLS level for user */
 	ebitmap_t cache;	/* This is an expanded set used for context validation during parsing */
@@ -188,57 +174,6 @@ struct cond_node;
 typedef struct cond_node cond_list_t;
 struct cond_av_list;
 
-typedef struct class_perm_node {
-	uint32_t class;
-	uint32_t data;		/* permissions or new type */
-	struct class_perm_node *next;
-} class_perm_node_t;
-
-typedef struct avrule {
-/* these typedefs are almost exactly the same as those in avtab.h - they are
- * here because of the need to include neverallow and dontaudit messages */
-#define AVRULE_ALLOWED     1
-#define AVRULE_AUDITALLOW  2
-#define AVRULE_AUDITDENY   4
-#define AVRULE_DONTAUDIT   8
-#define AVRULE_NEVERALLOW 128
-#define AVRULE_AV         (AVRULE_ALLOWED | AVRULE_AUDITALLOW | AVRULE_AUDITDENY | AVRULE_DONTAUDIT | AVRULE_NEVERALLOW)
-#define AVRULE_TRANSITION 16
-#define AVRULE_MEMBER     32
-#define AVRULE_CHANGE     64
-#define AVRULE_TYPE       (AVRULE_TRANSITION | AVRULE_MEMBER | AVRULE_CHANGE)
-	uint32_t specified;
-#define RULE_SELF 1
-	uint32_t flags;
-	type_set_t stypes;
-	type_set_t ttypes;
-	class_perm_node_t *perms;
-	unsigned long line;	/* line number from policy.conf where
-				 * this rule originated  */
-	struct avrule *next;
-} avrule_t;
-
-typedef struct role_trans_rule {
-	role_set_t roles;	/* current role */
-	type_set_t types;	/* program executable type */
-	uint32_t new_role;	/* new role */
-	struct role_trans_rule *next;
-} role_trans_rule_t;
-
-typedef struct role_allow_rule {
-	role_set_t roles;	/* current role */
-	role_set_t new_roles;	/* new roles */
-	struct role_allow_rule *next;
-} role_allow_rule_t;
-
-typedef struct range_trans_rule {
-	type_set_t stypes;
-	type_set_t ttypes;
-	ebitmap_t tclasses;
-	mls_semantic_range_t trange;
-	struct range_trans_rule *next;
-} range_trans_rule_t;
-
 /*
  * The configuration data includes security contexts for 
  * initial SIDs, unlabeled file systems, TCP and UDP port numbers, 
@@ -301,92 +236,12 @@ typedef struct genfs {
 
 /* section: module information */
 
-/* scope_index_t holds all of the symbols that are in scope in a
- * particular situation.  The bitmaps are indices (and thus must
- * subtract one) into the global policydb->scope array. */
-typedef struct scope_index {
-	ebitmap_t scope[SYM_NUM];
-#define p_classes_scope scope[SYM_CLASSES]
-#define p_roles_scope scope[SYM_ROLES]
-#define p_types_scope scope[SYM_TYPES]
-#define p_users_scope scope[SYM_USERS]
-#define p_bools_scope scope[SYM_BOOLS]
-#define p_sens_scope scope[SYM_LEVELS]
-#define p_cat_scope scope[SYM_CATS]
-
-	/* this array maps from class->value to the permissions within
-	 * scope.  if bit (perm->value - 1) is set in map
-	 * class_perms_map[class->value - 1] then that permission is
-	 * enabled for this class within this decl.  */
-	ebitmap_t *class_perms_map;
-	/* total number of classes in class_perms_map array */
-	uint32_t class_perms_len;
-} scope_index_t;
-
-/* a list of declarations for a particular avrule_decl */
-
-/* These two structs declare a block of policy that has TE and RBAC
- * statements and declarations.  The root block (the global policy)
- * can never have an ELSE branch. */
-typedef struct avrule_decl {
-	uint32_t decl_id;
-	uint32_t enabled;	/* whether this block is enabled */
 
-	cond_list_t *cond_list;
-	avrule_t *avrules;
-	role_trans_rule_t *role_tr_rules;
-	role_allow_rule_t *role_allow_rules;
-	range_trans_rule_t *range_tr_rules;
-	scope_index_t required;	/* symbols needed to activate this block */
-	scope_index_t declared;	/* symbols declared within this block */
 
-	/* for additive statements (type attribute, roles, and users) */
-	symtab_t symtab[SYM_NUM];
 
-	/* In a linked module this will contain the name of the module
-	 * from which this avrule_decl originated. */
-	char *module_name;
-
-	struct avrule_decl *next;
-} avrule_decl_t;
-
-typedef struct avrule_block {
-	avrule_decl_t *branch_list;
-	avrule_decl_t *enabled;	/* pointer to which branch is enabled.  this is
-				   used in linking and never written to disk */
-#define AVRULE_OPTIONAL 1
-	uint32_t flags;		/* any flags for this block, currently just optional */
-	struct avrule_block *next;
-} avrule_block_t;
-
-/* Every identifier has its own scope datum.  The datum describes if
- * the item is to be included into the final policy during
- * expansion. */
-typedef struct scope_datum {
-/* Required for this decl */
-#define SCOPE_REQ  1
-/* Declared in this decl */
-#define SCOPE_DECL 2
-	uint32_t scope;
-	uint32_t *decl_ids;
-	uint32_t decl_ids_len;
-	/* decl_ids is a list of avrule_decl's that declare/require
-	 * this symbol.  If scope==SCOPE_DECL then this is a list of
-	 * declarations.  If the symbol may only be declared once
-	 * (types, bools) then decl_ids_len will be exactly 1.  For
-	 * implicitly declared things (roles, users) then decl_ids_len
-	 * will be at least 1. */
-} scope_datum_t;
 
 /* The policy database */
 typedef struct policydb {
-#define POLICY_KERN SEPOL_POLICY_KERN
-#define POLICY_BASE SEPOL_POLICY_BASE
-#define POLICY_MOD SEPOL_POLICY_MOD
-	uint32_t policy_type;
-	char *name;
-	char *version;
-
 	/* Set when the policydb is modified such that writing is unsupported */
 	int unsupported_format;
 
@@ -421,19 +276,6 @@ typedef struct policydb {
 	user_datum_t **user_val_to_struct;
 	type_datum_t **type_val_to_struct;
 
-	/* module stuff section -- used in parsing and for modules */
-
-	/* keep track of the scope for every identifier.  these are
-	 * hash tables, where the key is the identifier name and value
-	 * a scope_datum_t.  as a convenience, one may use the
-	 * p_*_macros (cf. struct scope_index_t declaration). */
-	symtab_t scope[SYM_NUM];
-
-	/* module rule storage */
-	avrule_block_t *global;
-	/* avrule_decl index used for link/expand */
-	avrule_decl_t **decl_val_to_struct;
-
 	/* compiled storage of rules - use for the kernel policy */
 
 	/* type enforcement access vectors and transitions */
@@ -502,32 +344,12 @@ extern int policydb_context_isvalid(cons
 				    const context_struct_t * c);
 
 extern void symtabs_destroy(symtab_t * symtab);
-extern int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p);
 typedef void (*hashtab_destroy_func_t) (hashtab_key_t k, hashtab_datum_t d,
 					void *args);
 extern hashtab_destroy_func_t get_symtab_destroy_func(int sym_num);
 
-extern void class_perm_node_init(class_perm_node_t * x);
-extern void type_set_init(type_set_t * x);
-extern void type_set_destroy(type_set_t * x);
-extern int type_set_cpy(type_set_t * dst, type_set_t * src);
-extern int type_set_or_eq(type_set_t * dst, type_set_t * other);
-extern void role_set_init(role_set_t * x);
-extern void role_set_destroy(role_set_t * x);
-extern void avrule_init(avrule_t * x);
-extern void avrule_destroy(avrule_t * x);
-extern void avrule_list_destroy(avrule_t * x);
-extern void role_trans_rule_init(role_trans_rule_t * x);
-extern void role_trans_rule_list_destroy(role_trans_rule_t * x);
-
 extern void role_datum_init(role_datum_t * x);
 extern void role_datum_destroy(role_datum_t * x);
-extern void role_allow_rule_init(role_allow_rule_t * x);
-extern void role_allow_rule_destroy(role_allow_rule_t * x);
-extern void role_allow_rule_list_destroy(role_allow_rule_t * x);
-extern void range_trans_rule_init(range_trans_rule_t *x);
-extern void range_trans_rule_destroy(range_trans_rule_t *x);
-extern void range_trans_rule_list_destroy(range_trans_rule_t *x);
 extern void type_datum_init(type_datum_t * x);
 extern void type_datum_destroy(type_datum_t * x);
 extern void user_datum_init(user_datum_t * x);
@@ -537,12 +359,9 @@ extern void level_datum_destroy(level_da
 extern void cat_datum_init(cat_datum_t * x);
 extern void cat_datum_destroy(cat_datum_t * x);
 
-extern int check_assertions(sepol_handle_t * handle,
-			    policydb_t * p, avrule_t * avrules);
-
 extern int symtab_insert(policydb_t * x, uint32_t sym,
 			 hashtab_key_t key, hashtab_datum_t datum,
-			 uint32_t scope, uint32_t avrule_decl_id,
+			 uint32_t avrule_decl_id,
 			 uint32_t * value);
 
 /* A policy "file" may be a memory region referenced by a (data, len) pair
@@ -566,11 +385,11 @@ struct sepol_policy_file {
 
 extern int policydb_read(policydb_t * p, struct policy_file *fp,
 			 unsigned int verbose);
-extern int avrule_read_list(policydb_t * p, avrule_t ** avrules,
-			    struct policy_file *fp);
 
 extern int policydb_write(struct policydb *p, struct policy_file *pf);
 
+extern int expand_avtab(policydb_t *p, avtab_t *a, avtab_t *expa);
+
 #define PERM_SYMTAB_SIZE 32
 
 /* Identify specific policy version changes */
@@ -587,16 +406,6 @@ extern int policydb_write(struct policyd
 #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
 #define POLICYDB_VERSION_MAX	POLICYDB_VERSION_RANGETRANS
 
-/* Module versions and specific changes*/
-#define MOD_POLICYDB_VERSION_BASE	   4
-#define MOD_POLICYDB_VERSION_VALIDATETRANS 5
-#define MOD_POLICYDB_VERSION_MLS	   5
-#define MOD_POLICYDB_VERSION_RANGETRANS	   6
-#define MOD_POLICYDB_VERSION_MLS_USERS	   6
-
-#define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
-#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_MLS_USERS
-
 #define POLICYDB_CONFIG_MLS    1
 
 #define OBJECT_R "object_r"
@@ -604,8 +413,6 @@ extern int policydb_write(struct policyd
 
 #define POLICYDB_MAGIC SELINUX_MAGIC
 #define POLICYDB_STRING "SE Linux"
-#define POLICYDB_MOD_MAGIC SELINUX_MOD_MAGIC
-#define POLICYDB_MOD_STRING "SE Linux Module"
 
 #endif				/* _POLICYDB_H_ */
 
--- foo.orig/libsepol/include/sepol/users.h
+++ foo/libsepol/include/sepol/users.h
@@ -23,12 +23,6 @@ extern void sepol_set_delusers(int on);
 
 /*--------end compatibility----------*/
 
-/* Modify the user, or add it, if the key is not found */
-extern int sepol_user_modify(sepol_handle_t * handle,
-			     sepol_policydb_t * policydb,
-			     const sepol_user_key_t * key,
-			     const sepol_user_t * data);
-
 /* Return the number of users */
 extern int sepol_user_count(sepol_handle_t * handle,
 			    const sepol_policydb_t * p, unsigned int *response);
--- foo.orig/libsepol/src/private.h
+++ foo/libsepol/src/private.h
@@ -29,14 +29,13 @@
 
 /* Policy compatibility information. */
 struct policydb_compat_info {
-	unsigned int type;
 	unsigned int version;
 	unsigned int sym_num;
 	unsigned int ocon_num;
 };
 
-extern struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
-							   unsigned int type);
+extern struct policydb_compat_info *policydb_lookup_compat(unsigned int
+							   version);
 
 /* Reading from a policy "file". */
 static inline void *next_entry(struct policy_file *fp, size_t bytes)
--- foo.orig/libsepol/src/libsepol.map
+++ foo/libsepol/src/libsepol.map
@@ -1,6 +1,6 @@
 {
   global: 
-	sepol_module_package_*; sepol_link_modules; sepol_expand_module; sepol_link_packages;
+	sepol_module_package_*; sepol_link_packages;
 	sepol_bool_*; sepol_genbools*; 
 	sepol_context_*; sepol_mls_*; sepol_check_context;
 	sepol_iface_*; 
@@ -12,5 +12,7 @@
 	sepol_policydb_*; sepol_set_policydb_from_file; 
 	sepol_policy_kern_*;
 	sepol_policy_file_*;
+	expand_avtab;
+	expand_cond_av_list;
   local: *;
 };

-- 

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [POLICYREP] [Patch 5/5] This patch moves dispol to libsepol utilities. No functional changes to dispol. Makefile was modified to build dispol.
  2007-08-16 15:53 [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Mark Goldman
                   ` (3 preceding siblings ...)
  2007-08-16 15:53 ` [POLICYREP] [Patch 4/5] " Mark Goldman
@ 2007-08-16 15:53 ` Mark Goldman
  2007-09-18 14:28 ` [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Joshua Brindle
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Goldman @ 2007-08-16 15:53 UTC (permalink / raw)
  To: selinux

---
 libsepol/utils/Makefile |    3 	3 +	0 -	0 !
 libsepol/utils/dispol.c |  442 	442 +	0 -	0 !
 2 files changed, 445 insertions(+)

--- /dev/null
+++ foo/libsepol/utils/dispol.c
@@ -0,0 +1,442 @@
+
+/* Authors: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
+ *
+ * Copyright (C) 2003 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.
+ */
+
+/*
+ * displaypol.c
+ *
+ * Test program to the contents of a binary policy in text
+ * form.  This program currently only displays the
+ * avtab (including conditional avtab) rules.
+ *
+ * 	displaypol binary_pol_file
+ */
+
+#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/avtab.h>
+#include <sepol/policydb/services.h>
+#include <sepol/policydb/conditional.h>
+#include <sepol/policydb/util.h>
+#include <getopt.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+static policydb_t policydb;
+
+void usage(char *progname)
+{
+	printf("usage:  %s binary_pol_file\n\n", progname);
+	exit(1);
+}
+
+int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
+		       FILE * fp)
+{
+	char *perm;
+	fprintf(fp, "{");
+	perm = sepol_av_to_string(p, key->target_class, mask);
+	if (perm)
+		fprintf(fp, "%s ", perm);
+	fprintf(fp, "}");
+	return 0;
+}
+
+int render_type(uint32_t type, policydb_t * p, FILE * fp)
+{
+	fprintf(fp, "%s", p->p_type_val_to_name[type - 1]);
+	return 0;
+}
+
+int render_key(avtab_key_t * key, policydb_t * p, FILE * fp)
+{
+	char *stype, *ttype, *tclass;
+	stype = p->p_type_val_to_name[key->source_type - 1];
+	ttype = p->p_type_val_to_name[key->target_type - 1];
+	tclass = p->p_class_val_to_name[key->target_class - 1];
+	if (stype && ttype)
+		fprintf(fp, "%s %s : %s ", stype, ttype, tclass);
+	else if (stype)
+		fprintf(fp, "%s %u : %s ", stype, key->target_type, tclass);
+	else if (ttype)
+		fprintf(fp, "%u %s : %s ", key->source_type, ttype, tclass);
+	else
+		fprintf(fp, "%u %u : %s ", key->source_type, key->target_type,
+			tclass);
+	return 0;
+}
+
+/* 'what' values for this function */
+#define	RENDER_UNCONDITIONAL	0x0001	/* render all regardless of enabled state */
+#define RENDER_ENABLED		0x0002
+#define RENDER_DISABLED		0x0004
+#define RENDER_CONDITIONAL	(RENDER_ENABLED|RENDER_DISABLED)
+
+int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what,
+		   policydb_t * p, FILE * fp)
+{
+	if (!(what & RENDER_UNCONDITIONAL)) {
+		if (what != RENDER_CONDITIONAL && (((what & RENDER_ENABLED)
+						    && !(key->
+							 specified &
+							 AVTAB_ENABLED))
+						   || ((what & RENDER_DISABLED)
+						       && (key->
+							   specified &
+							   AVTAB_ENABLED)))) {
+			return 0;	/* doesn't match selection criteria */
+		}
+	}
+
+	if (!(what & RENDER_UNCONDITIONAL)) {
+		if (key->specified & AVTAB_ENABLED)
+			fprintf(fp, "[enabled] ");
+		else if (!(key->specified & AVTAB_ENABLED))
+			fprintf(fp, "[disabled] ");
+	}
+
+	if (key->specified & AVTAB_AV) {
+		if (key->specified & AVTAB_ALLOWED) {
+			fprintf(fp, "allow ");
+			render_key(key, p, fp);
+			render_access_mask(datum->data, key, p, fp);
+			fprintf(fp, ";\n");
+		}
+		if (key->specified & AVTAB_AUDITALLOW) {
+			fprintf(fp, "auditallow ");
+			render_key(key, p, fp);
+			render_access_mask(datum->data, key, p, fp);
+			fprintf(fp, ";\n");
+		}
+		if (key->specified & AVTAB_AUDITDENY) {
+			fprintf(fp, "dontaudit ");
+			render_key(key, p, fp);
+			/* We inverse the mask for dontaudit since the mask is internally stored
+			 * as a auditdeny mask */
+			render_access_mask(~datum->data, key, p, fp);
+			fprintf(fp, ";\n");
+		}
+	} else if (key->specified & AVTAB_TYPE) {
+		if (key->specified & AVTAB_TRANSITION) {
+			fprintf(fp, "type_transition ");
+			render_key(key, p, fp);
+			render_type(datum->data, p, fp);
+			fprintf(fp, ";\n");
+		}
+		if (key->specified & AVTAB_MEMBER) {
+			fprintf(fp, "type_member ");
+			render_key(key, p, fp);
+			render_type(datum->data, p, fp);
+			fprintf(fp, ";\n");
+		}
+		if (key->specified & AVTAB_CHANGE) {
+			fprintf(fp, "type_change ");
+			render_key(key, p, fp);
+			render_type(datum->data, p, fp);
+			fprintf(fp, ";\n");
+		}
+	} else {
+		fprintf(fp, "     ERROR: no valid rule type specified\n");
+		return -1;
+	}
+	return 0;
+}
+
+int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp)
+{
+	int i;
+	avtab_ptr_t cur;
+	avtab_t expa;
+
+	if (avtab_init(&expa))
+		goto oom;
+	if (expand_avtab(p, a, &expa)) {
+		avtab_destroy(&expa);
+		goto oom;
+	}
+
+	/* hmm...should have used avtab_map. */
+	for (i = 0; i < AVTAB_SIZE; i++) {
+		for (cur = expa.htable[i]; cur; cur = cur->next) {
+			render_av_rule(&cur->key, &cur->datum, what, p, fp);
+		}
+	}
+	avtab_destroy(&expa);
+	fprintf(fp, "\n");
+	return 0;
+      oom:
+	fprintf(stderr, "out of memory\n");
+	return 1;
+}
+
+int display_bools(policydb_t * p, FILE * fp)
+{
+	int i;
+
+	for (i = 0; i < p->p_bools.nprim; i++) {
+		fprintf(fp, "%s : %d\n", p->p_bool_val_to_name[i],
+			p->bool_val_to_struct[i]->state);
+	}
+	return 0;
+}
+
+void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
+{
+
+	cond_expr_t *cur;
+	for (cur = exp; cur != NULL; cur = cur->next) {
+		switch (cur->expr_type) {
+		case COND_BOOL:
+			fprintf(fp, "%s ",
+				p->p_bool_val_to_name[cur->bool - 1]);
+			break;
+		case COND_NOT:
+			fprintf(fp, "! ");
+			break;
+		case COND_OR:
+			fprintf(fp, "|| ");
+			break;
+		case COND_AND:
+			fprintf(fp, "&& ");
+			break;
+		case COND_XOR:
+			fprintf(fp, "^ ");
+			break;
+		case COND_EQ:
+			fprintf(fp, "== ");
+			break;
+		case COND_NEQ:
+			fprintf(fp, "!= ");
+			break;
+		default:
+			fprintf(fp, "error!");
+			break;
+		}
+	}
+}
+
+int display_cond_expressions(policydb_t * p, FILE * fp)
+{
+	cond_node_t *cur;
+	cond_av_list_t *av_cur, *expl = NULL;
+	avtab_t expa;
+
+	for (cur = p->cond_list; cur != NULL; cur = cur->next) {
+		fprintf(fp, "expression: ");
+		display_expr(p, cur->expr, fp);
+		fprintf(fp, "current state: %d\n", cur->cur_state);
+		fprintf(fp, "True list:\n");
+		if (avtab_init(&expa))
+			goto oom;
+		if (expand_cond_av_list(p, cur->true_list, &expl, &expa)) {
+			avtab_destroy(&expa);
+			goto oom;
+		}
+		for (av_cur = expl; av_cur != NULL; av_cur = av_cur->next) {
+			fprintf(fp, "\t");
+			render_av_rule(&av_cur->node->key, &av_cur->node->datum,
+				       RENDER_CONDITIONAL, p, fp);
+		}
+		cond_av_list_destroy(expl);
+		avtab_destroy(&expa);
+		fprintf(fp, "False list:\n");
+		if (avtab_init(&expa))
+			goto oom;
+		if (expand_cond_av_list(p, cur->false_list, &expl, &expa)) {
+			avtab_destroy(&expa);
+			goto oom;
+		}
+		for (av_cur = expl; av_cur != NULL; av_cur = av_cur->next) {
+			fprintf(fp, "\t");
+			render_av_rule(&av_cur->node->key, &av_cur->node->datum,
+				       RENDER_CONDITIONAL, p, fp);
+		}
+		cond_av_list_destroy(expl);
+		avtab_destroy(&expa);
+	}
+	return 0;
+
+      oom:
+	fprintf(stderr, "out of memory\n");
+	return 1;
+}
+
+int change_bool(char *name, int state, policydb_t * p, FILE * fp)
+{
+	cond_bool_datum_t *bool;
+
+	bool = hashtab_search(p->p_bools.table, name);
+	if (bool == NULL) {
+		fprintf(fp, "Could not find bool %s\n", name);
+		return -1;
+	}
+	bool->state = state;
+	evaluate_conds(p);
+	return 0;
+}
+
+int menu()
+{
+	printf("\nSelect a command:\n");
+	printf("1)  display unconditional AVTAB\n");
+	printf("2)  display conditional AVTAB (entirely)\n");
+	printf("3)  display conditional AVTAG (only ENABLED rules)\n");
+	printf("4)  display conditional AVTAB (only DISABLED rules)\n");
+	printf("5)  display conditional bools\n");
+	printf("6)  display conditional expressions\n");
+	printf("7)  change a boolean value\n");
+	printf("\n");
+	printf("f)  set output file\n");
+	printf("m)  display menu\n");
+	printf("q)  quit\n");
+	return 0;
+}
+
+int main(int argc, char **argv)
+{
+	FILE *out_fp = stdout;
+	char ans[81], OutfileName[121];
+	int fd, ret;
+	struct stat sb;
+	void *map;
+	char *name;
+	int state;
+	struct policy_file pf;
+
+	if (argc != 2)
+		usage(argv[0]);
+
+	fd = open(argv[1], O_RDONLY);
+	if (fd < 0) {
+		fprintf(stderr, "Can't open '%s':  %s\n",
+			argv[1], strerror(errno));
+		exit(1);
+	}
+	if (fstat(fd, &sb) < 0) {
+		fprintf(stderr, "Can't stat '%s':  %s\n",
+			argv[1], strerror(errno));
+		exit(1);
+	}
+	map =
+	    mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+	if (map == MAP_FAILED) {
+		fprintf(stderr, "Can't map '%s':  %s\n",
+			argv[1], strerror(errno));
+		exit(1);
+	}
+
+	/* read the binary policy */
+	fprintf(out_fp, "Reading policy...\n");
+	pf.type = PF_USE_MEMORY;
+	pf.data = map;
+	pf.len = sb.st_size;
+	if (policydb_init(&policydb)) {
+		fprintf(stderr, "%s:  Out of memory!\n", argv[0]);
+		exit(1);
+	}
+	ret = policydb_read(&policydb, &pf, 1);
+	if (ret) {
+		fprintf(stderr,
+			"%s:  error(s) encountered while parsing configuration\n",
+			argv[0]);
+		exit(1);
+	}
+
+	fprintf(stdout, "binary policy file loaded\n\n");
+	close(fd);
+
+	menu();
+	for (;;) {
+		printf("\nCommand (\'m\' for menu):  ");
+		fgets(ans, sizeof(ans), stdin);
+		switch (ans[0]) {
+
+		case '1':
+			display_avtab(&policydb.te_avtab, RENDER_UNCONDITIONAL,
+				      &policydb, out_fp);
+			break;
+		case '2':
+			display_avtab(&policydb.te_cond_avtab,
+				      RENDER_CONDITIONAL, &policydb, out_fp);
+			break;
+		case '3':
+			display_avtab(&policydb.te_cond_avtab, RENDER_ENABLED,
+				      &policydb, out_fp);
+			break;
+		case '4':
+			display_avtab(&policydb.te_cond_avtab, RENDER_DISABLED,
+				      &policydb, out_fp);
+			break;
+		case '5':
+			display_bools(&policydb, out_fp);
+			break;
+		case '6':
+			display_cond_expressions(&policydb, out_fp);
+			break;
+		case '7':
+			printf("name? ");
+			fgets(ans, sizeof(ans), stdin);
+			ans[strlen(ans) - 1] = 0;
+
+			name = malloc((strlen(ans) + 1) * sizeof(char));
+			if (name == NULL) {
+				fprintf(stderr, "couldn't malloc string.\n");
+				break;
+			}
+			strcpy(name, ans);
+
+			printf("state? ");
+			fgets(ans, sizeof(ans), stdin);
+			ans[strlen(ans) - 1] = 0;
+
+			if (atoi(ans))
+				state = 1;
+			else
+				state = 0;
+
+			change_bool(name, state, &policydb, out_fp);
+			free(name);
+			break;
+		case 'f':
+			printf
+			    ("\nFilename for output (<CR> for screen output): ");
+			fgets(OutfileName, sizeof(OutfileName), stdin);
+			OutfileName[strlen(OutfileName) - 1] = '\0';	/* fix_string (remove LF) */
+			if (strlen(OutfileName) == 0)
+				out_fp = stdout;
+			else if ((out_fp = fopen(OutfileName, "w")) == NULL) {
+				fprintf(stderr, "Cannot open output file %s\n",
+					OutfileName);
+				out_fp = stdout;
+			}
+			if (out_fp != stdout)
+				printf("\nOutput to file: %s\n", OutfileName);
+			break;
+		case 'q':
+			policydb_destroy(&policydb);
+			exit(0);
+			break;
+		case 'm':
+			menu();
+			break;
+		default:
+			printf("\nInvalid choice\n");
+			menu();
+			break;
+
+		}
+	}
+}
+
+/* FLASK */
--- foo.orig/libsepol/utils/Makefile
+++ foo/libsepol/utils/Makefile
@@ -6,6 +6,9 @@ CFLAGS ?= -Wall
 override CFLAGS += -I../include
 LDLIBS += -L../src -lsepol 
 
+LIBDIR=$(PREFIX)/lib
+LDLIBS=-lfl -lsepol -lselinux $(LIBDIR)/libsepol.a -L$(LIBDIR)
+
 TARGETS=$(patsubst %.c,%,$(wildcard *.c))
 
 all: $(TARGETS)

-- 

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch
  2007-08-16 15:53 [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Mark Goldman
                   ` (4 preceding siblings ...)
  2007-08-16 15:53 ` [POLICYREP] [Patch 5/5] This patch moves dispol to libsepol utilities. No functional changes to dispol. Makefile was modified to build dispol Mark Goldman
@ 2007-09-18 14:28 ` Joshua Brindle
  5 siblings, 0 replies; 7+ messages in thread
From: Joshua Brindle @ 2007-09-18 14:28 UTC (permalink / raw)
  To: Mark Goldman; +Cc: selinux

Mark Goldman wrote:
> This patchset removes module support from libsepol.  This
> patchset is in support of the policyrep work.
>
> Patches one and two removes the files that are solely for 
> supporting modular policies. 
>
> Patch three and four eliminates the various structures that 
> supported modular policies. All functional changes occur in 
> this patch.
>
> Patch five puts dispol in libsepol's utils directory.
> Dispol was not modified in this move.
>
> This e-mail splits the original patches up so that they will go
> through the list-serv without being bounced.
>
> -mdg
>
> Signed-off-by: Joshua Brindle <jbrindle@tresys.com>
>   

Merged into the policyrep branch with changes necessary due to the 
alignment patch that was applied to trunk.


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-09-18 14:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-16 15:53 [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Mark Goldman
2007-08-16 15:53 ` [POLICYREP] [Patch 1/5] << Part 1 >> This patch removes files that existed solely to support modular policies Mark Goldman
2007-08-16 15:53 ` [POLICYREP] [Patch 2/5] " Mark Goldman
2007-08-16 15:53 ` [POLICYREP] [Patch 3/5] << part 1 >> This patch does all the functional work of removing the module support code Mark Goldman
2007-08-16 15:53 ` [POLICYREP] [Patch 4/5] " Mark Goldman
2007-08-16 15:53 ` [POLICYREP] [Patch 5/5] This patch moves dispol to libsepol utilities. No functional changes to dispol. Makefile was modified to build dispol Mark Goldman
2007-09-18 14:28 ` [POLICYREP] [Patch 0/5] remove modular policy support for policy rep branch Joshua Brindle

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.