/* Authors: Karl MacMillan <kmacmillan@tresys.com>
 *	    Joshua Brindle <jbrindle@tresys.com>
 *	    Jason Tang <jtang@tresys.com>
 *          Christopher Ashworth <cashworth@tresys.com>
 *          Chris PeBenito <cpebenito@tresys.com>
 *	    Caleb Case <ccase@tresys.com>
 *
 * Copyright (C) 2004-2006,2009 Tresys Technology, LLC
 * Copyright (C) 2005 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
 */

/* This file contains semanage routines that manipulate the files on a
 * local module store.	Sandbox routines, used by both source and
 * direct connections, are here as well.
 */

struct dbase_policydb;
typedef struct dbase_policydb dbase_t;
#define DBASE_DEFINED

#include "semanage_store.h"
#include "database_policydb.h"
#include "handle.h"

#include <selinux/selinux.h>
#include <sepol/policydb.h>
#include <sepol/module.h>

#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <limits.h>
#include <libgen.h>

#include "debug.h"
#include "utilities.h"

#define SEMANAGE_CONF_FILE "semanage.conf"
/* relative path names to enum semanage_paths to special files and
 * directories for the module store */

#define TRUE 1

enum semanage_file_defs {
	SEMANAGE_ROOT,
	SEMANAGE_TRANS_LOCK,
	SEMANAGE_READ_LOCK,
	SEMANAGE_NUM_FILES
};

static char *semanage_paths[SEMANAGE_NUM_STORES][SEMANAGE_STORE_NUM_PATHS];
static char *semanage_files[SEMANAGE_NUM_FILES] = { NULL };
static int semanage_paths_initialized = 0;

/* These are paths relative to the bottom of the module store */
static const char *semanage_relative_files[SEMANAGE_NUM_FILES] = {
	"",
	"/semanage.trans.LOCK",
	"/semanage.read.LOCK"
};

static const char *semanage_store_paths[SEMANAGE_NUM_STORES] = {
	"/active",
	"/previous",
	"/tmp"
};

/* relative path names to enum sandbox_paths for special files within
 * a sandbox */
static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = {
	"",
	"/modules",
	"/base.linked",
	"/homedir_template",
	"/file_contexts.template",
	"/commit_num",
	"/ports.local",
	"/interfaces.local",
	"/nodes.local",
	"/booleans.local",
	"/seusers.local",
	"/users.local",
	"/users_extra.local",
	"/users_extra",
	"/disable_dontaudit",
	"/preserve_tunables",
	"/modules/disabled",
	"/policy.kern",
	"/file_contexts.local",
	"/file_contexts",
	"/seusers"
};

static char const * const semanage_final_prefix[SEMANAGE_FINAL_NUM] = {
	"/final",
	"",
};

static char *semanage_final[SEMANAGE_FINAL_NUM] = { NULL };
static char *semanage_final_suffix[SEMANAGE_FINAL_PATH_NUM] = { NULL };
static char *semanage_final_paths[SEMANAGE_FINAL_NUM][SEMANAGE_FINAL_PATH_NUM] = {{ NULL }};

/* A node used in a linked list of file contexts; used for sorting.
 */
typedef struct semanage_file_context_node {
	char *path;
	char *file_type;
	char *context;
	int path_len;
	int effective_len;
	int type_len;
	int context_len;
	int meta;		/* position of first meta char in path, -1 if none */
	struct semanage_file_context_node *next;
} semanage_file_context_node_t;

/* A node used in a linked list of buckets that contain
 *  semanage_file_context_node lists.  Used for sorting.
 */
typedef struct semanage_file_context_bucket {
	semanage_file_context_node_t *data;
	struct semanage_file_context_bucket *next;
} semanage_file_context_bucket_t;

/* A node used in a linked list of netfilter rules.
 */
typedef struct semanage_netfilter_context_node {
	char *rule;
	size_t rule_len;
	struct semanage_netfilter_context_node *next;
} semanage_netfilter_context_node_t;

/* Initialize the paths to config file, lock files and store root.
 */
static int semanage_init_paths(const char *root)
{
	size_t len, prefix_len;
	int i;

	if (!root)
		return -1;

	prefix_len = strlen(root);

	for (i = 0; i < SEMANAGE_NUM_FILES; i++) {
		len = (strlen(semanage_relative_files[i]) + prefix_len);
		semanage_files[i] = calloc(len + 1, sizeof(char));
		if (!semanage_files[i])
			return -1;
		sprintf(semanage_files[i], "%s%s", root,
			semanage_relative_files[i]);
	}

	return 0;
}

/* This initializes the paths inside the stores, this is only necessary 
 * when directly accessing the store
 */
static int semanage_init_store_paths(const char *root)
{
	int i, j;
	size_t len;
	size_t prefix_len;

	if (!root)
		return -1;

	prefix_len = strlen(root);

	for (i = 0; i < SEMANAGE_NUM_STORES; i++) {
		for (j = 0; j < SEMANAGE_STORE_NUM_PATHS; j++) {
			len = prefix_len + strlen(semanage_store_paths[i])
			    + strlen(semanage_sandbox_paths[j]);
			semanage_paths[i][j] = calloc(len + 1, sizeof(char));
			if (!semanage_paths[i][j])
				goto cleanup;
			sprintf(semanage_paths[i][j], "%s%s%s", root,
				semanage_store_paths[i],
				semanage_sandbox_paths[j]);
		}
	}

      cleanup:
	return 0;
}

static int semanage_init_final(semanage_handle_t *sh, const char *prefix)
{
	assert(sh);
	assert(prefix);

	int status = 0;
	size_t len;
	const char *store_path = sh->conf->store_path;
	size_t store_len = strlen(store_path);

	/* SEMANAGE_FINAL_TMP */
	len = strlen(semanage_root()) +
	      strlen(prefix) +
	      strlen("/") +
	      strlen(semanage_final_prefix[SEMANAGE_FINAL_TMP]) +
	      store_len;
	semanage_final[SEMANAGE_FINAL_TMP] = malloc(len + 1);
	if (semanage_final[SEMANAGE_FINAL_TMP] == NULL) {
		status = -1;
		goto cleanup;
	}

	sprintf(semanage_final[SEMANAGE_FINAL_TMP],
		"%s%s%s/%s",
		semanage_root(),
		prefix,
		semanage_final_prefix[SEMANAGE_FINAL_TMP],
		store_path);

	/* SEMANAGE_FINAL_SELINUX */
	const char *selinux_root = selinux_path();
	len = strlen(semanage_root()) +
	      strlen(selinux_root) +
	      strlen(semanage_final_prefix[SEMANAGE_FINAL_SELINUX]) +
	      store_len;
	semanage_final[SEMANAGE_FINAL_SELINUX] = malloc(len + 1);
	if (semanage_final[SEMANAGE_FINAL_SELINUX] == NULL) {
		status = -1;
		goto cleanup;
	}

	sprintf(semanage_final[SEMANAGE_FINAL_SELINUX],
		"%s%s%s%s",
		semanage_root(),
		selinux_root,
		semanage_final_prefix[SEMANAGE_FINAL_SELINUX],
		store_path);

cleanup:
	if (status != 0) {
		int i;
		for (i = 0; i < SEMANAGE_FINAL_NUM; i++) {
			free(semanage_final[i]);
			semanage_final[i] = NULL;
		}
	}

	return status;
}

static int semanage_init_final_suffix(semanage_handle_t *sh)
{
	int ret = 0;
	int status = 0;
	char path[PATH_MAX];
	size_t offset = strlen(selinux_policy_root());

	semanage_final_suffix[SEMANAGE_FINAL_TOPLEVEL] = strdup("");
	if (semanage_final_suffix[SEMANAGE_FINAL_TOPLEVEL] == NULL) {
		ERR(sh, "Unable to allocate space for policy top level path.");
		status = -1;
		goto cleanup;
	}

	semanage_final_suffix[SEMANAGE_FC] =
		strdup(selinux_file_context_path() + offset);
	if (semanage_final_suffix[SEMANAGE_FC] == NULL) {
		ERR(sh, "Unable to allocate space for file context path.");
		status = -1;
		goto cleanup;
	}

	semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] =
		strdup(selinux_file_context_homedir_path() + offset);
	if (semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] == NULL) {
		ERR(sh, "Unable to allocate space for file context home directory path.");
		status = -1;
		goto cleanup;
	}

	semanage_final_suffix[SEMANAGE_FC_LOCAL] =
		strdup(selinux_file_context_local_path() + offset);
	if (semanage_final_suffix[SEMANAGE_FC_LOCAL] == NULL) {
		ERR(sh, "Unable to allocate space for local file context path.");
		status = -1;
		goto cleanup;
	}

	semanage_final_suffix[SEMANAGE_NC] =
		strdup(selinux_netfilter_context_path() + offset);
	if (semanage_final_suffix[SEMANAGE_NC] == NULL) {
		ERR(sh, "Unable to allocate space for netfilter context path.");
		status = -1;
		goto cleanup;
	}

	semanage_final_suffix[SEMANAGE_SEUSERS] =
		strdup(selinux_usersconf_path() + offset);
	if (semanage_final_suffix[SEMANAGE_SEUSERS] == NULL) {
		ERR(sh, "Unable to allocate space for userconf path.");
		status = -1;
		goto cleanup;
	}

	ret = snprintf(path,
		       sizeof(path),
		       "%s.%d",
		       selinux_binary_policy_path() + offset,
		       sh->conf->policyvers);
	if (ret < 0 || ret >= (int)sizeof(path)) {
		ERR(sh, "Unable to compose policy binary path.");
		status = -1;
		goto cleanup;
	}

	semanage_final_suffix[SEMANAGE_KERNEL] = strdup(path);
	if (semanage_final_suffix[SEMANAGE_KERNEL] == NULL) {
		ERR(sh, "Unable to allocate space for policy binary path.");
		status = -1;
		goto cleanup;
	}

cleanup:
	if (status != 0) {
		int i;
		for (i = 0; i < SEMANAGE_FINAL_PATH_NUM; i++) {
			free(semanage_final_suffix[i]);
			semanage_final_suffix[i] = NULL;
		}
	}

	return status;
}

