/* 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>
#include <inttypes.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 int policy_file_length(struct policy_file *fp, size_t *out)
{
	long prev_offset, end_offset;
	int rc;
	switch (fp->type) {
	case PF_USE_STDIO:
		prev_offset = ftell(fp->fp);
		if (prev_offset < 0)
			return prev_offset;
		rc = fseek(fp->fp, 0L, SEEK_END);
		if (rc < 0)
			return rc;
		end_offset = ftell(fp->fp);
		if (end_offset < 0)
			return end_offset;
		rc = fseek(fp->fp, prev_offset, SEEK_SET);
		if (rc < 0)
			return rc;
		*out = end_offset;
		break;
	case PF_USE_MEMORY:
		*out = fp->size;
		break;
	default:
		*out = 0;
		break;
	}
	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)
{
	int rc;

	*p = calloc(1, sizeof(sepol_module_package_t));
	if (!(*p))
		return -1;

	rc = module_package_init(*p);
	if (rc < 0) {
		free(*p);
		*p = NULL;
	}

	return rc;
}


/* 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);
}


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++) {
		if (modules[i]->netfilter_contexts_len > 0) {
			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;
	int rc;

	offset = 0;
	nel = bytes;

	while (nel) {
		if (nel < _read_helper_bufsize)
			read_len = nel;
		else
			read_len = _read_helper_bufsize;
		rc = next_entry(&buf[offset], file, read_len);
		if (rc < 0)
			return -1;
		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 = NULL, nsec;
	unsigned i;
	size_t *off = NULL;
	int rc;

	buf = malloc(sizeof(uint32_t)*3);
	if (!buf) {
		ERR(file->handle, "out of memory");
		goto err;
	}
	  
	rc = next_entry(buf, file, sizeof(uint32_t) * 3);
	if (rc < 0) {
		ERR(file->handle, "module package header truncated");
		goto err;
	}
	if (le32_to_cpu(buf[0]) != SEPOL_MODULE_PACKAGE_MAGIC) {
		ERR(file->handle,
		    "wrong magic number for module package:  expected %#08x, got %#08x",
		    SEPOL_MODULE_PACKAGE_MAGIC, le32_to_cpu(buf[0]));
		goto err;
	}

	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);
		goto err;
	}

	off = (size_t *) calloc(nsec + 1, sizeof(size_t));
	if (!off) {
		ERR(file->handle, "out of memory");
		goto err;
	}

	free(buf);
	buf = calloc(nsec, sizeof(uint32_t));
	if (!buf) {
		ERR(file->handle, "out of memory");
		goto err;
	}
	rc = next_entry(buf, file, sizeof(uint32_t) * nsec);
	if (rc < 0) {
		ERR(file->handle, "module package offset array truncated");
		goto err;
	}

	for (i = 0; i < nsec; i++) {
		off[i] = le32_to_cpu(buf[i]);
		if (i && off[i] < off[i - 1]) {
			ERR(file->handle, "offsets are not increasing (at %u, "
			    "offset %zu -> %zu", i, off[i - 1],
			    off[i]);
			goto err;
		}
	}

	rc = policy_file_length(file, &off[nsec]);
	if (rc < 0)
		goto err;

	if (nsec && off[nsec] < off[nsec-1]) {
		ERR(file->handle, "offset greater than file size (at %u, "
		    "offset %zu -> %zu", nsec, off[nsec - 1],
		    off[nsec]);
		goto err;
	}
	*offsets = off;
	free(buf);
	return 0;

err:
	free(buf);
	free(off);
	return -1;
}

/* 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[1], nsec;
	size_t *offsets, len;
	int rc;
	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 */
		rc = next_entry(buf, file, sizeof(uint32_t));
		if (rc < 0) {
			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;

			rc = policydb_read(&mod->policy->p, file, verbose);
			if (rc < 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: %x ",
			    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 -1;
}

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[5], len, nsec;
	size_t *offsets = NULL;
	unsigned i, seen = 0;
	char *id;
	int rc;

	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 */
		rc = next_entry(buf, file, sizeof(uint32_t) * 2);
		if (rc < 0) {
			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 */
			id = malloc(len + 1);
			if (!id) {
				ERR(file->handle,
				    "out of memory (at section %u)",
				    i);
				goto cleanup;				
			}
			rc = next_entry(id, file, len);
			free(id);
			if (rc < 0) {
				ERR(file->handle,
				    "cannot get module string (at section %u)",
				    i);
				goto cleanup;
			}
			
			rc = next_entry(buf, file, sizeof(uint32_t) * 5);
			if (rc < 0) {
				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 */
			rc = next_entry(buf, file, sizeof(uint32_t));
			if (rc < 0) {
				ERR(file->handle,
				    "cannot get module name len (at section %u)",
				    i);
				goto cleanup;
			}

			len = le32_to_cpu(buf[0]);
			if (str_read(name, file, len)) {
				ERR(file->handle,
				    "cannot read module name (at section %u): %m",
				    i);
				goto cleanup;
			}

			rc = next_entry(buf, file, sizeof(uint32_t));
			if (rc < 0) {
				ERR(file->handle,
				    "cannot get module version len (at section %u)",
				    i);
				goto cleanup;
			}
			len = le32_to_cpu(buf[0]);
			if (str_read(version, file, len)) {
				ERR(file->handle,
				    "cannot read module version (at section %u): %m",
				i);
				goto cleanup;
			}
			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 */
		policy_file_init(&polfile);
		polfile.type = PF_LEN;
		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);
}
