
/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */

/*
 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
 *
 *	Support for enhanced MLS infrastructure.
 *
 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
 *
 * 	Added conditional policy language extensions
 * 
 * Updated: Joshua Brindle <jbrindle@tresys.com> and Jason Tang <jtang@tresys.org>
 *
 *	Module writing support
 *
 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
 * Copyright (C) 2003-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 <assert.h>
#include <stdlib.h>

#include <sepol/policydb/ebitmap.h>
#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"
#include "private.h"
#include "mls.h"

struct policy_data {
	struct policy_file *fp;
	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;
	uint32_t buf[32], bit, count;
	uint64_t map;
	size_t items;

	buf[0] = cpu_to_le32(MAPSIZE);
	buf[1] = cpu_to_le32(e->highbit);

	count = 0;
	for (n = e->node; n; n = n->next)
		count++;
	buf[2] = cpu_to_le32(count);

	items = put_entry(buf, sizeof(uint32_t), 3, fp);
	if (items != 3)
		return POLICYDB_ERROR;

	for (n = e->node; n; n = n->next) {
		bit = cpu_to_le32(n->startbit);
		items = put_entry(&bit, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		map = cpu_to_le64(n->map);
		items = put_entry(&map, sizeof(uint64_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;

	}

	return POLICYDB_SUCCESS;
}

/* Ordering of datums in the original avtab format in the policy file. */
static uint16_t spec_order[] = {
	AVTAB_ALLOWED,
	AVTAB_AUDITDENY,
	AVTAB_AUDITALLOW,
	AVTAB_TRANSITION,
	AVTAB_CHANGE,
	AVTAB_MEMBER
};

static int avtab_write_item(policydb_t * p,
			    avtab_ptr_t cur, struct policy_file *fp,
			    unsigned merge, unsigned commit, uint32_t * nel)
{
	avtab_ptr_t node;
	uint16_t buf16[4];
	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 i;

	if (oldvers) {
		/* Generate the old avtab format.
		   Requires merging similar entries if uncond avtab. */
		if (merge) {
			if (cur->merged)
				return POLICYDB_SUCCESS;	/* already merged by prior merge */
		}

		items = 1;	/* item 0 is used for the item count */
		val = cur->key.source_type;
		buf32[items++] = cpu_to_le32(val);
		val = cur->key.target_type;
		buf32[items++] = cpu_to_le32(val);
		val = cur->key.target_class;
		buf32[items++] = cpu_to_le32(val);

		val = cur->key.specified & ~AVTAB_ENABLED;
		if (cur->key.specified & AVTAB_ENABLED)
			val |= AVTAB_ENABLED_OLD;
		set = 1;

		if (merge) {
			/* Merge specifier values for all similar (av or type)
			   entries that have the same key. */
			if (val & AVTAB_AV)
				lookup = AVTAB_AV;
			else if (val & AVTAB_TYPE)
				lookup = AVTAB_TYPE;
			else
				return POLICYDB_ERROR;
			for (node = avtab_search_node_next(cur, lookup);
			     node;
			     node = avtab_search_node_next(node, lookup)) {
				val |= (node->key.specified & ~AVTAB_ENABLED);
				set++;
				if (node->key.specified & AVTAB_ENABLED)
					val |= AVTAB_ENABLED_OLD;
			}
		}

		if (!(val & (AVTAB_AV | AVTAB_TYPE))) {
			ERR(fp->handle, "null entry");
			return POLICYDB_ERROR;
		}
		if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) {
			ERR(fp->handle, "entry has both access "
			    "vectors and types");
			return POLICYDB_ERROR;
		}

		buf32[items++] = cpu_to_le32(val);

		if (merge) {
			/* Include datums for all similar (av or type)
			   entries that have the same key. */
			for (i = 0;
			     i < (sizeof(spec_order) / sizeof(spec_order[0]));
			     i++) {
				if (val & spec_order[i]) {
					if (cur->key.specified & spec_order[i])
						node = cur;
					else {
						node =
						    avtab_search_node_next(cur,
									   spec_order
									   [i]);
						if (nel)
							(*nel)--;	/* one less node */
					}

					if (!node) {
						ERR(fp->handle, "missing node");
						return POLICYDB_ERROR;
					}
					buf32[items++] =
					    cpu_to_le32(node->datum.data);
					set--;
					node->merged = 1;
				}
			}
		} else {
			buf32[items++] = cpu_to_le32(cur->datum.data);
			cur->merged = 1;
			set--;
		}

		if (set) {
			ERR(fp->handle, "data count wrong");
			return POLICYDB_ERROR;
		}

		buf32[0] = cpu_to_le32(items - 1);

		if (commit) {
			/* Commit this item to the policy file. */
			items2 = put_entry(buf32, sizeof(uint32_t), items, fp);
			if (items != items2)
				return POLICYDB_ERROR;
		}

		return POLICYDB_SUCCESS;
	}

	/* Generate the new avtab format. */
	buf16[0] = cpu_to_le16(cur->key.source_type);
	buf16[1] = cpu_to_le16(cur->key.target_type);
	buf16[2] = cpu_to_le16(cur->key.target_class);
	buf16[3] = cpu_to_le16(cur->key.specified);
	items = put_entry(buf16, sizeof(uint16_t), 4, fp);
	if (items != 4)
		return POLICYDB_ERROR;
	buf32[0] = cpu_to_le32(cur->datum.data);
	items = put_entry(buf32, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	return POLICYDB_SUCCESS;
}