/* Initialize final paths. */
static int semanage_init_final_paths(semanage_handle_t *sh)
{
	int status = 0;
	int i, j;
	size_t len;

	for (i = 0; i < SEMANAGE_FINAL_NUM; i++) {
		for (j = 0; j < SEMANAGE_FINAL_PATH_NUM; j++) {
			len = 	  strlen(semanage_final[i])
				+ strlen(semanage_final_suffix[j]);

			semanage_final_paths[i][j] = malloc(len + 1);
			if (semanage_final_paths[i][j] == NULL) {
				ERR(sh, "Unable to allocate space for policy final path.");
				status = -1;
				goto cleanup;
			}

			sprintf(semanage_final_paths[i][j],
				"%s%s",
				semanage_final[i],
				semanage_final_suffix[j]);
		}
	}

cleanup:
	if (status != 0) {
		for (i = 0; i < SEMANAGE_FINAL_NUM; i++) {
			for (j = 0; j < SEMANAGE_FINAL_PATH_NUM; j++) {
				free(semanage_final_paths[i][j]);
				semanage_final_paths[i][j] = NULL;
			}
		}
	}

	return status;
}

/* THIS MUST BE THE FIRST FUNCTION CALLED IN THIS LIBRARY.  If the
 * library has nnot been initialized yet then call the functions that
 * initialize the path variables.  This function does nothing if it
 * was previously called and that call was successful.  Return 0 on
 * success, -1 on error.
 *
 * Note that this function is NOT thread-safe.
 */
int semanage_check_init(semanage_handle_t *sh, const char *prefix)
{
	int rc;
	if (semanage_paths_initialized == 0) {
		char root[PATH_MAX];

		rc = snprintf(root,
			      sizeof(root),
			      "%s%s/%s",
			      semanage_root(),
			      prefix,
			      sh->conf->store_path);
		if (rc < 0 || rc >= (int)sizeof(root))
			return -1;

		rc = semanage_init_paths(root);
		if (rc)
			return rc;

		rc = semanage_init_store_paths(root);
		if (rc)
			return rc;

		rc = semanage_init_final(sh, prefix);
		if (rc)
			return rc;

		rc = semanage_init_final_suffix(sh);
		if (rc)
			return rc;

		rc = semanage_init_final_paths(sh);
		if (rc)
			return rc;

		semanage_paths_initialized = 1;
	}
	return 0;
}

/* Given a definition number, return a file name from the paths array */
const char *semanage_fname(enum semanage_sandbox_defs file_enum)
{
	return semanage_sandbox_paths[file_enum];
}

/* Given a store location (active/previous/tmp) and a definition
 * number, return a fully-qualified path to that file or directory.
 * The caller must not alter the string returned (and hence why this
 * function return type is const).
 *
 * This function shall never return a NULL, assuming that
 * semanage_check_init() was previously called.
 */
const char *semanage_path(enum semanage_store_defs store,
			  enum semanage_sandbox_defs path_name)
{
	assert(semanage_paths[store][path_name]);
	return semanage_paths[store][path_name];
}

/* Given a store location (tmp or selinux) and a definition
 * number, return a fully-qualified path to that file or directory.
 * The caller must not alter the string returned (and hence why this
 * function return type is const).
 *
 * This function shall never return a NULL, assuming that
 * semanage_check_init() was previously called.
 */
const char *semanage_final_path(enum semanage_final_defs store,
				enum semanage_final_path_defs path_name)
{
	assert(semanage_final_paths[store][path_name]);
	return semanage_final_paths[store][path_name];
}

/* Return a fully-qualified path + filename to the semanage
 * configuration file. If semanage.conf file in the semanage
 * root is cannot be read, use the default semanage.conf as a
 * fallback.
 *
 * The caller is responsible for freeing the returned string.
 */
char *semanage_conf_path(void)
{
	char *semanage_conf = NULL;
	int len;

	len = strlen(semanage_root()) + strlen(selinux_path()) + strlen(SEMANAGE_CONF_FILE);
	semanage_conf = calloc(len + 1, sizeof(char));
	if (!semanage_conf)
		return NULL;
	snprintf(semanage_conf, len + 1, "%s%s%s", semanage_root(), selinux_path(),
		 SEMANAGE_CONF_FILE);

	if (access(semanage_conf, R_OK) != 0) {
		snprintf(semanage_conf, len + 1, "%s%s", selinux_path(), SEMANAGE_CONF_FILE);
	}

	return semanage_conf;
}

/**************** functions that create module store ***************/

/* Check that the semanage store exists.  If 'create' is non-zero then
 * create the directories.  Returns 0 if module store exists (either
 * already or just created), -1 if does not exist or could not be
 * read, or -2 if it could not create the store. */
int semanage_create_store(semanage_handle_t * sh, int create)
{
	struct stat sb;
	int mode_mask = R_OK | W_OK | X_OK;
	const char *path = semanage_files[SEMANAGE_ROOT];
	int fd;

	if (stat(path, &sb) == -1) {
		if (errno == ENOENT && create) {
			if (mkdir(path, S_IRWXU) == -1) {
				ERR(sh, "Could not create module store at %s.",
				    path);
				return -2;
			}
		} else {
			if (create)
				ERR(sh,
				    "Could not read from module store at %s.",
				    path);
			return -1;
		}
	} else {
		if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) {
			ERR(sh,
			    "Could not access module store at %s, or it is not a directory.",
			    path);
			return -1;
		}
	}
	path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL);
	if (stat(path, &sb) == -1) {
		if (errno == ENOENT && create) {
			if (mkdir(path, S_IRWXU) == -1) {
				ERR(sh,
				    "Could not create module store, active subdirectory at %s.",
				    path);
				return -2;
			}
		} else {
			ERR(sh,
			    "Could not read from module store, active subdirectory at %s.",
			    path);
			return -1;
		}
	} else {
		if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) {
			ERR(sh,
			    "Could not access module store active subdirectory at %s, or it is not a directory.",
			    path);
			return -1;
		}
	}
	path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES);
	if (stat(path, &sb) == -1) {
		if (errno == ENOENT && create) {
			if (mkdir(path, S_IRWXU) == -1) {
				ERR(sh,
				    "Could not create module store, active modules subdirectory at %s.",
				    path);
				return -2;
			}
		} else {
			ERR(sh,
			    "Could not read from module store, active modules subdirectory at %s.",
			    path);
			return -1;
		}
	} else {
		if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) {
			ERR(sh,
			    "Could not access module store active modules subdirectory at %s, or it is not a directory.",
			    path);
			return -1;
		}
	}
	path = semanage_files[SEMANAGE_READ_LOCK];
	if (stat(path, &sb) == -1) {
		if (errno == ENOENT && create) {
			if ((fd = creat(path, S_IRUSR | S_IWUSR)) == -1) {
				ERR(sh, "Could not create lock file at %s.",
				    path);
				return -2;
			}
			close(fd);
		} else {
			ERR(sh, "Could not read lock file at %s.", path);
			return -1;
		}
	} else {
		if (!S_ISREG(sb.st_mode) || access(path, R_OK | W_OK) == -1) {
			ERR(sh, "Could not access lock file at %s.", path);
			return -1;
		}
	}
	return 0;
}

/* returns <0 if the active store cannot be read or doesn't exist
 * 0 if the store exists but the lock file cannot be accessed 
 * SEMANAGE_CAN_READ if the store can be read and the lock file used
 * SEMANAGE_CAN_WRITE if the modules directory and binary policy dir can be written to
 */
int semanage_store_access_check(void)
{
	const char *path;
	int rc = -1;

	/* read access on active store */
	path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL);
	if (access(path, R_OK | X_OK) != 0)
		goto out;

	/* we can read the active store meaning it is managed
	 * so now we return 0 to indicate no error */
	rc = 0;

	/* read access on lock file required for locking
	 * write access necessary if the lock file does not exist
	 */
	path = semanage_files[SEMANAGE_READ_LOCK];
	if (access(path, R_OK) != 0) {
		if (access(path, F_OK) == 0) {
			goto out;
		}

		path = semanage_files[SEMANAGE_ROOT];
		if (access(path, R_OK | W_OK | X_OK) != 0) {
			goto out;
		}
	}

	/* everything needed for reading has been checked */
	rc = SEMANAGE_CAN_READ;

	/* check the modules directory */
	path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_MODULES);
	if (access(path, R_OK | W_OK | X_OK) != 0)
		goto out;

	rc = SEMANAGE_CAN_WRITE;

      out:
	return rc;
}

/********************* other I/O functions *********************/

/* Callback used by scandir() to select files. */
static int semanage_filename_select(const struct dirent *d)
{
	if (d->d_name[0] == '.'
	    && (d->d_name[1] == '\0'
		|| (d->d_name[1] == '.' && d->d_name[2] == '\0')))
		return 0;
	return 1;
}

/* Copies a file from src to dst.  If dst already exists then
 * overwrite it.  Returns 0 on success, -1 on error. */
int semanage_copy_file(const char *src, const char *dst, mode_t mode)
{
	int in, out, retval = 0, amount_read, n, errsv = errno;
	char tmp[PATH_MAX];
	char buf[4192];
	mode_t mask;

	n = snprintf(tmp, PATH_MAX, "%s.tmp", dst);
	if (n < 0 || n >= PATH_MAX)
		return -1;

	if ((in = open(src, O_RDONLY)) == -1) {
		return -1;
	}

	if (!mode)
		mode = S_IRUSR | S_IWUSR;
	
	mask = umask(0);
	if ((out = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, mode)) == -1) {
		umask(mask);
		errsv = errno;
		close(in);
		retval = -1;
		goto out;
	}
	umask(mask);
	while (retval == 0 && (amount_read = read(in, buf, sizeof(buf))) > 0) {
		if (write(out, buf, amount_read) < 0) {
			errsv = errno;
			retval = -1;
		}
	}
	if (amount_read < 0) {
		errsv = errno;
		retval = -1;
	}
	close(in);
	if (close(out) < 0) {
		errsv = errno;
		retval = -1;
	}

	if (!retval && rename(tmp, dst) == -1)
		return -1;

out:
	errno = errsv;
	return retval;
}

static int semanage_copy_dir_flags(const char *src, const char *dst, int flag);

/* Copies all of the files from src to dst, recursing into
 * subdirectories.  Returns 0 on success, -1 on error. */
static int semanage_copy_dir(const char *src, const char *dst)
{
	return semanage_copy_dir_flags(src, dst, 1);
}

/* Copies all of the dirs from src to dst, recursing into
 * subdirectories. If flag == 1, then copy regular files as
 * well. Returns 0 on success, -1 on error. */
static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
{
	int i, len = 0, retval = -1;
	struct stat sb;
	struct dirent **names = NULL;
	char path[PATH_MAX], path2[PATH_MAX];

	if ((len = scandir(src, &names, semanage_filename_select, NULL)) == -1) {
		fprintf(stderr, "Could not read the contents of %s: %s\n", src, strerror(errno));
		return -1;
	}

	if (stat(dst, &sb) != 0) {
		if (mkdir(dst, S_IRWXU) != 0) {
			fprintf(stderr, "Could not create %s: %s\n", dst, strerror(errno));
			goto cleanup;
		}
	}

	for (i = 0; i < len; i++) {
		snprintf(path, sizeof(path), "%s/%s", src, names[i]->d_name);
		/* stat() to see if this entry is a file or not since
		 * d_type isn't set properly on XFS */
		if (stat(path, &sb)) {
			goto cleanup;
		}
		snprintf(path2, sizeof(path2), "%s/%s", dst, names[i]->d_name);
		if (S_ISDIR(sb.st_mode)) {
			if (mkdir(path2, 0700) == -1 ||
			    semanage_copy_dir_flags(path, path2, flag) == -1) {
				goto cleanup;
			}
		} else if (S_ISREG(sb.st_mode) && flag == 1) {
			if (semanage_copy_file(path, path2, sb.st_mode) < 0) {
				goto cleanup;
			}
		}
	}
	retval = 0;
      cleanup:
	for (i = 0; names != NULL && i < len; i++) {
		free(names[i]);
	}
	free(names);
	return retval;
}

/* Recursively removes the contents of a directory along with the
 * directory itself.  Returns 0 on success, non-zero on error. */
int semanage_remove_directory(const char *path)
{
	struct dirent **namelist = NULL;
	int num_entries, i;
	if ((num_entries = scandir(path, &namelist, semanage_filename_select,
				   NULL)) == -1) {
		return -1;
	}
	for (i = 0; i < num_entries; i++) {
		char s[NAME_MAX];
		struct stat buf;
		snprintf(s, sizeof(s), "%s/%s", path, namelist[i]->d_name);
		if (stat(s, &buf) == -1) {
			return -2;
		}
		if (S_ISDIR(buf.st_mode)) {
			int retval;
			if ((retval = semanage_remove_directory(s)) != 0) {
				return retval;
			}
		} else {
			if (remove(s) == -1) {
				return -3;
			}
		}
		free(namelist[i]);
	}
	free(namelist);
	if (rmdir(path) == -1) {
		return -4;
	}
	return 0;
}

int semanage_mkpath(semanage_handle_t *sh, const char *path)
{
	char fn[PATH_MAX];
	char *c;
	int rc = 0;

	if (strlen(path) >= PATH_MAX) {
		return -1;
	}

	for (c = strcpy(fn, path) + 1; *c != '\0'; c++) {
		if (*c != '/') {
			continue;
		}

		*c = '\0';
		rc = semanage_mkdir(sh, fn);
		if (rc < 0) {
			goto cleanup;
		}
		*c = '/';
	}
	rc = semanage_mkdir(sh, fn);

cleanup:
	return rc;
}

int semanage_mkdir(semanage_handle_t *sh, const char *path)
{
	int status = 0;
	struct stat sb;

	/* check if directory already exists */
	if (stat(path, &sb) != 0) {
		/* make the modules directory */
		if (mkdir(path, S_IRWXU) != 0) {
			ERR(sh, "Cannot make directory at %s", path);
			status = -1;
			goto cleanup;

		}
	}
	else {
		/* check that it really is a directory */
		if (!S_ISDIR(sb.st_mode)) {
			ERR(sh, "Directory path taken by non-directory file at %s.", path);
			status = -1;
			goto cleanup;
		}
	}

cleanup:
	return status;
}

/********************* sandbox management routines *********************/

/* Creates a sandbox for a single client. Returns 0 if a
 * sandbox was created, -1 on error.
 */
int semanage_make_sandbox(semanage_handle_t * sh)
{
	const char *sandbox = semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL);
	struct stat buf;
	int errsv;

	if (stat(sandbox, &buf) == -1) {
		if (errno != ENOENT) {
			ERR(sh, "Error scanning directory %s.", sandbox);
			return -1;
		}
		errno = 0;
	} else {
		/* remove the old sandbox */
		if (semanage_remove_directory(sandbox) != 0) {
			ERR(sh, "Error removing old sandbox directory %s.",
			    sandbox);
			return -1;
		}
	}

	if (mkdir(sandbox, S_IRWXU) == -1 ||
	    semanage_copy_dir(semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL),
			      sandbox) == -1) {
		ERR(sh, "Could not copy files to sandbox %s.", sandbox);
		goto cleanup;
	}
	return 0;

      cleanup:
	errsv = errno;
	semanage_remove_directory(sandbox);
	errno = errsv;
	return -1;
}

/* Create final temporary space. Returns -1 on error 0 on success. */
int semanage_make_final(semanage_handle_t *sh)
{
	int status = 0;
	int ret = 0;
	char fn[PATH_MAX];

	/* Create tmp dir if it does not exist. */
	ret = snprintf(fn,
		       sizeof(fn),
		       "%s%s%s",
		       semanage_root(),
		       sh->conf->store_root_path,
		       semanage_final_prefix[SEMANAGE_FINAL_TMP]);
	if (ret < 0 || ret >= (int)sizeof(fn)) {
		ERR(sh, "Unable to compose the final tmp path.");
		status = -1;
		goto cleanup;
	}

	ret = semanage_mkdir(sh, fn);
	if (ret != 0) {
		ERR(sh, "Unable to create temporary directory for final files at %s", fn);
		status = -1;
		goto cleanup;
	}

	/* Delete store specific dir if it exists. */
	ret = semanage_remove_directory(
		semanage_final_path(SEMANAGE_FINAL_TMP,
				    SEMANAGE_FINAL_TOPLEVEL));
	if (ret < -1) {
		status = -1;
		goto cleanup;
	}

	// Build final directory structure
	int i;
	for (i = 1; i < SEMANAGE_FINAL_PATH_NUM; i++) {
		if (strlen(semanage_final_path(SEMANAGE_FINAL_TMP, i)) >= sizeof(fn)) {
			ERR(sh, "Unable to compose the final paths.");
			status = -1;
			goto cleanup;
		}
		strcpy(fn, semanage_final_path(SEMANAGE_FINAL_TMP, i));
		ret = semanage_mkpath(sh, dirname(fn));
		if (ret < 0) {
			status = -1;
			goto cleanup;
		}
	}

cleanup:
	return status;
}

/* qsort comparison function for semanage_get_active_modules. */
static int semanage_get_active_modules_cmp(const void *a, const void *b)
{
	semanage_module_info_t *aa = (semanage_module_info_t *)a;
	semanage_module_info_t *bb = (semanage_module_info_t *)b;

	return strcmp(aa->name, bb->name);
}

int semanage_get_cil_paths(semanage_handle_t * sh,
				semanage_module_info_t *modinfos,
				int num_modinfos,
				char *** filenames)
{
	char path[PATH_MAX];
	char **names = NULL;

	int ret;
	int status = 0;
	int i = 0;

	names = calloc(num_modinfos, sizeof(*names));
	if (names == NULL) {
		ERR(sh, "Error allocating space for filenames.");
		status = -1;
		goto cleanup;
	}

	for (i = 0; i < num_modinfos; i++) {
		ret = semanage_module_get_path(
				sh,
				&modinfos[i],
				SEMANAGE_MODULE_PATH_CIL,
				path,
				sizeof(path));
		if (ret != 0) {
			status = -1;
			goto cleanup;
		}

		names[i] = strdup(path);

		if (names[i] == NULL) {
			status = -1;
			goto cleanup;
		}
	}

cleanup:
	if (status != 0) {
		for (i = 0; i < num_modinfos; i++) {
			free(names[i]);
		}
		free(names);
	} else {
		*filenames = names;
	}

	return status;
}

/* Scans the modules directory for the current semanage handler.  This
 * might be the active directory or sandbox, depending upon if the
 * handler has a transaction lock.  Allocates and fills in *modinfos
 * with an array of module infos; length of array is stored in
 * *num_modules. The caller is responsible for free()ing *modinfos and its
 * individual elements.	 Upon success returns 0, -1 on error.
 */
int semanage_get_active_modules(semanage_handle_t * sh,
				semanage_module_info_t ** modinfo,
				int *num_modules)
{
	assert(sh);
	assert(modinfo);
	assert(num_modules);
	*modinfo = NULL;
	*num_modules = 0;

	int status = 0;
	int ret = 0;

	int i = 0;
	int j = 0;

	semanage_list_t *list = NULL;
	semanage_list_t *found = NULL;

	semanage_module_info_t *all_modinfos = NULL;
	int all_modinfos_len = 0;

	void *tmp = NULL;

	/* get all modules */
	ret = semanage_module_list_all(sh, &all_modinfos, &all_modinfos_len);
	if (ret != 0) {
		status = -1;
		goto cleanup;
	}

	if (all_modinfos_len == 0) {
		goto cleanup;
	}

	/* allocate enough for worst case */
	(*modinfo) = calloc(all_modinfos_len, sizeof(**modinfo));
	if ((*modinfo) == NULL) {
		ERR(sh, "Error allocating space for module information.");
		status = -1;
		goto cleanup;
	}

	/* for each highest priority, enabled module get its path */
	semanage_list_destroy(&list);
	j = 0;
	for (i = 0; i < all_modinfos_len; i++) {
		/* check if enabled */
		if (all_modinfos[i].enabled != 1) continue;

		/* check if we've seen this before (i.e. highest priority) */
		found = semanage_list_find(list, all_modinfos[i].name);
		if (found == NULL) {
			ret = semanage_list_push(&list, all_modinfos[i].name);
			if (ret != 0) {
				ERR(sh, "Failed to add module name to list of known names.");
				status = -1;
				goto cleanup;
			}
		}
		else continue;

		if (semanage_module_info_clone(sh, &all_modinfos[i], &(*modinfo)[j]) != 0) {
			status = -1;
			goto cleanup;
		}

		j += 1;
	}

	*num_modules = j;

	if (j == 0) {
		free(*modinfo);
		*modinfo = NULL;
		goto cleanup;
	}

	/* realloc the array to its min size */
	tmp = realloc(*modinfo, j * sizeof(**modinfo));
	if (tmp == NULL) {
		ERR(sh, "Error allocating space for filenames.");
		status = -1;
		goto cleanup;
	}
	*modinfo = tmp;

	/* sort array on module name */
	qsort(*modinfo,
	      *num_modules,
	      sizeof(**modinfo),
	      semanage_get_active_modules_cmp);

cleanup:
	semanage_list_destroy(&list);

	for (i = 0; i < all_modinfos_len; i++) {
		semanage_module_info_destroy(sh, &all_modinfos[i]);
	}
	free(all_modinfos);

	if (status != 0) {
		for (i = 0; i < j; j++) {
			semanage_module_info_destroy(sh, &(*modinfo)[i]);
		}
		free(*modinfo);
	}

	return status;
}