static inline void avtab_reset_merged(avtab_t * a)
{
	unsigned int i;
	avtab_ptr_t cur;
	for (i = 0; i < a->nslot; i++) {
		for (cur = a->htable[i]; cur; cur = cur->next)
			cur->merged = 0;
	}
}

static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp)
{
	unsigned int i;
	int rc;
	avtab_t expa;
	avtab_ptr_t cur;
	uint32_t nel;
	size_t items;
	unsigned int oldvers = (p->policy_type == POLICY_KERN
				&& 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;
	} else {
		/* New avtab format.  nel is good to go. */
		nel = cpu_to_le32(a->nel);
		items = put_entry(&nel, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}

	for (i = 0; i < a->nslot; i++) {
		for (cur = a->htable[i]; cur; cur = cur->next) {
			/* If old format, compute final nel.
			   If new format, write out the items. */
			if (avtab_write_item(p, cur, fp, 1, !oldvers, &nel)) {
				rc = -1;
				goto out;
			}
		}
	}

	if (oldvers) {
		/* Old avtab format.
		   Write the computed nel value, then write the items. */
		nel = cpu_to_le32(nel);
		items = put_entry(&nel, sizeof(uint32_t), 1, fp);
		if (items != 1) {
			rc = -1;
			goto out;
		}
		avtab_reset_merged(a);
		for (i = 0; i < a->nslot; i++) {
			for (cur = a->htable[i]; cur; cur = cur->next) {
				if (avtab_write_item(p, cur, fp, 1, 1, NULL)) {
					rc = -1;
					goto out;
				}
			}
		}
	}

	rc = 0;
      out:
	if (oldvers)
		avtab_destroy(&expa);
	return rc;
}

/*
 * 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.
 */
static int mls_write_level(mls_level_t * l, struct policy_file *fp)
{
	uint32_t sens;
	size_t items;

	sens = cpu_to_le32(l->sens);
	items = put_entry(&sens, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	if (ebitmap_write(&l->cat, fp))
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

/*
 * Write a MLS range structure to a policydb binary 
 * representation file.
 */
static int mls_write_range_helper(mls_range_t * r, struct policy_file *fp)
{
	uint32_t buf[3];
	size_t items, items2;
	int eq;

	eq = mls_level_eq(&r->level[1], &r->level[0]);

	items = 1;		/* item 0 is used for the item count */
	buf[items++] = cpu_to_le32(r->level[0].sens);
	if (!eq)
		buf[items++] = cpu_to_le32(r->level[1].sens);
	buf[0] = cpu_to_le32(items - 1);

	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items2 != items)
		return POLICYDB_ERROR;

	if (ebitmap_write(&r->level[0].cat, fp))
		return POLICYDB_ERROR;
	if (!eq)
		if (ebitmap_write(&r->level[1].cat, fp))
			return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int sens_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	level_datum_t *levdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;

	levdatum = (level_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(levdatum->isalias);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (mls_write_level(levdatum->level, fp))
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int cat_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	cat_datum_t *catdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;

	catdatum = (cat_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(catdatum->s.value);
	buf[items++] = cpu_to_le32(catdatum->isalias);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int role_trans_write(policydb_t *p, struct policy_file *fp)
{
	role_trans_t *r = p->role_tr;
	role_trans_t *tr;
	uint32_t buf[3];
	size_t nel, items;
	int new_roletr = (p->policy_type == POLICY_KERN &&
			  p->policyvers >= POLICYDB_VERSION_ROLETRANS);
	int warning_issued = 0;

	nel = 0;
	for (tr = r; tr; tr = tr->next)
		if(new_roletr || tr->tclass == SECCLASS_PROCESS)
			nel++;

	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (tr = r; tr; tr = tr->next) {
		if (!new_roletr && tr->tclass != SECCLASS_PROCESS) {
			if (!warning_issued)
				WARN(fp->handle, "Discarding role_transition "
				     "rules for security classes other than "
				     "\"process\"");
			warning_issued = 1;
			continue;
		}
		buf[0] = cpu_to_le32(tr->role);
		buf[1] = cpu_to_le32(tr->type);
		buf[2] = cpu_to_le32(tr->new_role);
		items = put_entry(buf, sizeof(uint32_t), 3, fp);
		if (items != 3)
			return POLICYDB_ERROR;
		if (new_roletr) {
			buf[0] = cpu_to_le32(tr->tclass);
			items = put_entry(buf, sizeof(uint32_t), 1, fp);
			if (items != 1)
				return POLICYDB_ERROR;
		}
	}

	return POLICYDB_SUCCESS;
}

static int role_allow_write(role_allow_t * r, struct policy_file *fp)
{
	role_allow_t *ra;
	uint32_t buf[2];
	size_t nel, items;

	nel = 0;
	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) {
		buf[0] = cpu_to_le32(ra->role);
		buf[1] = cpu_to_le32(ra->new_role);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

static int filename_trans_write(filename_trans_t * r, struct policy_file *fp)
{
	filename_trans_t *ft;
	uint32_t buf[4];
	size_t nel, items, len;

	nel = 0;
	for (ft = r; ft; ft = ft->next)
		nel++;
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (ft = r; ft; ft = ft->next) {
		len = strlen(ft->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(ft->name, sizeof(char), len, fp);
		if (items != len)
			return POLICYDB_ERROR;

		buf[0] = cpu_to_le32(ft->stype);
		buf[1] = cpu_to_le32(ft->ttype);
		buf[2] = cpu_to_le32(ft->tclass);
		buf[3] = cpu_to_le32(ft->otype);
		items = put_entry(buf, sizeof(uint32_t), 4, fp);
		if (items != 4)
			return POLICYDB_ERROR;
	}

	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;
	uint32_t buf[3], len;
	unsigned int items, items2;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	struct policydb *p = pd->p;

	booldatum = (cond_bool_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(booldatum->s.value);
	buf[items++] = cpu_to_le32(booldatum->state);
	buf[items++] = cpu_to_le32(len);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;
	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (p->policy_type != POLICY_KERN &&
	    p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) {
		buf[0] = cpu_to_le32(booldatum->flags);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

/*
 * cond_write_cond_av_list doesn't write out the av_list nodes.
 * Instead it writes out the key/value pairs from the avtab. This
 * is necessary because there is no way to uniquely identifying rules
 * in the avtab so it is not possible to associate individual rules
 * in the avtab with a conditional without saving them as part of
 * the conditional. This means that the avtab with the conditional
 * rules will not be saved but will be rebuilt on policy load.
 */
static int cond_write_av_list(policydb_t * p,
			      cond_av_list_t * list, struct policy_file *fp)
{
	uint32_t buf[4];
	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);
	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;
	}

	len = 0;
	for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
		if (cur_list->node->parse_context)
			len++;
	}

	buf[0] = cpu_to_le32(len);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		goto out;

	if (len == 0) {
		rc = 0;
		goto out;
	}

	for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
		if (cur_list->node->parse_context)
			if (avtab_write_item(p, cur_list->node, fp, 0, 1, NULL))
				goto out;
	}

	rc = 0;
      out:
	if (oldvers) {
		cond_av_list_destroy(new_list);
		avtab_destroy(&expa);
	}

	return rc;
}

static int cond_write_node(policydb_t * p,
			   cond_node_t * node, struct policy_file *fp)
{
	cond_expr_t *cur_expr;
	uint32_t buf[2];
	uint32_t items, items2, len;

	buf[0] = cpu_to_le32(node->cur_state);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	/* expr */
	len = 0;
	for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
		len++;

	buf[0] = cpu_to_le32(len);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
		items = 0;
		buf[items++] = cpu_to_le32(cur_expr->expr_type);
		buf[items++] = cpu_to_le32(cur_expr->bool);
		items2 = put_entry(buf, sizeof(uint32_t), items, fp);
		if (items2 != items)
			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 (p->policy_type != POLICY_KERN &&
	    p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) {
		buf[0] = cpu_to_le32(node->flags);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

static int cond_write_list(policydb_t * p, cond_list_t * list,
			   struct policy_file *fp)
{
	cond_node_t *cur;
	uint32_t len, items;
	uint32_t buf[1];

	len = 0;
	for (cur = list; cur != NULL; cur = cur->next)
		len++;
	buf[0] = cpu_to_le32(len);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	for (cur = list; cur != NULL; cur = cur->next) {
		if (cond_write_node(p, cur, fp) != 0)
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

/*
 * Write a security context structure
 * to a policydb binary representation file.
 */
static int context_write(struct policydb *p, context_struct_t * c,
			 struct policy_file *fp)
{
	uint32_t buf[32];
	size_t items, items2;

	items = 0;
	buf[items++] = cpu_to_le32(c->user);
	buf[items++] = cpu_to_le32(c->role);
	buf[items++] = cpu_to_le32(c->type);
	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 (mls_write_range_helper(&c->range, fp))
			return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

/*
 * The following *_write functions are used to
 * write the symbol data to a policy database
 * binary representation file.
 */

static int perm_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	perm_datum_t *perdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;

	perdatum = (perm_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(perdatum->s.value);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int common_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	common_datum_t *comdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;

	comdatum = (common_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(comdatum->s.value);
	buf[items++] = cpu_to_le32(comdatum->permissions.nprim);
	buf[items++] = cpu_to_le32(comdatum->permissions.table->nel);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (hashtab_map(comdatum->permissions.table, perm_write, pd))
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int write_cons_helper(policydb_t * p,
			     constraint_node_t * node, int allowxtarget,
			     struct policy_file *fp)
{
	constraint_node_t *c;
	constraint_expr_t *e;
	uint32_t buf[3], nexpr;
	int items;

	for (c = node; c; c = c->next) {
		nexpr = 0;
		for (e = c->expr; e; e = e->next) {
			nexpr++;
		}
		buf[0] = cpu_to_le32(c->permissions);
		buf[1] = cpu_to_le32(nexpr);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
		for (e = c->expr; e; e = e->next) {
			items = 0;
			buf[0] = cpu_to_le32(e->expr_type);
			buf[1] = cpu_to_le32(e->attr);
			buf[2] = cpu_to_le32(e->op);
			items = put_entry(buf, sizeof(uint32_t), 3, fp);
			if (items != 3)
				return POLICYDB_ERROR;

			switch (e->expr_type) {
			case CEXPR_NAMES:
				if (!allowxtarget && (e->attr & CEXPR_XTARGET))
					return POLICYDB_ERROR;
				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;
			}
		}
	}

	return POLICYDB_SUCCESS;
}

static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	class_datum_t *cladatum;
	constraint_node_t *c;
	uint32_t buf[32], ncons;
	size_t items, items2, len, len2;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	struct policydb *p = pd->p;

	cladatum = (class_datum_t *) datum;

	len = strlen(key);
	if (cladatum->comkey)
		len2 = strlen(cladatum->comkey);
	else
		len2 = 0;

	ncons = 0;
	for (c = cladatum->constraints; c; c = c->next) {
		ncons++;
	}

	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(len2);
	buf[items++] = cpu_to_le32(cladatum->s.value);
	buf[items++] = cpu_to_le32(cladatum->permissions.nprim);
	if (cladatum->permissions.table)
		buf[items++] = cpu_to_le32(cladatum->permissions.table->nel);
	else
		buf[items++] = 0;
	buf[items++] = cpu_to_le32(ncons);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (cladatum->comkey) {
		items = put_entry(cladatum->comkey, 1, len2, fp);
		if (items != len2)
			return POLICYDB_ERROR;
	}
	if (hashtab_map(cladatum->permissions.table, perm_write, pd))
		return POLICYDB_ERROR;

	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)) {
		/* write out the validatetrans rule */
		ncons = 0;
		for (c = cladatum->validatetrans; c; c = c->next) {
			ncons++;
		}
		buf[0] = cpu_to_le32(ncons);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		if (write_cons_helper(p, cladatum->validatetrans, 1, fp))
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	role_datum_t *role;
	uint32_t buf[32];
	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;

	/*
	 * Role attributes are redundant for policy.X, skip them
	 * when writing the roles symbol table. They are also skipped
	 * when pp is downgraded.
	 *
	 * Their numbers would be deducted in policydb_write().
	 */
	if ((role->flavor == ROLE_ATTRIB) &&
	    ((p->policy_type == POLICY_KERN) ||
	     (p->policy_type != POLICY_KERN &&
	      p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB)))
		return POLICYDB_SUCCESS;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(role->s.value);
	if (policydb_has_boundary_feature(p))
		buf[items++] = cpu_to_le32(role->bounds);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	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 (p->policy_type != POLICY_KERN &&
	    p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) {
		buf[0] = cpu_to_le32(role->flavor);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;

		if (ebitmap_write(&role->roles, fp))
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

static int type_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	type_datum_t *typdatum;
	uint32_t buf[32];
	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;

	/*
	 * The kernel policy version less than 24 (= POLICYDB_VERSION_BOUNDARY)
	 * does not support to load entries of attribute, so we skip to write it.
	 */
	if (p->policy_type == POLICY_KERN
	    && p->policyvers < POLICYDB_VERSION_BOUNDARY
	    && typdatum->flavor == TYPE_ATTRIB)
		return POLICYDB_SUCCESS;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(typdatum->s.value);
	if (policydb_has_boundary_feature(p)) {
		uint32_t properties = 0;

		if (p->policy_type != POLICY_KERN
		    && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) {
			buf[items++] = cpu_to_le32(typdatum->primary);
		}

		if (typdatum->primary)
			properties |= TYPEDATUM_PROPERTY_PRIMARY;

		if (typdatum->flavor == TYPE_ATTRIB) {
			properties |= TYPEDATUM_PROPERTY_ATTRIBUTE;
		} else if (typdatum->flavor == TYPE_ALIAS
			   && p->policy_type != POLICY_KERN)
			properties |= TYPEDATUM_PROPERTY_ALIAS;

		if (typdatum->flags & TYPE_FLAGS_PERMISSIVE
		    && p->policy_type != POLICY_KERN)
			properties |= TYPEDATUM_PROPERTY_PERMISSIVE;

		buf[items++] = cpu_to_le32(properties);
		buf[items++] = cpu_to_le32(typdatum->bounds);
	} else {
		buf[items++] = cpu_to_le32(typdatum->primary);

		if (p->policy_type != POLICY_KERN) {
			buf[items++] = cpu_to_le32(typdatum->flavor);

			if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
				buf[items++] = cpu_to_le32(typdatum->flags);
			else if (typdatum->flags & TYPE_FLAGS_PERMISSIVE)
				WARN(fp->handle, "Warning! Module policy "
				     "version %d cannot support permissive "
				     "types, but one was defined",
				     p->policyvers);
		}
	}
	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;

	return POLICYDB_SUCCESS;
}

static int user_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	user_datum_t *usrdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	struct policydb *p = pd->p;

	usrdatum = (user_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(usrdatum->s.value);
	if (policydb_has_boundary_feature(p))
		buf[items++] = cpu_to_le32(usrdatum->bounds);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	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 ((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 (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;
}

static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
				void *datap) = {
common_write, class_write, role_write, type_write, user_write,
	    cond_write_bool, sens_write, cat_write,};

static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
			  struct policy_file *fp)
{
	unsigned int i, j;
	size_t nel, items;
	uint32_t buf[32];
	ocontext_t *c;
	for (i = 0; i < info->ocon_num; i++) {
		nel = 0;
		for (c = p->ocontexts[i]; c; c = c->next)
			nel++;
		buf[0] = cpu_to_le32(nel);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		for (c = p->ocontexts[i]; c; c = c->next) {
			switch (i) {
			case OCON_XEN_ISID:
				buf[0] = cpu_to_le32(c->sid[0]);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_PIRQ:
				buf[0] = cpu_to_le32(c->u.pirq);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_IOPORT:
				buf[0] = c->u.ioport.low_ioport;
				buf[1] = c->u.ioport.high_ioport;
				for (j = 0; j < 2; j++)
					buf[j] = cpu_to_le32(buf[j]);
				items = put_entry(buf, sizeof(uint32_t), 2, fp);
				if (items != 2)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_IOMEM:
				buf[0] = c->u.iomem.low_iomem;
				buf[1] = c->u.iomem.high_iomem;
				for (j = 0; j < 2; j++)
					buf[j] = cpu_to_le32(buf[j]);
				items = put_entry(buf, sizeof(uint32_t), 2, fp);
				if (items != 2)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_PCIDEVICE:
				buf[0] = cpu_to_le32(c->u.device);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			}
		}
	}
	return POLICYDB_SUCCESS;
}

static int ocontext_write_selinux(struct policydb_compat_info *info,
	policydb_t *p, struct policy_file *fp)
{
	unsigned int i, j;
	size_t nel, items, len;
	uint32_t buf[32];
	ocontext_t *c;
	for (i = 0; i < info->ocon_num; i++) {
		nel = 0;
		for (c = p->ocontexts[i]; c; c = c->next)
			nel++;
		buf[0] = cpu_to_le32(nel);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		for (c = p->ocontexts[i]; c; c = c->next) {
			switch (i) {
			case OCON_ISID:
				buf[0] = cpu_to_le32(c->sid[0]);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_FS:
			case OCON_NETIF:
				len = strlen(c->u.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(c->u.name, 1, len, fp);
				if (items != len)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[1], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_PORT:
				buf[0] = c->u.port.protocol;
				buf[1] = c->u.port.low_port;
				buf[2] = c->u.port.high_port;
				for (j = 0; j < 3; j++) {
					buf[j] = cpu_to_le32(buf[j]);
				}
				items = put_entry(buf, sizeof(uint32_t), 3, fp);
				if (items != 3)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_NODE:
				buf[0] = c->u.node.addr; /* network order */
				buf[1] = c->u.node.mask; /* network order */
				items = put_entry(buf, sizeof(uint32_t), 2, fp);
				if (items != 2)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_FSUSE:
				buf[0] = cpu_to_le32(c->v.behavior);
				len = strlen(c->u.name);
				buf[1] = cpu_to_le32(len);
				items = put_entry(buf, sizeof(uint32_t), 2, fp);
				if (items != 2)
					return POLICYDB_ERROR;
				items = put_entry(c->u.name, 1, len, fp);
				if (items != len)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_NODE6:
				for (j = 0; j < 4; j++)
					buf[j] = c->u.node6.addr[j]; /* network order */
				for (j = 0; j < 4; j++)
					buf[j + 4] = c->u.node6.mask[j]; /* network order */
				items = put_entry(buf, sizeof(uint32_t), 8, fp);
				if (items != 8)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			}
		}
	}
	return POLICYDB_SUCCESS;
}

static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
	struct policy_file *fp)
{
	int rc = POLICYDB_ERROR;
	switch (p->target_platform) {
	case SEPOL_TARGET_SELINUX:
		rc = ocontext_write_selinux(info, p, fp);
		break;
	case SEPOL_TARGET_XEN:
		rc = ocontext_write_xen(info, p, fp);
		break;
	}
	return rc;
}

static int genfs_write(policydb_t * p, struct policy_file *fp)
{
	genfs_t *genfs;
	ocontext_t *c;
	size_t nel = 0, items, len;
	uint32_t buf[32];

	for (genfs = p->genfs; genfs; genfs = genfs->next)
		nel++;
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (genfs = p->genfs; genfs; genfs = genfs->next) {
		len = strlen(genfs->fstype);
		buf[0] = cpu_to_le32(len);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		items = put_entry(genfs->fstype, 1, len, fp);
		if (items != len)
			return POLICYDB_ERROR;
		nel = 0;
		for (c = genfs->head; c; c = c->next)
			nel++;
		buf[0] = cpu_to_le32(nel);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		for (c = genfs->head; c; c = c->next) {
			len = strlen(c->u.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(c->u.name, 1, len, fp);
			if (items != len)
				return POLICYDB_ERROR;
			buf[0] = cpu_to_le32(c->v.sclass);
			items = put_entry(buf, sizeof(uint32_t), 1, fp);
			if (items != 1)
				return POLICYDB_ERROR;
			if (context_write(p, &c->context[0], fp))
				return POLICYDB_ERROR;
		}
	}
	return POLICYDB_SUCCESS;
}

static int range_write(policydb_t * p, struct policy_file *fp)
{
	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 warning_issued = 0;

	nel = 0;
	for (rt = p->range_tr; rt; rt = rt->next) {
		/* all range_transitions are written for the new format, only
		   process related range_transitions are written for the old
		   format, so count accordingly */
		if (new_rangetr || rt->target_class == SECCLASS_PROCESS)
			nel++;
	}
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (rt = p->range_tr; rt; rt = rt->next) {
		if (!new_rangetr && rt->target_class != SECCLASS_PROCESS) {
			if (!warning_issued)
				WARN(fp->handle, "Discarding range_transition "
				     "rules for security classes other than "
				     "\"process\"");
			warning_issued = 1;
			continue;
		}
		buf[0] = cpu_to_le32(rt->source_type);
		buf[1] = cpu_to_le32(rt->target_type);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
		if (new_rangetr) {
			buf[0] = cpu_to_le32(rt->target_class);
			items = put_entry(buf, sizeof(uint32_t), 1, fp);
			if (items != 1)
				return POLICYDB_ERROR;
		}
		if (mls_write_range_helper(&rt->target_range, fp))
			return POLICYDB_ERROR;
	}
	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 only_process(ebitmap_t *in)
{
	unsigned int i;
	ebitmap_node_t *node;

	ebitmap_for_each_bit(in, node, i) {
		if (ebitmap_node_get_bit(node, i) &&
		    i != SECCLASS_PROCESS - 1)
			return 0;
	}
	return 1;
}

static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t,
				 struct policy_file *fp)
{
	int nel = 0;
	size_t items;
	uint32_t buf[1];
	role_trans_rule_t *tr;
	int warned = 0;
	int new_role = p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS;

	for (tr = t; tr; tr = tr->next)
		if (new_role || only_process(&tr->classes))
			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 (!new_role && !only_process(&tr->classes)) {
			if (!warned)
				WARN(fp->handle, "Discarding role_transition "
					"rules for security classes other than "
					"\"process\"");
			warned = 1;
			continue;
		}
		if (role_set_write(&tr->roles, fp))
			return POLICYDB_ERROR;
		if (type_set_write(&tr->types, fp))
			return POLICYDB_ERROR;
		if (new_role)
			if (ebitmap_write(&tr->classes, 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 filename_trans_rule_write(filename_trans_rule_t * t, struct policy_file *fp)
{
	int nel = 0;
	size_t items;
	uint32_t buf[2], len;
	filename_trans_rule_t *ftr;

	for (ftr = t; ftr; ftr = ftr->next)
		nel++;

	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	for (ftr = t; ftr; ftr = ftr->next) {
		len = strlen(ftr->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(ftr->name, sizeof(char), len, fp);
		if (items != len)
			return POLICYDB_ERROR;

		if (type_set_write(&ftr->stypes, fp))
			return POLICYDB_ERROR;
		if (type_set_write(&ftr->ttypes, fp))
			return POLICYDB_ERROR;

		buf[0] = cpu_to_le32(ftr->tclass);
		buf[1] = cpu_to_le32(ftr->otype);

		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			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(p, 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_FILENAME_TRANS &&
	    filename_trans_rule_write(decl->filename_trans_rules, fp))
		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;
}

static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)),
			     hashtab_datum_t datum, void *args)
{
	type_datum_t *typdatum = datum;
	uint32_t *p_nel = args;

	if (typdatum->flavor == TYPE_ATTRIB) {
		/* uncount attribute from total number of types */
		(*p_nel)--;
	}
	return 0;
}

static int role_attr_uncount(hashtab_key_t key __attribute__ ((unused)),
			     hashtab_datum_t datum, void *args)
{
	role_datum_t *role = datum;
	uint32_t *p_nel = args;

	if (role->flavor == ROLE_ATTRIB) {
		/* uncount attribute from total number of roles */
		(*p_nel)--;
	}
	return 0;
}

/*
 * Write the configuration data in a policy database
 * structure to a policy database binary representation
 * file.
 */
int policydb_write(policydb_t * p, struct policy_file *fp)
{
	unsigned int i, num_syms;
	uint32_t buf[32], config;
	size_t items, items2, len;
	struct policydb_compat_info *info;
	struct policy_data pd;
	char *policydb_str;

	if (p->unsupported_format)
		return POLICYDB_UNSUPPORTED;

	pd.fp = fp;
	pd.p = p;

	config = 0;
	if (p->mls) {
		if ((p->policyvers < POLICYDB_VERSION_MLS &&
		    p->policy_type == POLICY_KERN) ||
		    (p->policyvers < MOD_POLICYDB_VERSION_MLS &&
		    p->policy_type == POLICY_BASE) ||
		    (p->policyvers < MOD_POLICYDB_VERSION_MLS &&
		    p->policy_type == POLICY_MOD)) {
			ERR(fp->handle, "policy version %d cannot support MLS",
			    p->policyvers);
			return POLICYDB_ERROR;
		}
		config |= POLICYDB_CONFIG_MLS;
	}

	config |= (POLICYDB_CONFIG_UNKNOWN_MASK & p->handle_unknown);

	/* 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_target_strings[p->target_platform]);
		policydb_str = policydb_target_strings[p->target_platform];
	} else {
		buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC);
		len = strlen(POLICYDB_MOD_STRING);
		policydb_str = POLICYDB_MOD_STRING;
	}
	buf[items++] = cpu_to_le32(len);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;
	items = put_entry(policydb_str, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	/* Write the version, config, and table sizes. */
	items = 0;
	info = policydb_lookup_compat(p->policyvers, p->policy_type,
					p->target_platform);
	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);
	buf[items++] = cpu_to_le32(info->ocon_num);

	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	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;
	}

	if ((p->policyvers >= POLICYDB_VERSION_POLCAP &&
	     p->policy_type == POLICY_KERN) ||
	    (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
	     p->policy_type == POLICY_BASE) ||
	    (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
	     p->policy_type == POLICY_MOD)) {
		if (ebitmap_write(&p->policycaps, fp) == -1)
			return POLICYDB_ERROR;
	}

	if (p->policyvers < POLICYDB_VERSION_PERMISSIVE &&
	    p->policy_type == POLICY_KERN) {
		ebitmap_node_t *tnode;

		ebitmap_for_each_bit(&p->permissive_map, tnode, i) {
			if (ebitmap_node_get_bit(tnode, i)) {
				WARN(fp->handle, "Warning! Policy version %d cannot "
				     "support permissive types, but some were defined",
				     p->policyvers);
				break;
			}
		}
	}

	if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
	    p->policy_type == POLICY_KERN) {
		if (ebitmap_write(&p->permissive_map, fp) == -1)
			return POLICYDB_ERROR;
	}

	num_syms = info->sym_num;
	for (i = 0; i < num_syms; i++) {
		buf[0] = cpu_to_le32(p->symtab[i].nprim);
		buf[1] = p->symtab[i].table->nel;

		/*
		 * A special case when writing type/attribute symbol table.
		 * The kernel policy version less than 24 does not support
		 * to load entries of attribute, so we have to re-calculate
		 * the actual number of types except for attributes.
		 */
		if (i == SYM_TYPES &&
		    p->policyvers < POLICYDB_VERSION_BOUNDARY &&
		    p->policy_type == POLICY_KERN) {
			hashtab_map(p->symtab[i].table, type_attr_uncount, &buf[1]);
		}

		/*
		 * Another special case when writing role/attribute symbol
		 * table, role attributes are redundant for policy.X, or
		 * when the pp's version is not big enough. So deduct
		 * their numbers from p_roles.table->nel.
		 */
		if ((i == SYM_ROLES) &&
		    ((p->policy_type == POLICY_KERN) ||
		     (p->policy_type != POLICY_KERN &&
		      p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB)))
			hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]);

		buf[1] = cpu_to_le32(buf[1]);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
		if (hashtab_map(p->symtab[i].table, write_f[i], &pd))
			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, fp))
			return POLICYDB_ERROR;
		if (role_allow_write(p->role_allow, fp))
			return POLICYDB_ERROR;
		if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS) {
			if (filename_trans_write(p->filename_trans, fp))
				return POLICYDB_ERROR;
		} else {
			if (p->filename_trans)
				WARN(fp->handle, "Discarding filename type transition rules");
		}
	} else {
		if (avrule_block_write(p->global, num_syms, p, fp) == -1) {
			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 (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 (range_write(p, fp)) {
			return POLICYDB_ERROR;
		}
	}

	if (p->policy_type == POLICY_KERN
	    && 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;
		}
	}

	return POLICYDB_SUCCESS;
}