/******************* routines that run external programs *******************/

/* Appends a single character to a string.  Returns a pointer to the
 * realloc()ated string.  If out of memory return NULL; original
 * string will remain untouched.
 */
static char *append(char *s, char c)
{
	size_t len = (s == NULL ? 0 : strlen(s));
	char *new_s = realloc(s, len + 2);
	if (new_s == NULL) {
		return NULL;
	}
	s = new_s;
	s[len] = c;
	s[len + 1] = '\0';
	return s;
}

/* Append string 't' to string 's', realloc()ating 's' as needed.  't'
 * may be safely free()d afterwards.  Returns a pointer to the
 * realloc()ated 's'.  If out of memory return NULL; original strings
 * will remain untouched.
 */
static char *append_str(char *s, const char *t)
{
	size_t s_len = (s == NULL ? 0 : strlen(s));
	size_t t_len = (t == NULL ? 0 : strlen(t));
	char *new_s = realloc(s, s_len + t_len + 1);
	if (new_s == NULL) {
		return NULL;
	}
	s = new_s;
	memcpy(s + s_len, t, t_len);
	s[s_len + t_len] = '\0';
	return s;
}

/*
 * Append an argument string to an argument vector.  Replaces the
 * argument pointer passed in.  Returns -1 on error.  Increments
 * 'num_args' on success.
 */
static int append_arg(char ***argv, int *num_args, const char *arg)
{
	char **a;

	a = realloc(*argv, sizeof(**argv) * (*num_args + 1));
	if (a == NULL)
		return -1;

	*argv = a;
	a[*num_args] = NULL;

	if (arg) {
		a[*num_args] = strdup(arg);
		if (!a[*num_args])
			return -1;
	}
	(*num_args)++;
	return 0;
}

/* free()s all strings within a null-terminated argument vector, as
 * well as the pointer itself. */
static void free_argv(char **argv)
{
	int i;
	for (i = 0; argv != NULL && argv[i] != NULL; i++) {
		free(argv[i]);
	}
	free(argv);
}

/* Take an argument string and split and place into an argument
 * vector.  Respect normal quoting, double-quoting, and backslash
 * conventions.	 Perform substitutions on $@ and $< symbols.  Returns
 * a NULL-terminated argument vector; caller is responsible for
 * free()ing the vector and its elements. */
static char **split_args(const char *arg0, char *arg_string,
			 const char *new_name, const char *old_name)
{
	char **argv = NULL, *s, *arg = NULL, *targ;
	int num_args = 0, in_quote = 0, in_dquote = 0, rc;

	rc = append_arg(&argv, &num_args, arg0);
	if (rc)
		goto cleanup;
	s = arg_string;
	/* parse the argument string one character at a time,
	 * repsecting quotes and other special characters */
	while (s != NULL && *s != '\0') {
		switch (*s) {
		case '\\':{
				if (*(s + 1) == '\0') {
					targ = append(arg, '\\');
					if (targ == NULL)
						goto cleanup;
					arg = targ;
				} else {
					targ = append(arg, *(s + 1));
					if (targ == NULL)
						goto cleanup;
					arg = targ;
					s++;
				}
				break;
			}
		case '\'':{
				if (in_dquote) {
					targ = append(arg, *s);
					if (targ == NULL)
						goto cleanup;
					arg = targ;
				} else if (in_quote) {
					in_quote = 0;
				} else {
					in_quote = 1;
					targ = append(arg, '\0');
					if (targ == NULL)
						goto cleanup;
					arg = targ;
				}
				break;
			}
		case '\"':{
				if (in_quote) {
					targ = append(arg, *s);
					if (targ == NULL)
						goto cleanup;
					arg = targ;
				} else if (in_dquote) {
					in_dquote = 0;
				} else {
					in_dquote = 1;
					targ = append(arg, '\0');
					if (targ == NULL)
						goto cleanup;
					arg = targ;
				}
				break;
			}
		case '$':{
				switch (*(s + 1)) {
				case '@':{
						targ = append_str(arg, new_name);
						if (targ == NULL)
							goto cleanup;
						arg = targ;
						s++;
						break;
					}
				case '<':{
						targ = append_str(arg, old_name);
						if (targ == NULL)
							goto cleanup;
						arg = targ;
						s++;
						break;
					}
				default:{
						targ = append(arg, *s);
						if (targ == NULL)
							goto cleanup;
						arg = targ;
					}
				}
				break;
			}
		default:{
				if (isspace(*s) && !in_quote && !in_dquote) {
					if (arg != NULL) {
						rc = append_arg(&argv, &num_args, arg);
						free(arg);
						arg = NULL;
					}
				} else {
					if ((targ = append(arg, *s)) == NULL) {
						goto cleanup;
					} else {
						arg = targ;
					}
				}
			}
		}
		s++;
	}
	if (arg != NULL) {
		rc = append_arg(&argv, &num_args, arg);
		free(arg);
		arg = NULL;
	}
	/* explicitly add a NULL at the end */
	rc = append_arg(&argv, &num_args, NULL);
	if (rc)
		goto cleanup;
	return argv;
      cleanup:
	free_argv(argv);
	free(arg);
	return NULL;
}

/* Take the arguments given in v->args and expand any $ macros within.
 * Split the arguments into different strings (argv).  Next fork and
 * execute the process.	 BE SURE THAT ALL FILE DESCRIPTORS ARE SET TO
 * CLOSE-ON-EXEC.  Take the return value of the child process and
 * return it, -1 on error.
 */
static int semanage_exec_prog(semanage_handle_t * sh,
			      external_prog_t * e, const char *new_name,
			      const char *old_name)
{
	char **argv;
	pid_t forkval;
	int status = 0;

	argv = split_args(e->path, e->args, new_name, old_name);
	if (argv == NULL) {
		ERR(sh, "Out of memory!");
		return -1;
	}

	/* no need to use pthread_atfork() -- child will not be using
	 * any mutexes. */
	forkval = vfork();
	if (forkval == 0) {
		/* child process.  file descriptors will be closed
		 * because they were set as close-on-exec. */
		execve(e->path, argv, NULL);
		_exit(EXIT_FAILURE);	/* if execve() failed */
	}

	free_argv(argv);

	if (forkval == -1) {
		ERR(sh, "Error while forking process.");
		return -1;
	}

	/* parent process.  wait for child to finish */
	if (waitpid(forkval, &status, 0) == -1 || !WIFEXITED(status)) {
		ERR(sh, "Child process %s did not exit cleanly.",
		    e->path);
		return -1;
	}
	return WEXITSTATUS(status);
}

/* reloads the policy pointed to by the handle, used locally by install 
 * and exported for user reload requests */
int semanage_reload_policy(semanage_handle_t * sh)
{
	int r = 0;

	if (!sh)
		return -1;

	if ((r = semanage_exec_prog(sh, sh->conf->load_policy, "", "")) != 0) {
		ERR(sh, "load_policy returned error code %d.", r);
	}
	return r;
}

hidden_def(semanage_reload_policy)

/* This expands the file_context.tmpl file to file_context and homedirs.template */
int semanage_split_fc(semanage_handle_t * sh)
{
	FILE *file_con = NULL;
	int fc = -1, hd = -1, retval = -1;
	char buf[PATH_MAX] = { 0 };

	/* I use fopen here instead of open so that I can use fgets which only reads a single line */
	file_con = fopen(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL), "r");
	if (!file_con) {
		ERR(sh, "Could not open %s for reading.",
		    semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL));
		goto cleanup;
	}

	fc = open(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
		  O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
	if (fc < 0) {
		ERR(sh, "Could not open %s for writing.",
		    semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC));
		goto cleanup;
	}
	hd = open(semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL),
		  O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
	if (hd < 0) {
		ERR(sh, "Could not open %s for writing.",
		    semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL));
		goto cleanup;
	}

	while (fgets_unlocked(buf, PATH_MAX, file_con)) {
		if (!strncmp(buf, "HOME_DIR", 8) ||
		    !strncmp(buf, "HOME_ROOT", 9) || strstr(buf, "ROLE") ||
		    strstr(buf, "USER")) {
			/* This contains one of the template variables, write it to homedir.template */
			if (write(hd, buf, strlen(buf)) < 0) {
				ERR(sh, "Write to %s failed.",
				    semanage_path(SEMANAGE_TMP,
						  SEMANAGE_HOMEDIR_TMPL));
				goto cleanup;
			}
		} else {
			if (write(fc, buf, strlen(buf)) < 0) {
				ERR(sh, "Write to %s failed.",
				    semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC));
				goto cleanup;
			}
		}
	}

	retval = 0;
      cleanup:
	if (file_con)
		fclose(file_con);
	if (fc >= 0)
		close(fc);
	if (hd >= 0)
		close(hd);

	return retval;

}

static int sefcontext_compile(semanage_handle_t * sh, const char *path) {

	int r;

	if (access(path, F_OK) != 0) {
		return 0;
	}

	if ((r = semanage_exec_prog(sh, sh->conf->sefcontext_compile, path, "")) != 0) {
		ERR(sh, "sefcontext_compile returned error code %d. Compiling %s", r, path);
		return -1;
	}

	return 0;
}

/* Load the contexts of the final tmp into the final selinux directory.
 * Return 0 on success, -3 on error.
 */
static int semanage_install_final_tmp(semanage_handle_t * sh)
{
	int status = -3;
	int ret = 0;
	int i = 0;
	const char *src = NULL;
	const char *dst = NULL;
	struct stat sb;
	char fn[PATH_MAX];

	/* For each of the final files install it if it exists.
	 * i = 1 to avoid copying the top level directory.
	 */
	for (i = 1; i < SEMANAGE_FINAL_PATH_NUM; i++) {
		src = semanage_final_path(SEMANAGE_FINAL_TMP, i);
		dst = semanage_final_path(SEMANAGE_FINAL_SELINUX, i);

		/* skip file if src doesn't exist */
		if (stat(src, &sb) != 0) continue;

		/* skip genhomedircon if configured */
		if (sh->conf->disable_genhomedircon &&
		    i == SEMANAGE_FC_HOMEDIRS) continue;
		
		strcpy(fn, dst);
		ret = semanage_mkpath(sh, dirname(fn));
		if (ret < 0) {
			goto cleanup;
		}

		ret = semanage_copy_file(src, dst, sh->conf->file_mode);
		if (ret < 0) {
			ERR(sh, "Could not copy %s to %s.", src, dst);
			goto cleanup;
		}
	}

	if (!sh->do_reload)
		goto skip_reload;

	/* This stats what libselinux says the active store is (according to config)
	 * and what we are installing to, to decide if they are the same store. If
	 * they are not then we do not reload policy.
	 */
	const char *really_active_store = selinux_policy_root();
	struct stat astore;
	struct stat istore;
	const char *storepath = semanage_final_path(SEMANAGE_FINAL_SELINUX,
						    SEMANAGE_FINAL_TOPLEVEL);

	if (stat(really_active_store, &astore) == 0) {
		if (stat(storepath, &istore)) {
			ERR(sh, "Could not stat store path %s.", storepath);
			goto cleanup;
		}

		if (!(astore.st_ino == istore.st_ino &&
		      astore.st_dev == istore.st_dev)) {
			/* They are not the same store */
			goto skip_reload;
		}
	} else if (errno == ENOENT &&
		   strcmp(really_active_store, storepath) != 0) {
		errno = 0;
		goto skip_reload;
	}

	if (semanage_reload_policy(sh)) {
		goto cleanup;
	}

skip_reload:
	if (sh->do_check_contexts) {
		ret = semanage_exec_prog(
			sh,
			sh->conf->setfiles,
			semanage_final_path(SEMANAGE_FINAL_SELINUX,
					    SEMANAGE_KERNEL),
			semanage_final_path(SEMANAGE_FINAL_SELINUX,
					    SEMANAGE_FC));
		if (ret != 0) {
			ERR(sh, "setfiles returned error code %d.", ret);
			goto cleanup;
		}
	}

	if (sefcontext_compile(sh,
		    semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC)) != 0) {
		goto cleanup;
	}

	if (sefcontext_compile(sh,
		    semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC_LOCAL)) != 0) {
		goto cleanup;
	}

	if (sefcontext_compile(sh,
		    semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC_HOMEDIRS)) != 0) {
		goto cleanup;
	}

	status = 0;
cleanup:
	return status;
}

/* Prepare the sandbox to be installed by making a backup of the
 * current active directory.  Then copy the sandbox to the active
 * directory.  Return the new commit number on success, negative
 * values on error. */
static int semanage_commit_sandbox(semanage_handle_t * sh)
{
	int commit_number, fd, retval;
	char write_buf[32];
	const char *commit_filename =
	    semanage_path(SEMANAGE_TMP, SEMANAGE_COMMIT_NUM_FILE);
	ssize_t amount_written;
	const char *active = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_TOPLEVEL);
	const char *backup =
	    semanage_path(SEMANAGE_PREVIOUS, SEMANAGE_TOPLEVEL);
	const char *sandbox = semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL);
	struct stat buf;

	/* update the commit number */
	if ((commit_number = semanage_direct_get_serial(sh)) < 0) {
		return -1;
	}
	commit_number++;
	memset(write_buf, 0, sizeof(write_buf));
	snprintf(write_buf, sizeof(write_buf), "%d", commit_number);
	if ((fd =
	     open(commit_filename, O_WRONLY | O_CREAT | O_TRUNC,
		  S_IRUSR | S_IWUSR)) == -1) {
		ERR(sh, "Could not open commit number file %s for writing.",
		    commit_filename);
		return -1;
	}
	amount_written = write(fd, write_buf, sizeof(write_buf));
	if (amount_written == -1) {
		ERR(sh, "Error while writing commit number to %s.",
		    commit_filename);
		close(fd);
		return -1;
	}
	close(fd);

	retval = commit_number;

	if (semanage_get_active_lock(sh) < 0) {
		return -1;
	}
	/* make the backup of the current active directory */
	if (stat(backup, &buf) == 0) {
		if (S_ISDIR(buf.st_mode) &&
		    semanage_remove_directory(backup) != 0) {
			ERR(sh, "Could not remove previous backup %s.", backup);
			retval = -1;
			goto cleanup;
		}
	} else if (errno != ENOENT) {
		ERR(sh, "Could not stat directory %s.", backup);
		retval = -1;
		goto cleanup;
	}

	if (rename(active, backup) == -1) {
		ERR(sh, "Error while renaming %s to %s.", active, backup);
		retval = -1;
		goto cleanup;
	}

	/* clean up some files from the sandbox before install */
	/* remove homedir_template from sandbox */

	if (rename(sandbox, active) == -1) {
		ERR(sh, "Error while renaming %s to %s.", sandbox, active);
		/* note that if an error occurs during the next
		 * function then the store will be left in an
		 * inconsistent state */
		if (rename(backup, active) < 0)
			ERR(sh, "Error while renaming %s back to %s.", backup,
			    active);
		retval = -1;
		goto cleanup;
	}
	if (semanage_install_final_tmp(sh) != 0) {
		/* note that if an error occurs during the next three
		 * function then the store will be left in an
		 * inconsistent state */
		int errsv = errno;
		if (rename(active, sandbox) < 0)
			ERR(sh, "Error while renaming %s back to %s.", active,
			    sandbox);
		else if (rename(backup, active) < 0)
			ERR(sh, "Error while renaming %s back to %s.", backup,
			    active);
		else
			semanage_install_final_tmp(sh);
		errno = errsv;
		retval = -1;
		goto cleanup;
	}

	if (!sh->conf->save_previous) {
		int errsv = errno;
		retval = semanage_remove_directory(backup);
		if (retval < 0) {
			ERR(sh, "Could not delete previous directory %s.", backup);
			goto cleanup;
		}
		errno = errsv;
	}

      cleanup:
	semanage_release_active_lock(sh);
	return retval;
}

/* Takes the kernel policy in a sandbox, move it to the active
 * directory, copy it to the binary policy path, then load it.	Upon
 * error move the active directory back to the sandbox.	 This function
 * should be placed within a mutex lock to ensure that it runs
 * atomically.	Returns commit number on success, -1 on error.
 */
int semanage_install_sandbox(semanage_handle_t * sh)
{
	int retval = -1, commit_num = -1;

	if (sh->conf->load_policy == NULL) {
		ERR(sh,
		    "No load_policy program specified in configuration file.");
		goto cleanup;
	}
	if (sh->conf->setfiles == NULL) {
		ERR(sh, "No setfiles program specified in configuration file.");
		goto cleanup;
	}

	if (sh->conf->sefcontext_compile == NULL) {
		ERR(sh, "No sefcontext_compile program specified in configuration file.");
		goto cleanup;
	}

	if ((commit_num = semanage_commit_sandbox(sh)) < 0) {
		retval = commit_num;
		goto cleanup;
	}

	retval = commit_num;

      cleanup:
	return retval;

}

/********************* functions that manipulate lock *********************/

static int semanage_get_lock(semanage_handle_t * sh,
			     const char *lock_name, const char *lock_file)
{
	int fd;
	struct timeval origtime, curtime;
	int got_lock = 0;

	if ((fd = open(lock_file, O_RDONLY)) == -1) {
		if ((fd =
		     open(lock_file, O_RDWR | O_CREAT | O_TRUNC,
			  S_IRUSR | S_IWUSR)) == -1) {
			ERR(sh, "Could not open direct %s at %s.", lock_name,
			    lock_file);
			return -1;
		}
	}
	if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
		ERR(sh, "Could not set close-on-exec for %s at %s.", lock_name,
		    lock_file);
		close(fd);
		return -1;
	}

	if (sh->timeout == 0) {
		/* return immediately */
		origtime.tv_sec = 0;
	} else {
		origtime.tv_sec = sh->timeout;
	}
	origtime.tv_usec = 0;
	do {
		curtime.tv_sec = 1;
		curtime.tv_usec = 0;
		if (flock(fd, LOCK_EX | LOCK_NB) == 0) {
			got_lock = 1;
			break;
		} else if (errno != EAGAIN) {
			ERR(sh, "Error obtaining direct %s at %s.", lock_name,
			    lock_file);
			close(fd);
			return -1;
		}
		if (origtime.tv_sec > 0 || sh->timeout == -1) {
			if (select(0, NULL, NULL, NULL, &curtime) == -1) {
				if (errno == EINTR) {
					continue;
				}
				ERR(sh,
				    "Error while waiting to get direct %s at %s.",
				    lock_name, lock_file);
				close(fd);
				return -1;
			}
			origtime.tv_sec--;
		}
	} while (origtime.tv_sec > 0 || sh->timeout == -1);
	if (!got_lock) {
		ERR(sh, "Could not get direct %s at %s.", lock_name, lock_file);
		close(fd);
		return -1;
	}
	return fd;
}

/* Locking for the module store for transactions.  This is very basic
 * locking of the module store and doesn't do anything if the module
 * store is being manipulated with a program not using this library
 * (but the policy should prevent that).  Returns 0 on success, -1 if
 * it could not obtain a lock.
 */
int semanage_get_trans_lock(semanage_handle_t * sh)
{
	const char *lock_file = semanage_files[SEMANAGE_TRANS_LOCK];

	if (sh->u.direct.translock_file_fd >= 0)
		return 0;

	sh->u.direct.translock_file_fd =
	    semanage_get_lock(sh, "transaction lock", lock_file);
	if (sh->u.direct.translock_file_fd >= 0) {
		return 0;
	} else {
		return -1;
	}
}

/* Locking for the module store for active store reading; this also includes
 * the file containing the commit number.  This is very basic locking
 * of the module store and doesn't do anything if the module store is
 * being manipulated with a program not using this library (but the
 * policy should prevent that).	 Returns 0 on success, -1 if it could
 * not obtain a lock.
 */
int semanage_get_active_lock(semanage_handle_t * sh)
{
	const char *lock_file = semanage_files[SEMANAGE_READ_LOCK];

	if (sh->u.direct.activelock_file_fd >= 0)
		return 0;

	sh->u.direct.activelock_file_fd =
	    semanage_get_lock(sh, "read lock", lock_file);
	if (sh->u.direct.activelock_file_fd >= 0) {
		return 0;
	} else {
		return -1;
	}
}

/* Releases the transaction lock.  Does nothing if there was not one already
 * there. */
void semanage_release_trans_lock(semanage_handle_t * sh)
{
	int errsv = errno;
	if (sh->u.direct.translock_file_fd >= 0) {
		flock(sh->u.direct.translock_file_fd, LOCK_UN);
		close(sh->u.direct.translock_file_fd);
		sh->u.direct.translock_file_fd = -1;
	}
	errno = errsv;
}

/* Releases the read lock.  Does nothing if there was not one already
 * there. */
void semanage_release_active_lock(semanage_handle_t * sh)
{
	int errsv = errno;
	if (sh->u.direct.activelock_file_fd >= 0) {
		flock(sh->u.direct.activelock_file_fd, LOCK_UN);
		close(sh->u.direct.activelock_file_fd);
		sh->u.direct.activelock_file_fd = -1;
	}
	errno = errsv;
}

/* Read the current commit number from the commit number file which
 * the handle is pointing, resetting the file pointer afterwards.
 * Return it (a non-negative number), or -1 on error. */
int semanage_direct_get_serial(semanage_handle_t * sh)
{
	char buf[32];
	int fd, commit_number;
	ssize_t amount_read;
	const char *commit_filename;
	memset(buf, 0, sizeof(buf));

	if (sh->is_in_transaction) {
		commit_filename =
		    semanage_path(SEMANAGE_TMP, SEMANAGE_COMMIT_NUM_FILE);
	} else {
		commit_filename =
		    semanage_path(SEMANAGE_ACTIVE, SEMANAGE_COMMIT_NUM_FILE);
	}

	if ((fd = open(commit_filename, O_RDONLY)) == -1) {
		if (errno == ENOENT) {
			/* the commit number file does not exist yet,
			 * so assume that the number is 0 */
			errno = 0;
			return 0;
		} else {
			ERR(sh, "Could not open commit number file %s.",
			    commit_filename);
			return -1;
		}
	}

	amount_read = read(fd, buf, sizeof(buf));
	if (amount_read == -1) {
		ERR(sh, "Error while reading commit number from %s.",
		    commit_filename);
		commit_number = -1;
	} else if (sscanf(buf, "%d", &commit_number) != 1) {
		/* if nothing was read, assume that the commit number is 0 */
		commit_number = 0;
	} else if (commit_number < 0) {
		/* read file ought never have negative values */
		ERR(sh,
		    "Commit number file %s is corrupted; it should only contain a non-negative integer.",
		    commit_filename);
		commit_number = -1;
	}

	close(fd);
	return commit_number;
}

/* HIGHER LEVEL COMMIT FUNCTIONS */

int semanage_load_files(semanage_handle_t * sh, cil_db_t *cildb, char **filenames, int numfiles)
{
	int retval = 0;
	FILE *fp;
	ssize_t size;
	char *data = NULL;
	char *filename;
	int i;

	for (i = 0; i < numfiles; i++) {
		filename = filenames[i];

		if ((fp = fopen(filename, "rb")) == NULL) {
			ERR(sh, "Could not open module file %s for reading.", filename);
			goto cleanup;
		}

		if ((size = bunzip(sh, fp, &data)) <= 0) {
			rewind(fp);
			__fsetlocking(fp, FSETLOCKING_BYCALLER);

			if (fseek(fp, 0, SEEK_END) != 0) {
				ERR(sh, "Failed to determine size of file %s.", filename);
				goto cleanup;
			}
			size = ftell(fp);
			rewind(fp);

			data = malloc(size);
			if (fread(data, size, 1, fp) != 1) {
				ERR(sh, "Failed to read file %s.", filename);
				goto cleanup;
			}
		}

		fclose(fp);
		fp = NULL;

		retval = cil_add_file(cildb, filename, data, size);
		if (retval != SEPOL_OK) {
			ERR(sh, "Error while reading from file %s.", filename);
			goto cleanup;
		}
	
		free(data);
		data = NULL;
	}

	return retval;

      cleanup:
	if (fp != NULL) {
		fclose(fp);
	}
	free(data);
	return -1;
}

/* 
 * Expands the policy contained within *base 
 */

/**
 * Read the policy from the sandbox (kernel)
 */
int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in)
{

	int retval = STATUS_ERR;
	const char *kernel_filename = NULL;
	struct sepol_policy_file *pf = NULL;
	FILE *infile = NULL;

	if ((kernel_filename =
	     semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL)) == NULL) {
		goto cleanup;
	}
	if ((infile = fopen(kernel_filename, "r")) == NULL) {
		ERR(sh, "Could not open kernel policy %s for reading.",
		    kernel_filename);
		goto cleanup;
	}
	__fsetlocking(infile, FSETLOCKING_BYCALLER);
	if (sepol_policy_file_create(&pf)) {
		ERR(sh, "Out of memory!");
		goto cleanup;
	}
	sepol_policy_file_set_fp(pf, infile);
	sepol_policy_file_set_handle(pf, sh->sepolh);
	if (sepol_policydb_read(in, pf) == -1) {
		ERR(sh, "Error while reading kernel policy from %s.",
		    kernel_filename);
		goto cleanup;
	}
	retval = STATUS_SUCCESS;

      cleanup:
	if (infile != NULL) {
		fclose(infile);
	}
	sepol_policy_file_free(pf);
	return retval;
}
/**
 * Writes the final policy to the sandbox (kernel)
 */
int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out)
{

	int retval = STATUS_ERR;
	const char *kernel_filename = NULL;
	struct sepol_policy_file *pf = NULL;
	FILE *outfile = NULL;

	if ((kernel_filename =
	     semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL)) == NULL) {
		goto cleanup;
	}
	if ((outfile = fopen(kernel_filename, "wb")) == NULL) {
		ERR(sh, "Could not open kernel policy %s for writing.",
		    kernel_filename);
		goto cleanup;
	}
	__fsetlocking(outfile, FSETLOCKING_BYCALLER);
	if (sepol_policy_file_create(&pf)) {
		ERR(sh, "Out of memory!");
		goto cleanup;
	}
	sepol_policy_file_set_fp(pf, outfile);
	sepol_policy_file_set_handle(pf, sh->sepolh);
	if (sepol_policydb_write(out, pf) == -1) {
		ERR(sh, "Error while writing kernel policy to %s.",
		    kernel_filename);
		goto cleanup;
	}
	retval = STATUS_SUCCESS;

      cleanup:
	if (outfile != NULL) {
		fclose(outfile);
	}
	sepol_policy_file_free(pf);
	return retval;
}

/* Execute the module verification programs for each source module.
 * Returns 0 if every verifier returned success, -1 on error.
 */
int semanage_verify_modules(semanage_handle_t * sh,
			    char **module_filenames, int num_modules)
{
	int i, retval;
	semanage_conf_t *conf = sh->conf;
	if (conf->mod_prog == NULL) {
		return 0;
	}
	for (i = 0; i < num_modules; i++) {
		char *module = module_filenames[i];
		external_prog_t *e;
		for (e = conf->mod_prog; e != NULL; e = e->next) {
			if ((retval =
			     semanage_exec_prog(sh, e, module, "$<")) != 0) {
				return -1;
			}
		}
	}
	return 0;
}

/* Execute the linker verification programs for the linked (but not
 * expanded) base.  Returns 0 if every verifier returned success, -1
 * on error.
 */
int semanage_verify_linked(semanage_handle_t * sh)
{
	external_prog_t *e;
	semanage_conf_t *conf = sh->conf;
	const char *linked_filename =
	    semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED);
	int retval = -1;
	if (conf->linked_prog == NULL) {
		return 0;
	}
	for (e = conf->linked_prog; e != NULL; e = e->next) {
		if (semanage_exec_prog(sh, e, linked_filename, "$<") != 0) {
			goto cleanup;
		}
	}
	retval = 0;
      cleanup:
	return retval;
}

/* Execute each of the kernel verification programs.  Returns 0 if
 * every verifier returned success, -1 on error.
 */
int semanage_verify_kernel(semanage_handle_t * sh)
{
	int retval = -1;
	const char *kernel_filename =
	    semanage_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL);
	semanage_conf_t *conf = sh->conf;
	external_prog_t *e;
	if (conf->kernel_prog == NULL) {
		return 0;
	}
	for (e = conf->kernel_prog; e != NULL; e = e->next) {
		if (semanage_exec_prog(sh, e, kernel_filename, "$<") != 0) {
			goto cleanup;
		}
	}
	retval = 0;
      cleanup:
	return retval;
}

/********************* functions that sort file contexts *********************/

/* Free the given node. */
static void semanage_fc_node_destroy(semanage_file_context_node_t * x)
{
	free(x->path);
	free(x->file_type);
	free(x->context);
	free(x);
}

/* Free the linked list of nodes starting at the given node. */
static void semanage_fc_node_list_destroy(semanage_file_context_node_t * x)
{
	semanage_file_context_node_t *temp;

	while (x) {
		temp = x;
		x = x->next;
		semanage_fc_node_destroy(temp);
	}
}

/* Free the linked list of buckets (and their node lists) 
 * starting at the given bucket. */
static void semanage_fc_bucket_list_destroy(semanage_file_context_bucket_t * x)
{
	semanage_file_context_bucket_t *temp;

	while (x) {
		temp = x;
		x = x->next;
		semanage_fc_node_list_destroy(temp->data);
		free(temp);
	}
}

/* Compares two file contexts' regular expressions and returns:
 *    -1 if a is less specific than b
 *     0 if a and be are equally specific
 *     1 if a is more specific than b
 * The comparison is based on the following heuristics,
 *  in order from most important to least important, given a and b:
 *     If a is a regular expression and b is not,
 *      -> a is less specific than b.
 *     If a's stem length is shorter than b's stem length,
 *      -> a is less specific than b.
 *     If a's string length is shorter than b's string length,
 *      -> a is less specific than b.
 *     If a does not have a specified type and b does not,
 *      -> a is less specific than b.
 * FIXME: These heuristics are imperfect, but good enough for 
 * now.  A proper comparison would determine which (if either)
 * regular expression is a subset of the other.
 */
static int semanage_fc_compare(semanage_file_context_node_t * a,
			       semanage_file_context_node_t * b)
{
	int a_has_meta = (a->meta >= 0);
	int b_has_meta = (b->meta >= 0);

	/* Check to see if either a or b are regexes
	 *  and the other isn't. */
	if (a_has_meta && !b_has_meta)
		return -1;
	if (b_has_meta && !a_has_meta)
		return 1;

	/* Check to see if either a or b have a shorter stem
	 *  length than the other. */
	if (a->meta < b->meta)
		return -1;
	if (b->meta < a->meta)
		return 1;

	/* Check to see if either a or b have a shorter string
	 *  length than the other. */
	if (a->effective_len < b->effective_len)
		return -1;
	if (b->effective_len < a->effective_len)
		return 1;

	/* Check to see if either a or b has a specified type
	 *  and the other doesn't. */
	if (!a->file_type && b->file_type)
		return -1;
	if (!b->file_type && a->file_type)
		return 1;

	/* If none of the above conditions were satisfied, 
	 * then a and b are equally specific. */
	return 0;
}

/* Merges two sorted file context linked lists into a single sorted one.
 * The left list is assumed to represent nodes that came first in the original ordering. 
 * The final sorted list is returned.
 */
static semanage_file_context_node_t
    * semanage_fc_merge(semanage_file_context_node_t * left,
			semanage_file_context_node_t * right)
{
	semanage_file_context_node_t *head;
	semanage_file_context_node_t *current;
	semanage_file_context_node_t *tail;

	if (!left)
		return right;

	if (!right)
		return left;

	if (semanage_fc_compare(left, right) == 1) {
		head = tail = right;
		right = right->next;
	} else {
		head = tail = left;
		left = left->next;
	}

	while (left && right) {
		/* if left was more specific than right,
		 * insert right before left.  Otherwise leave order alone. */
		if (semanage_fc_compare(left, right) == 1) {
			current = right;
			right = right->next;
		} else {
			current = left;
			left = left->next;
		}

		tail = tail->next = current;
	}

	tail->next = (left != NULL) ? left : right;

	return head;
}

/* Sorts file contexts from least specific to most specific.
 * A bucket linked list is passed in.  Upon completion,
 * there is only one bucket (pointed to by master) that 
 * contains a linked list of all the file contexts in sorted order.
 * Explanation of the algorithm:
 *  This is a stable implementation of an iterative merge sort.
 *  Each bucket initially has a linked list of file contexts
 *   that are 1 node long.
 *  Each pass, buckets (and the nodes they contain) are merged 
 *   two at time.
 *  Buckets are merged until there is only one bucket left, 
 *   containing the list of file contexts, sorted.
 */
static void semanage_fc_merge_sort(semanage_file_context_bucket_t * master)
{
	semanage_file_context_bucket_t *current;
	semanage_file_context_bucket_t *temp;

	/* Loop until master is the only bucket left.
	 * When we stop master contains the sorted list. */
	while (master->next) {
		current = master;

		/* Merge buckets two-by-two. 
		 * If there is an odd number of buckets, the last 
		 * bucket will be left alone, which corresponds 
		 * to the operation of merging it with an empty bucket. */
		while (current) {
			if (current->next) {
				current->data =
				    semanage_fc_merge(current->data,
						      current->next->data);
				temp = current->next;
				current->next = current->next->next;

				/* Free the (now empty) second bucket.
				 * (This does not touch the node list
				 * in the bucket because it has been 
				 * shifted over to the first bucket. */
				free(temp);
			}
			current = current->next;
		}
	}
}

/* Compute the location of the first regular expression 
 *   meta character in the path of the given node, if it exists. 
 * On return:
 *     fc_node->meta = position of meta character, if it exists
 *			(-1 corresponds to no character)
 */
static void semanage_fc_find_meta(semanage_file_context_node_t * fc_node)
{
	int c = 0;
	int escape_chars = 0;

	fc_node->meta = -1;

	/* Note: this while loop has been adapted from
	 *  spec_hasMetaChars in matchpathcon.c from
	 *  libselinux-1.22. */
	while (fc_node->path[c] != '\0') {
		switch (fc_node->path[c]) {
		case '.':
		case '^':
		case '$':
		case '?':
		case '*':
		case '+':
		case '|':
		case '[':
		case '(':
		case '{':
			fc_node->meta = c - escape_chars;
			return;
		case '\\':
			/* If an escape character is found,
			 *  skip the next character. */
			c++;
			escape_chars++;
			break;
		}

		c++;
	}
}

/* Replicates strchr, but limits search to buf_len characters. */
static char *semanage_strnchr(const char *buf, size_t buf_len, char c)
{
	size_t idx = 0;

	if (buf == NULL)
		return NULL;
	if (buf_len <= 0)
		return NULL;

	while (idx < buf_len) {
		if (buf[idx] == c)
			return (char *)buf + idx;
		idx++;
	}

	return NULL;
}

/* Returns a pointer to the end of line character in the given buffer.
 * Used in the context of a file context char buffer that we will be 
 * parsing and sorting.
 */
static char *semanage_get_line_end(const char *buf, size_t buf_len)
{
	char *line_end = NULL;

	if (buf == NULL)
		return NULL;
	if (buf_len <= 0)
		return NULL;

	line_end = semanage_strnchr(buf, buf_len, '\n');
	if (!line_end)
		line_end = semanage_strnchr(buf, buf_len, '\r');
	if (!line_end)
		line_end = semanage_strnchr(buf, buf_len, EOF);

	return line_end;
}

/*  Entry function for sorting a set of file context lines.
 *  Returns 0 on success, -1 on failure.
 *  Allocates a buffer pointed to by sorted_buf that contains the sorted lines.
 *  sorted_buf_len is set to the size of this buffer.
 *  This buffer is guaranteed to have a final \0 character. 
 *  This buffer must be released by the caller.
 */
int semanage_fc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len,
		     char **sorted_buf, size_t * sorted_buf_len)
{
	size_t start, finish, regex_len, type_len, context_len;
	size_t line_len, buf_remainder, i;
	ssize_t sanity_check;
	const char *line_buf, *line_end;
	char *sorted_buf_pos;
	int escape_chars, just_saw_escape;

	semanage_file_context_node_t *temp;
	semanage_file_context_node_t *head;
	semanage_file_context_node_t *current;
	semanage_file_context_bucket_t *master;
	semanage_file_context_bucket_t *bcurrent;

	i = 0;

	if (sh == NULL) {
		return -1;
	}
	if (buf == NULL) {
		ERR(sh, "Received NULL buffer.");
		return -1;
	}
	if (buf_len <= 0) {
		ERR(sh, "Received buffer of length 0.");
		return -1;
	}

	/* Initialize the head of the linked list 
	 * that will contain a node for each file context line. */
	head = current =
	    (semanage_file_context_node_t *) calloc(1,
						    sizeof
						    (semanage_file_context_node_t));
	if (!head) {
		ERR(sh, "Failure allocating memory.");
		return -1;
	}

	/* Parse the char buffer into a semanage_file_context_node_t linked list. */
	line_buf = buf;
	buf_remainder = buf_len;
	while ((line_end = semanage_get_line_end(line_buf, buf_remainder))) {
		line_len = line_end - line_buf + 1;
		sanity_check = buf_remainder - line_len;
		buf_remainder = buf_remainder - line_len;

		if (sanity_check < 0) {
			ERR(sh, "Failure parsing file context buffer.");
			semanage_fc_node_list_destroy(head);
			return -1;
		}

		if (line_len == 0 || line_len == 1) {
			line_buf = line_end + 1;
			continue;
		}

		/* Skip the whitespace at the front of the line. */
		for (i = 0; i < line_len; i++) {
			if (!isspace(line_buf[i]))
				break;
		}

		/* Check for a blank line. */
		if (i >= line_len) {
			line_buf = line_end + 1;
			continue;
		}

		/* Check if the line is a comment. */
		if (line_buf[i] == '#') {
			line_buf = line_end + 1;
			continue;
		}

		/* Allocate a new node. */
		temp =
		    (semanage_file_context_node_t *) calloc(1,
							    sizeof
							    (semanage_file_context_node_t));
		if (!temp) {
			ERR(sh, "Failure allocating memory.");
			semanage_fc_node_list_destroy(head);
			return -1;
		}
		temp->next = NULL;

		/* Extract the regular expression from the line. */
		escape_chars = 0;
		just_saw_escape = 0;
		start = i;
		while (i < line_len && (!isspace(line_buf[i]))) {
			if (line_buf[i] == '\\') {
				if (!just_saw_escape) {
					escape_chars++;
					just_saw_escape = 1;
				} else {
					/* We're looking at an escaped 
					   escape. Reset our flag. */
					just_saw_escape = 0;
				}
			} else {
				just_saw_escape = 0;
			}
			i++;
		}
		finish = i;
		regex_len = finish - start;

		if (regex_len == 0) {
			ERR(sh,
			    "WARNING: semanage_fc_sort: Regex of length 0.");
			semanage_fc_node_destroy(temp);
			line_buf = line_end + 1;
			continue;
		}

		temp->path = (char *)strndup(&line_buf[start], regex_len);
		if (!temp->path) {
			ERR(sh, "Failure allocating memory.");
			semanage_fc_node_destroy(temp);
			semanage_fc_node_list_destroy(head);
			return -1;
		}

		/* Skip the whitespace after the regular expression. */
		for (; i < line_len; i++) {
			if (!isspace(line_buf[i]))
				break;
		}
		if (i == line_len) {
			ERR(sh,
			    "WARNING: semanage_fc_sort: Incomplete context. %s", temp->path);
			semanage_fc_node_destroy(temp);
			line_buf = line_end + 1;
			continue;
		}

		/* Extract the inode type from the line (if it exists). */
		if (line_buf[i] == '-') {
			type_len = 2;	/* defined as '--', '-d', '-f', etc. */

			if (i + type_len >= line_len) {
				ERR(sh,
				    "WARNING: semanage_fc_sort: Incomplete context. %s", temp->path);
				semanage_fc_node_destroy(temp);
				line_buf = line_end + 1;
				continue;
			}

			/* Record the inode type. */
			temp->file_type =
			    (char *)strndup(&line_buf[i], type_len);
			if (!temp->file_type) {
				ERR(sh, "Failure allocating memory.");
				semanage_fc_node_destroy(temp);
				semanage_fc_node_list_destroy(head);
				return -1;
			}

			i += type_len;

			/* Skip the whitespace after the type. */
			for (; i < line_len; i++) {
				if (!isspace(line_buf[i]))
					break;
			}
			if (i == line_len) {
				ERR(sh,
				    "WARNING: semanage_fc_sort: Incomplete context. %s", temp->path);
				semanage_fc_node_destroy(temp);
				line_buf = line_end + 1;
				continue;
			}
		} else {
			type_len = 0;	/* inode type did not exist in the file context */
		}

		/* Extract the context from the line. */
		start = i;
		while (i < line_len && (!isspace(line_buf[i])))
			i++;
		finish = i;
		context_len = finish - start;

		temp->context = (char *)strndup(&line_buf[start], context_len);
		if (!temp->context) {
			ERR(sh, "Failure allocating memory.");
			semanage_fc_node_destroy(temp);
			semanage_fc_node_list_destroy(head);
			return -1;
		}

		/* Initialize the data about the file context. */
		temp->path_len = regex_len;
		temp->effective_len = regex_len - escape_chars;
		temp->type_len = type_len;
		temp->context_len = context_len;
		semanage_fc_find_meta(temp);

		/* Add this node to the end of the linked list. */
		current->next = temp;
		current = current->next;

		line_buf = line_end + 1;
	}

	/* Create the bucket linked list from the node linked list. */
	current = head->next;
	bcurrent = master = (semanage_file_context_bucket_t *)
	    calloc(1, sizeof(semanage_file_context_bucket_t));
	if (!master) {
		ERR(sh, "Failure allocating memory.");
		semanage_fc_node_list_destroy(head);
		return -1;
	}

	/* Free the head node, as it is no longer used. */
	semanage_fc_node_destroy(head);
	head = NULL;

	/* Place each node into a bucket. */
	while (current) {
		bcurrent->data = current;
		current = current->next;

		/* Detach the node in the bucket from the old list. */
		bcurrent->data->next = NULL;

		/* If we need another bucket, add one to the end. */
		if (current) {
			bcurrent->next = (semanage_file_context_bucket_t *)
			    calloc(1, sizeof(semanage_file_context_bucket_t));
			if (!(bcurrent->next)) {
				ERR(sh, "Failure allocating memory.");
				semanage_fc_bucket_list_destroy(master);
				return -1;
			}

			bcurrent = bcurrent->next;
		}
	}

	/* Sort the bucket list. */
	semanage_fc_merge_sort(master);

	/* First, calculate how much space we'll need for 
	 * the newly sorted block of data.  (We don't just
	 * use buf_len for this because we have extracted
	 * comments and whitespace.) */
	i = 0;
	current = master->data;
	while (current) {
		i += current->path_len + 1;	/* +1 for a tab */
		if (current->file_type) {
			i += current->type_len + 1;	/* +1 for a tab */
		}
		i += current->context_len + 1;	/* +1 for a newline */
		current = current->next;
	}
	i = i + 1;		/* +1 for trailing \0 */

	/* Allocate the buffer for the sorted list. */
	*sorted_buf = calloc(i, sizeof(char));
	if (!*sorted_buf) {
		ERR(sh, "Failure allocating memory.");
		semanage_fc_bucket_list_destroy(master);
		return -1;
	}
	*sorted_buf_len = i;

	/* Output the sorted semanage_file_context linked list to the char buffer. */
	sorted_buf_pos = *sorted_buf;
	current = master->data;
	while (current) {
		/* Output the path. */
		i = current->path_len + 1;	/* +1 for tab */
		snprintf(sorted_buf_pos, i + 1, "%s\t", current->path);
		sorted_buf_pos = sorted_buf_pos + i;

		/* Output the type, if there is one. */
		if (current->file_type) {
			i = strlen(current->file_type) + 1;	/* +1 for tab */
			snprintf(sorted_buf_pos, i + 1, "%s\t",
				 current->file_type);
			sorted_buf_pos = sorted_buf_pos + i;
		}

		/* Output the context. */
		i = strlen(current->context) + 1;	/* +1 for newline */
		snprintf(sorted_buf_pos, i + 1, "%s\n", current->context);
		sorted_buf_pos = sorted_buf_pos + i;

		current = current->next;
	}

	/* Clean up. */
	semanage_fc_bucket_list_destroy(master);

	/* Sanity check. */
	sorted_buf_pos++;
	if ((sorted_buf_pos - *sorted_buf) != (ssize_t) * sorted_buf_len) {
		ERR(sh, "Failure writing sorted buffer.");
		free(*sorted_buf);
		*sorted_buf = NULL;
		return -1;
	}

	return 0;
}

/********************* functions that sort netfilter contexts *********************/
#define NC_SORT_NAMES { "pre", "base", "module", "local", "post" }
#define NC_SORT_NAMES_LEN { 3, 4, 6, 5, 4 }
#define NC_SORT_NEL 5
static void semanage_nc_destroy_ruletab(semanage_netfilter_context_node_t *
					ruletab[NC_SORT_NEL][2])
{
	semanage_netfilter_context_node_t *curr, *next;
	int i;

	for (i = 0; i < NC_SORT_NEL; i++) {
		for (curr = ruletab[i][0]; curr != NULL; curr = next) {
			next = curr->next;
			free(curr->rule);
			free(curr);
		}
	}
}

/*  Entry function for sorting a set of netfilter context lines.
 *  Returns 0 on success, -1 on failure.
 *  Allocates a buffer pointed to by sorted_buf that contains the sorted lines.
 *  sorted_buf_len is set to the size of this buffer.
 *  This buffer is guaranteed to have a final \0 character. 
 *  This buffer must be released by the caller.
 */
int semanage_nc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len,
		     char **sorted_buf, size_t * sorted_buf_len)
{

	/* parsing bits */
	const char *priority_names[] = NC_SORT_NAMES;
	const int priority_names_len[] = NC_SORT_NAMES_LEN;
	size_t line_len, buf_remainder, i, offset;
	const char *line_buf, *line_end;

	/* ruletab bits */
	/* keep track of the head (index 0) and tail (index 1) with this array */
	semanage_netfilter_context_node_t *ruletab[NC_SORT_NEL][2];
	semanage_netfilter_context_node_t *curr, *node;
	int priority;

	/* sorted buffer bits */
	char *sorted_buf_pos;
	size_t count;

	/* initialize ruletab */
	memset(ruletab, 0,
	       NC_SORT_NEL * 2 * sizeof(semanage_netfilter_context_node_t *));

	/* while lines to be read */
	line_buf = buf;
	buf_remainder = buf_len;
	while ((line_end = semanage_get_line_end(line_buf, buf_remainder))) {
		line_len = line_end - line_buf + 1;
		buf_remainder = buf_remainder - line_len;

		if (line_len == 0 || line_len == 1) {
			line_buf = line_end + 1;
			continue;
		}

		/* Skip the whitespace at the front of the line. */
		for (i = 0; i < line_len; i++) {
			if (!isspace(line_buf[i]))
				break;
		}

		/* Check for a blank line. */
		if (i >= line_len) {
			line_buf = line_end + 1;
			continue;
		}

		/* Check if the line is a comment. */
		if (line_buf[i] == '#') {
			line_buf = line_end + 1;
			continue;
		}

		/* extract priority */
		priority = -1;
		offset = 0;
		for (i = 0; i < NC_SORT_NEL; i++) {
			if (strncmp
			    (line_buf, priority_names[i],
			     priority_names_len[i]) == 0) {
				priority = i;
				offset = priority_names_len[i];
				break;
			}
		}

		if (priority < 0) {
			ERR(sh, "Netfilter context line missing priority.");
			semanage_nc_destroy_ruletab(ruletab);
			return -1;
		}

		/* skip over whitespace */
		for (; offset < line_len && isspace(line_buf[offset]);
		     offset++) ;

		/* load rule into node */
		node = (semanage_netfilter_context_node_t *)
		    malloc(sizeof(semanage_netfilter_context_node_t));
		if (!node) {
			ERR(sh, "Failure allocating memory.");
			semanage_nc_destroy_ruletab(ruletab);
			return -1;
		}

		node->rule =
		    (char *)strndup(line_buf + offset, line_len - offset);
		node->rule_len = line_len - offset;
		node->next = NULL;

		if (!node->rule) {
			ERR(sh, "Failure allocating memory.");
			free(node);
			semanage_nc_destroy_ruletab(ruletab);
			return -1;
		}

		/* add node to rule table */
		if (ruletab[priority][0] && ruletab[priority][1]) {
			/* add to end of list, update tail pointer */
			ruletab[priority][1]->next = node;
			ruletab[priority][1] = node;
		} else {
			/* this list is empty, make head and tail point to the node */
			ruletab[priority][0] = ruletab[priority][1] = node;
		}

		line_buf = line_end + 1;
	}

	/* First, calculate how much space we'll need for 
	 * the newly sorted block of data.  (We don't just
	 * use buf_len for this because we have extracted
	 * comments and whitespace.)  Start at 1 for trailing \0 */
	count = 1;
	for (i = 0; i < NC_SORT_NEL; i++)
		for (curr = ruletab[i][0]; curr != NULL; curr = curr->next)
			count += curr->rule_len;

	/* Allocate the buffer for the sorted list. */
	*sorted_buf = calloc(count, sizeof(char));
	if (!*sorted_buf) {
		ERR(sh, "Failure allocating memory.");
		semanage_nc_destroy_ruletab(ruletab);
		return -1;
	}
	*sorted_buf_len = count;

	/* write out rule buffer */
	sorted_buf_pos = *sorted_buf;
	for (i = 0; i < NC_SORT_NEL; i++) {
		for (curr = ruletab[i][0]; curr != NULL; curr = curr->next) {
			/* put rule into buffer */
			snprintf(sorted_buf_pos, curr->rule_len + 1, "%s\n", curr->rule);	/* +1 for newline */
			sorted_buf_pos = sorted_buf_pos + curr->rule_len;
		}
	}

	/* free ruletab */
	semanage_nc_destroy_ruletab(ruletab);

	return 0;
}
