
/*
 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 
 */
/*
 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
 *
 *	Support for enhanced MLS infrastructure.
 *
 * Updated: Frank Mayer <mayerf@tresys.com>
 *          and Karl MacMillan <kmacmillan@tresys.com>
 *
 * 	Added conditional policy language extensions
 *
 * Updated: Red Hat, Inc.  James Morris <jmorris@redhat.com>
 *
 *      Fine-grained netlink support
 *      IPv6 support
 *      Code cleanup
 *
 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
 * Copyright (C) 2003 - 2004 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
 */

/* FLASK */

/*
 * Implementation of the security services.
 */

/* Initial sizes malloc'd for sepol_compute_av_reason_buffer() support */
#define REASON_BUF_SIZE 2048
#define EXPR_BUF_SIZE 1024
#define STACK_LEN 32

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <sepol/policydb/policydb.h>
#include <sepol/policydb/sidtab.h>
#include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/flask.h>
#include <sepol/policydb/util.h>

#include "debug.h"
#include "private.h"
#include "context.h"
#include "av_permissions.h"
#include "dso.h"
#include "mls.h"

#define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0)
#define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0)

static int selinux_enforcing = 1;

static sidtab_t mysidtab, *sidtab = &mysidtab;
static policydb_t mypolicydb, *policydb = &mypolicydb;

/* Used by sepol_compute_av_reason_buffer() to keep track of entries */
static int reason_buf_used;
static int reason_buf_len;

/* Stack services for RPN to infix conversion. */
static char **stack;
static int stack_len;
static int next_stack_entry;

static void push(char *expr_ptr)
{
	if (next_stack_entry >= stack_len) {
		char **new_stack = stack;
		int new_stack_len;

		if (stack_len == 0)
			new_stack_len = STACK_LEN;
		else
			new_stack_len = stack_len * 2;

		new_stack = realloc(stack, new_stack_len * sizeof(*stack));
		if (!new_stack) {
			ERR(NULL, "unable to allocate stack space");
			return;
		}
		stack_len = new_stack_len;
		stack = new_stack;
	}
	stack[next_stack_entry] = expr_ptr;
	next_stack_entry++;
}

static char *pop(void)
{
	next_stack_entry--;
	if (next_stack_entry < 0) {
		next_stack_entry = 0;
		ERR(NULL, "pop called with no stack entries");
		return NULL;
	}
	return stack[next_stack_entry];
}
/* End Stack services */

int hidden sepol_set_sidtab(sidtab_t * s)
{
	sidtab = s;
	return 0;
}

int hidden sepol_set_policydb(policydb_t * p)
{
	policydb = p;
	return 0;
}

int sepol_set_policydb_from_file(FILE * fp)
{
	struct policy_file pf;

	policy_file_init(&pf);
	pf.fp = fp;
	pf.type = PF_USE_STDIO;
	if (mypolicydb.policy_type)
		policydb_destroy(&mypolicydb);
	if (policydb_init(&mypolicydb)) {
		ERR(NULL, "Out of memory!");
		return -1;
	}
	if (policydb_read(&mypolicydb, &pf, 0)) {
		policydb_destroy(&mypolicydb);
		ERR(NULL, "can't read binary policy: %s", strerror(errno));
		return -1;
	}
	policydb = &mypolicydb;
	return sepol_sidtab_init(sidtab);
}

/*
 * The largest sequence number that has been used when
 * providing an access decision to the access vector cache.
 * The sequence number only changes when a policy change
 * occurs.
 */
static uint32_t latest_granting = 0;

/*
 * cat_expr_buf adds a string to an expression buffer and handles
 * realloc's if buffer is too small. The array of expression text
 * buffer pointers and its counter are globally defined here as
 * constraint_expr_eval_reason() sets them up and cat_expr_buf
 * updates the e_buf pointer.
 */
static int expr_counter;
static char **expr_list;
static int expr_buf_used;
static int expr_buf_len;

static void cat_expr_buf(char *e_buf, char *string)
{
	int len, new_buf_len;
	char *p, *new_buf = e_buf;

	while (1) {
		p = e_buf + expr_buf_used;
		len = snprintf(p, expr_buf_len - expr_buf_used, "%s", string);
		if (len < 0 || len >= expr_buf_len - expr_buf_used) {
			new_buf_len = expr_buf_len + EXPR_BUF_SIZE;
			new_buf = realloc(e_buf, new_buf_len);
			if (!new_buf) {
				ERR(NULL, "failed to realloc expr buffer");
				return;
			}
			/* Update new ptr in expr list and locally + new len */
			expr_list[expr_counter] = new_buf;
			e_buf = new_buf;
			expr_buf_len = new_buf_len;
		} else {
			expr_buf_used += len;
			return;
		}
	}
}

/*
 * If the POLICY_KERN version is >= POLICYDB_VERSION_CONSTRAINT_NAMES,
 * then for 'types' only, read the types_names->types list as it will
 * contain a list of types and attributes that were defined in the
 * policy source.
 * For user and role plus types (for policy vers <
 * POLICYDB_VERSION_CONSTRAINT_NAMES) just read the e->names list.
 */
static void get_name_list(constraint_expr_t *e, int type,
							char *src, char *op, int failed)
{
	ebitmap_t *types;
	int rc = 0;
	unsigned int i;
	char tmp_buf[128];
	int counter = 0;

	if (policydb->policy_type == POLICY_KERN &&
			policydb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES &&
			type == CEXPR_TYPE)
		types = &e->type_names->types;
	else
		types = &e->names;

	/* Find out how many entries */
	for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) {
		rc = ebitmap_get_bit(types, i);
		if (rc == 0)
			continue;
		else
			counter++;
	}
	snprintf(tmp_buf, sizeof(tmp_buf), "(%s%s", src, op);
	cat_expr_buf(expr_list[expr_counter], tmp_buf);

	if (counter == 0)
		cat_expr_buf(expr_list[expr_counter], "<empty_set> ");
	if (counter > 1)
		cat_expr_buf(expr_list[expr_counter], " {");
	if (counter >= 1) {
		for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) {
			rc = ebitmap_get_bit(types, i);
			if (rc == 0)
				continue;

			/* Collect entries */
			switch (type) {
			case CEXPR_USER:
				snprintf(tmp_buf, sizeof(tmp_buf), " %s",
							policydb->p_user_val_to_name[i]);
				break;
			case CEXPR_ROLE:
				snprintf(tmp_buf, sizeof(tmp_buf), " %s",
							policydb->p_role_val_to_name[i]);
				break;
			case CEXPR_TYPE:
				snprintf(tmp_buf, sizeof(tmp_buf), " %s",
							policydb->p_type_val_to_name[i]);
				break;
			}
			cat_expr_buf(expr_list[expr_counter], tmp_buf);
		}
	}
	if (counter > 1)
		cat_expr_buf(expr_list[expr_counter], " }");
	if (failed)
		cat_expr_buf(expr_list[expr_counter], " -Fail-) ");
	else
		cat_expr_buf(expr_list[expr_counter], ") ");

	return;
}

static void msgcat(char *src, char *tgt, char *op, int failed)
{
	char tmp_buf[128];
	if (failed)
		snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s -Fail-) ",
				src, op, tgt);
	else
		snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s) ",
				src, op, tgt);
	cat_expr_buf(expr_list[expr_counter], tmp_buf);
}

/* Returns a buffer with class, statement type and permissions */
static char *get_class_info(sepol_security_class_t tclass,
							constraint_node_t *constraint,
							context_struct_t *xcontext)
{
	constraint_expr_t *e;
	int mls, state_num;

	/* Find if MLS statement or not */
	mls = 0;
	for (e = constraint->expr; e; e = e->next) {
		if (e->attr >= CEXPR_L1L2) {
			mls = 1;
			break;
		}
	}

	/* Determine statement type */
	char *statements[] = {
		"constrain ",			/* 0 */
		"mlsconstrain ",		/* 1 */
		"validatetrans ",		/* 2 */
		"mlsvalidatetrans ",	/* 3 */
		0 };

	if (xcontext == NULL)
		state_num = mls + 0;
	else
		state_num = mls + 2;

	int class_buf_len = 0;
	int new_class_buf_len;
	int len, buf_used;
	char *class_buf = NULL, *p;
	char *new_class_buf = NULL;

	while (1) {
		new_class_buf_len = class_buf_len + EXPR_BUF_SIZE;
		new_class_buf = realloc(class_buf, new_class_buf_len);
			if (!new_class_buf)
				return NULL;
		class_buf_len = new_class_buf_len;
		class_buf = new_class_buf;
		buf_used = 0;
		p = class_buf;

		/* Add statement type */
		len = snprintf(p, class_buf_len - buf_used, "%s", statements[state_num]);
		if (len < 0 || len >= class_buf_len - buf_used)
			continue;

		/* Add class entry */
		p += len;
		buf_used += len;
		len = snprintf(p, class_buf_len - buf_used, "%s ",
				policydb->p_class_val_to_name[tclass - 1]);
		if (len < 0 || len >= class_buf_len - buf_used)
			continue;

		/* Add permission entries */
		p += len;
		buf_used += len;
		len = snprintf(p, class_buf_len - buf_used, "{%s } (",
				sepol_av_to_string(policydb, tclass, constraint->permissions));
		if (len < 0 || len >= class_buf_len - buf_used)
			continue;
		break;
	}
	return class_buf;
}

/*
 * Modified version of constraint_expr_eval that will process each
 * constraint as before but adds the information to text buffers that
 * will hold various components. The expression will be in RPN format,
 * therefore there is a stack based RPN to infix converter to produce
 * the final readable constraint.
 *
 * Return the boolean value of a constraint expression
 * when it is applied to the specified source and target
 * security contexts.
 *
 * xcontext is a special beast...  It is used by the validatetrans rules
 * only.  For these rules, scontext is the context before the transition,
 * tcontext is the context after the transition, and xcontext is the
 * context of the process performing the transition.  All other callers
 * of constraint_expr_eval_reason should pass in NULL for xcontext.
 *
 * This function will also build a buffer as the constraint is processed
 * for analysis. If this option is not required, then:
 *      'tclass' should be '0' and r_buf MUST be NULL.
 */
static int constraint_expr_eval_reason(context_struct_t *scontext,
				context_struct_t *tcontext,
				context_struct_t *xcontext,
				sepol_security_class_t tclass,
				constraint_node_t *constraint,
				char **r_buf,
				unsigned int flags)
{
	uint32_t val1, val2;
	context_struct_t *c;
	role_datum_t *r1, *r2;
	mls_level_t *l1, *l2;
	constraint_expr_t *e;
	int s[CEXPR_MAXDEPTH];
	int sp = -1;
	char tmp_buf[128];

/*
 * Define the s_t_x_num values that make up r1, t2 etc. in text strings
 * Set 1 = source, 2 = target, 3 = xcontext for validatetrans
 */
#define SOURCE  1
#define TARGET  2
#define XTARGET 3

	int s_t_x_num = SOURCE;

	/* Set 0 = fail, u = CEXPR_USER, r = CEXPR_ROLE, t = CEXPR_TYPE */
	int u_r_t = 0;

	char *src = NULL;
	char *tgt = NULL;
	int rc = 0, x;
	char *class_buf = NULL;

	class_buf = get_class_info(tclass, constraint, xcontext);
	if (!class_buf) {
		ERR(NULL, "failed to allocate class buffer");
		return -ENOMEM;
	}

	/* Original function but with buffer support */
	int expr_list_len = 0;
	expr_counter = 0;
	expr_list = NULL;
	for (e = constraint->expr; e; e = e->next) {
		/* Allocate a stack to hold expression buffer entries */
		if (expr_counter >= expr_list_len) {
			char **new_expr_list = expr_list;
			int new_expr_list_len;

			if (expr_list_len == 0)
				new_expr_list_len = STACK_LEN;
			else
				new_expr_list_len = expr_list_len * 2;

			new_expr_list = realloc(expr_list,
					new_expr_list_len * sizeof(*expr_list));
			if (!new_expr_list) {
				ERR(NULL, "failed to allocate expr buffer stack");
				rc = -ENOMEM;
				goto out;
			}
			expr_list_len = new_expr_list_len;
			expr_list = new_expr_list;
		}

		/*
		 * malloc a buffer to store each expression text component. If
		 * buffer is too small cat_expr_buf() will realloc extra space.
		 */
		expr_buf_len = EXPR_BUF_SIZE;
		expr_list[expr_counter] = malloc(expr_buf_len);
		if (!expr_list[expr_counter]) {
			ERR(NULL, "failed to allocate expr buffer");
			rc = -ENOMEM;
			goto out;
		}
		expr_buf_used = 0;

		/* Now process each expression of the constraint */
		switch (e->expr_type) {
		case CEXPR_NOT:
			BUG_ON(sp < 0);
			s[sp] = !s[sp];
			cat_expr_buf(expr_list[expr_counter], "not");
			break;
		case CEXPR_AND:
			BUG_ON(sp < 1);
			sp--;
			s[sp] &= s[sp + 1];
			cat_expr_buf(expr_list[expr_counter], "and");
			break;
		case CEXPR_OR:
			BUG_ON(sp < 1);
			sp--;
			s[sp] |= s[sp + 1];
			cat_expr_buf(expr_list[expr_counter], "or");
			break;
		case CEXPR_ATTR:
			if (sp == (CEXPR_MAXDEPTH - 1))
				goto out;

			switch (e->attr) {
			case CEXPR_USER:
				val1 = scontext->user;
				val2 = tcontext->user;
				free(src); src = strdup("u1");
				free(tgt); tgt = strdup("u2");
				break;
			case CEXPR_TYPE:
				val1 = scontext->type;
				val2 = tcontext->type;
				free(src); src = strdup("t1");
				free(tgt); tgt = strdup("t2");
				break;
			case CEXPR_ROLE:
				val1 = scontext->role;
				val2 = tcontext->role;
				r1 = policydb->role_val_to_struct[val1 - 1];
				r2 = policydb->role_val_to_struct[val2 - 1];
				free(src); src = strdup("r1");
				free(tgt); tgt = strdup("r2");

				switch (e->op) {
				case CEXPR_DOM:
					s[++sp] = ebitmap_get_bit(&r1->dominates, val2 - 1);
					msgcat(src, tgt, "dom", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_DOMBY:
					s[++sp] = ebitmap_get_bit(&r2->dominates, val1 - 1);
					msgcat(src, tgt, "domby", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_INCOMP:
					s[++sp] = (!ebitmap_get_bit(&r1->dominates, val2 - 1)
						 && !ebitmap_get_bit(&r2->dominates, val1 - 1));
					msgcat(src, tgt, "incomp", s[sp] == 0);
					expr_counter++;
					continue;
				default:
					break;
				}
				break;
			case CEXPR_L1L2:
				l1 = &(scontext->range.level[0]);
				l2 = &(tcontext->range.level[0]);
				free(src); src = strdup("l1");
				free(tgt); tgt = strdup("l2");
				goto mls_ops;
			case CEXPR_L1H2:
				l1 = &(scontext->range.level[0]);
				l2 = &(tcontext->range.level[1]);
				free(src); src = strdup("l1");
				free(tgt); tgt = strdup("h2");
				goto mls_ops;
			case CEXPR_H1L2:
				l1 = &(scontext->range.level[1]);
				l2 = &(tcontext->range.level[0]);
				free(src); src = strdup("h1");
				free(tgt); tgt = strdup("l2");
				goto mls_ops;
			case CEXPR_H1H2:
				l1 = &(scontext->range.level[1]);
				l2 = &(tcontext->range.level[1]);
				free(src); src = strdup("h1");
				free(tgt); tgt = strdup("h2");
				goto mls_ops;
			case CEXPR_L1H1:
				l1 = &(scontext->range.level[0]);
				l2 = &(scontext->range.level[1]);
				free(src); src = strdup("l1");
				free(tgt); tgt = strdup("h1");
				goto mls_ops;
			case CEXPR_L2H2:
				l1 = &(tcontext->range.level[0]);
				l2 = &(tcontext->range.level[1]);
				free(src); src = strdup("l2");
				free(tgt); tgt = strdup("h2");
mls_ops:
				switch (e->op) {
				case CEXPR_EQ:
					s[++sp] = mls_level_eq(l1, l2);
					msgcat(src, tgt, "eq", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_NEQ:
					s[++sp] = !mls_level_eq(l1, l2);
					msgcat(src, tgt, "!=", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_DOM:
					s[++sp] = mls_level_dom(l1, l2);
					msgcat(src, tgt, "dom", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_DOMBY:
					s[++sp] = mls_level_dom(l2, l1);
					msgcat(src, tgt, "domby", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_INCOMP:
					s[++sp] = mls_level_incomp(l2, l1);
					msgcat(src, tgt, "incomp", s[sp] == 0);
					expr_counter++;
					continue;
				default:
					BUG();
					goto out;
				}
				break;
			default:
				BUG();
				goto out;
			}

			switch (e->op) {
			case CEXPR_EQ:
				s[++sp] = (val1 == val2);
				msgcat(src, tgt, "==", s[sp] == 0);
				break;
			case CEXPR_NEQ:
				s[++sp] = (val1 != val2);
				msgcat(src, tgt, "!=", s[sp] == 0);
				break;
			default:
				BUG();
				goto out;
			}
			break;
		case CEXPR_NAMES:
			if (sp == (CEXPR_MAXDEPTH - 1))
				goto out;
			s_t_x_num = SOURCE;
			c = scontext;
			if (e->attr & CEXPR_TARGET) {
				s_t_x_num = TARGET;
				c = tcontext;
			} else if (e->attr & CEXPR_XTARGET) {
				s_t_x_num = XTARGET;
				c = xcontext;
			}
			if (!c) {
				BUG();
				goto out;
			}
			if (e->attr & CEXPR_USER) {
				u_r_t = CEXPR_USER;
				val1 = c->user;
				snprintf(tmp_buf, sizeof(tmp_buf), "u%d ", s_t_x_num);
				free(src); src = strdup(tmp_buf);
			} else if (e->attr & CEXPR_ROLE) {
				u_r_t = CEXPR_ROLE;
				val1 = c->role;
				snprintf(tmp_buf, sizeof(tmp_buf), "r%d ", s_t_x_num);
				free(src); src = strdup(tmp_buf);
			} else if (e->attr & CEXPR_TYPE) {
				u_r_t = CEXPR_TYPE;
				val1 = c->type;
				snprintf(tmp_buf, sizeof(tmp_buf), "t%d ", s_t_x_num);
				free(src); src = strdup(tmp_buf);
			} else {
				BUG();
				goto out;
			}

			switch (e->op) {
			case CEXPR_EQ:
				s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
				get_name_list(e, u_r_t, src, "==", s[sp] == 0);
				break;

			case CEXPR_NEQ:
				s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
				get_name_list(e, u_r_t, src, "!=", s[sp] == 0);
				break;
			default:
				BUG();
				goto out;
			}
			break;
		default:
			BUG();
			goto out;
		}
		expr_counter++;
	}

	/*
	 * At this point each expression of the constraint is in
	 * expr_list[n+1] and in RPN format. Now convert to 'infix'
	 */

	/*
	 * Save expr count but zero expr_counter to detect if
	 * 'BUG(); goto out;' was called as we need to release any used
	 * expr_list malloc's. Normally they are released by the RPN to
	 * infix code.
	 */
	int expr_count = expr_counter;
	expr_counter = 0;

	/*
	 * The array of expression answer buffer pointers and counter.
	 * Generate the same number of answer buffer entries as expression
	 * buffers (as there will never be more).
	 */
	char **answer_list;
	int answer_counter = 0;

	answer_list = malloc(expr_count * sizeof(*answer_list));
	if (!answer_list) {
		ERR(NULL, "failed to allocate answer stack");
		rc = -ENOMEM;
		goto out;
	}

	/* The pop operands */
	char *a;
	char *b;
	int a_len, b_len;

	/* Convert constraint from RPN to infix notation. */
	for (x = 0; x != expr_count; x++) {
		if (strncmp(expr_list[x], "and", 3) == 0 || strncmp(expr_list[x],
					"or", 2) == 0) {
			b = pop();
			b_len = strlen(b);
			a = pop();
			a_len = strlen(a);

			/* get a buffer to hold the answer */
			answer_list[answer_counter] = malloc(a_len + b_len + 8);
			if (!answer_list[answer_counter]) {
				ERR(NULL, "failed to allocate answer buffer");
				rc = -ENOMEM;
				goto out;
			}
			memset(answer_list[answer_counter], '\0', a_len + b_len + 8);

			sprintf(answer_list[answer_counter], "%s %s %s", a,
					expr_list[x], b);
			push(answer_list[answer_counter++]);
			free(a);
			free(b);
		} else if (strncmp(expr_list[x], "not", 3) == 0) {
			b = pop();
			b_len = strlen(b);

			answer_list[answer_counter] = malloc(b_len + 8);
			if (!answer_list[answer_counter]) {
				ERR(NULL, "failed to allocate answer buffer");
				rc = -ENOMEM;
				goto out;
			}
			memset(answer_list[answer_counter], '\0', b_len + 8);

			if (strncmp(b, "not", 3) == 0)
				sprintf(answer_list[answer_counter], "%s (%s)",
						expr_list[x], b);
			else
				sprintf(answer_list[answer_counter], "%s%s",
						expr_list[x], b);
			push(answer_list[answer_counter++]);
			free(b);
		} else {
			push(expr_list[x]);
		}
	}
	/* Get the final answer from tos and build constraint text */
	a = pop();

	/* Constraint calculation: rc = 0 is denied, rc = 1 is granted */
	sprintf(tmp_buf, "Constraint %s\n", s[0] ? "GRANTED" : "DENIED");

	int len, new_buf_len;
	char *p, **new_buf = r_buf;
	/*
	 * These contain the constraint components that are added to the
	 * callers reason buffer.
	 */
	char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 };

	/*
	 * This will add the constraints to the callers reason buffer (who is
	 * responsible for freeing the memory). It will handle any realloc's
	 * should the buffer be too short.
	 * The reason_buf_used and reason_buf_len counters are defined
	 * globally as multiple constraints can be in the buffer.
	 */

	if (r_buf && ((s[0] == 0) || ((s[0] == 1 &&
				(flags & SHOW_GRANTED) == SHOW_GRANTED)))) {
		for (x = 0; buffers[x] != NULL; x++) {
			while (1) {
				p = *r_buf + reason_buf_used;
				len = snprintf(p, reason_buf_len - reason_buf_used,
						"%s", buffers[x]);
				if (len < 0 || len >= reason_buf_len - reason_buf_used) {
					new_buf_len = reason_buf_len + REASON_BUF_SIZE;
					*new_buf = realloc(*r_buf, new_buf_len);
					if (!new_buf) {
						ERR(NULL, "failed to realloc reason buffer");
						goto out1;
					}
					**r_buf = **new_buf;
					reason_buf_len = new_buf_len;
					continue;
				} else {
					reason_buf_used += len;
					break;
				}
			}
		}
	}

out1:
	rc = s[0];
	free(a);

out:
	free(class_buf);
	free(src);
	free(tgt);

	if (expr_counter) {
		for (x = 0; expr_list[x] != NULL; x++)
			free(expr_list[x]);
	}
	return rc;
}

/*
 * Compute access vectors based on a context structure pair for
 * the permissions in a particular class.
 */
static int context_struct_compute_av(context_struct_t * scontext,
				     context_struct_t * tcontext,
				     sepol_security_class_t tclass,
				     sepol_access_vector_t requested,
				     struct sepol_av_decision *avd,
				     unsigned int *reason,
				     char **r_buf,
					 unsigned int flags)
{
	constraint_node_t *constraint;
	struct role_allow *ra;
	avtab_key_t avkey;
	class_datum_t *tclass_datum;
	avtab_ptr_t node;
	ebitmap_t *sattr, *tattr;
	ebitmap_node_t *snode, *tnode;
	unsigned int i, j;

	if (!tclass || tclass > policydb->p_classes.nprim) {
		ERR(NULL, "unrecognized class %d", tclass);
		return -EINVAL;
	}
	tclass_datum = policydb->class_val_to_struct[tclass - 1];

	/* 
	 * Initialize the access vectors to the default values.
	 */
	avd->allowed = 0;
	avd->decided = 0xffffffff;
	avd->auditallow = 0;
	avd->auditdeny = 0xffffffff;
	avd->seqno = latest_granting;
	*reason = 0;

	/*
	 * If a specific type enforcement rule was defined for
	 * this permission check, then use it.
	 */
	avkey.target_class = tclass;
	avkey.specified = AVTAB_AV;
	sattr = &policydb->type_attr_map[scontext->type - 1];
	tattr = &policydb->type_attr_map[tcontext->type - 1];
	ebitmap_for_each_bit(sattr, snode, i) {
		if (!ebitmap_node_get_bit(snode, i))
			continue;
		ebitmap_for_each_bit(tattr, tnode, j) {
			if (!ebitmap_node_get_bit(tnode, j))
				continue;
			avkey.source_type = i + 1;
			avkey.target_type = j + 1;
			for (node =
			     avtab_search_node(&policydb->te_avtab, &avkey);
			     node != NULL;
			     node =
			     avtab_search_node_next(node, avkey.specified)) {
				if (node->key.specified == AVTAB_ALLOWED)
					avd->allowed |= node->datum.data;
				else if (node->key.specified ==
					 AVTAB_AUDITALLOW)
					avd->auditallow |= node->datum.data;
				else if (node->key.specified == AVTAB_AUDITDENY)
					avd->auditdeny &= node->datum.data;
			}

			/* Check conditional av table for additional permissions */
			cond_compute_av(&policydb->te_cond_avtab, &avkey, avd);

		}
	}

	if (requested & ~avd->allowed) {
		*reason |= SEPOL_COMPUTEAV_TE;
		requested &= avd->allowed;
	}

	/* 
	 * Remove any permissions prohibited by a constraint (this includes
	 * the MLS policy).
	 */
	constraint = tclass_datum->constraints;
	while (constraint) {
		if ((constraint->permissions & (avd->allowed)) &&
		    !constraint_expr_eval_reason(scontext, tcontext, NULL,
					  tclass, constraint, r_buf, flags)) {
			avd->allowed =
			    (avd->allowed) & ~(constraint->permissions);
		}
		constraint = constraint->next;
	}

	if (requested & ~avd->allowed) {
		*reason |= SEPOL_COMPUTEAV_CONS;
		requested &= avd->allowed;
	}

	/* 
	 * If checking process transition permission and the
	 * role is changing, then check the (current_role, new_role) 
	 * pair.
	 */
	if (tclass == SECCLASS_PROCESS &&
	    (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) &&
	    scontext->role != tcontext->role) {
		for (ra = policydb->role_allow; ra; ra = ra->next) {
			if (scontext->role == ra->role &&
			    tcontext->role == ra->new_role)
				break;
		}
		if (!ra)
			avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION |
							  PROCESS__DYNTRANSITION);
	}

	if (requested & ~avd->allowed) {
		*reason |= SEPOL_COMPUTEAV_RBAC;
		requested &= avd->allowed;
	}

	return 0;
}

int hidden sepol_validate_transition(sepol_security_id_t oldsid,
				     sepol_security_id_t newsid,
				     sepol_security_id_t tasksid,
				     sepol_security_class_t tclass)
{
	context_struct_t *ocontext;
	context_struct_t *ncontext;
	context_struct_t *tcontext;
	class_datum_t *tclass_datum;
	constraint_node_t *constraint;

	if (!tclass || tclass > policydb->p_classes.nprim) {
		ERR(NULL, "unrecognized class %d", tclass);
		return -EINVAL;
	}
	tclass_datum = policydb->class_val_to_struct[tclass - 1];

	ocontext = sepol_sidtab_search(sidtab, oldsid);
	if (!ocontext) {
		ERR(NULL, "unrecognized SID %d", oldsid);
		return -EINVAL;
	}

	ncontext = sepol_sidtab_search(sidtab, newsid);
	if (!ncontext) {
		ERR(NULL, "unrecognized SID %d", newsid);
		return -EINVAL;
	}

	tcontext = sepol_sidtab_search(sidtab, tasksid);
	if (!tcontext) {
		ERR(NULL, "unrecognized SID %d", tasksid);
		return -EINVAL;
	}

	constraint = tclass_datum->validatetrans;
	while (constraint) {
		if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext,
					  0, constraint, NULL, 0)) {
			return -EPERM;
		}
		constraint = constraint->next;
	}

	return 0;
}

int hidden sepol_compute_av_reason(sepol_security_id_t ssid,
				   sepol_security_id_t tsid,
				   sepol_security_class_t tclass,
				   sepol_access_vector_t requested,
				   struct sepol_av_decision *avd,
				   unsigned int *reason)
{
	context_struct_t *scontext = 0, *tcontext = 0;
	int rc = 0;

	scontext = sepol_sidtab_search(sidtab, ssid);
	if (!scontext) {
		ERR(NULL, "unrecognized SID %d", ssid);
		rc = -EINVAL;
		goto out;
	}
	tcontext = sepol_sidtab_search(sidtab, tsid);
	if (!tcontext) {
		ERR(NULL, "unrecognized SID %d", tsid);
		rc = -EINVAL;
		goto out;
	}

	rc = context_struct_compute_av(scontext, tcontext, tclass,
					requested, avd, reason, NULL, 0);
      out:
	return rc;
}

/*
 * sepol_compute_av_reason_buffer - the reason buffer is malloc'd to
 * REASON_BUF_SIZE. If the buffer size is exceeded, then it is realloc'd
 * in the constraint_expr_eval_reason() function.
 */
int hidden sepol_compute_av_reason_buffer(sepol_security_id_t ssid,
				   sepol_security_id_t tsid,
				   sepol_security_class_t tclass,
				   sepol_access_vector_t requested,
				   struct sepol_av_decision *avd,
				   unsigned int *reason,
				   char **reason_buf,
				   unsigned int flags)
{
	context_struct_t *scontext = 0, *tcontext = 0;
	int rc = 0;

	scontext = sepol_sidtab_search(sidtab, ssid);
	if (!scontext) {
		ERR(NULL, "unrecognized SID %d", ssid);
		rc = -EINVAL;
		goto out;
	}
	tcontext = sepol_sidtab_search(sidtab, tsid);
	if (!tcontext) {
		ERR(NULL, "unrecognized SID %d", tsid);
		rc = -EINVAL;
		goto out;
	}

	/*
	 * Set the buffer to NULL as constraints may not be processed.
	 * If a buffer is required, then the routines in
	 * constraint_expr_eval_reason will realloc in REASON_BUF_SIZE
	 * chunks (as it gets called for each constraint processed).
	 * We just make sure these start from zero.
	 */
	*reason_buf = NULL;
	reason_buf_used = 0;
	reason_buf_len = 0;

	rc = context_struct_compute_av(scontext, tcontext, tclass,
					   requested, avd, reason, reason_buf, flags);
out:
	return rc;
}

int hidden sepol_compute_av(sepol_security_id_t ssid,
			    sepol_security_id_t tsid,
			    sepol_security_class_t tclass,
			    sepol_access_vector_t requested,
			    struct sepol_av_decision *avd)
{
	unsigned int reason = 0;
	return sepol_compute_av_reason(ssid, tsid, tclass, requested, avd,
				       &reason);
}

/*
 * Return a class ID associated with the class string specified by
 * class_name.
 */
int hidden sepol_string_to_security_class(const char *class_name,
			sepol_security_class_t *tclass)
{
	char *class = NULL;
	sepol_security_class_t id;

	for (id = 1;; id++) {
		class = policydb->p_class_val_to_name[id - 1];
		if (class == NULL) {
			ERR(NULL, "could not convert %s to class id", class_name);
			return STATUS_ERR;
		}
		if ((strcmp(class, class_name)) == 0) {
			*tclass = id;
			return STATUS_SUCCESS;
		}
	}
}

/*
 * Return access vector bit associated with the class ID and permission
 * string.
 */
int hidden sepol_string_to_av_perm(sepol_security_class_t tclass,
					const char *perm_name,
					sepol_access_vector_t *av)
{
	class_datum_t *tclass_datum;
	perm_datum_t *perm_datum;

	if (!tclass || tclass > policydb->p_classes.nprim) {
		ERR(NULL, "unrecognized class %d", tclass);
		return -EINVAL;
	}
	tclass_datum = policydb->class_val_to_struct[tclass - 1];

	/* Check for unique perms then the common ones (if any) */
	perm_datum = (perm_datum_t *)
			hashtab_search(tclass_datum->permissions.table,
			(hashtab_key_t)perm_name);
	if (perm_datum != NULL) {
		*av = 0x1 << (perm_datum->s.value - 1);
		return STATUS_SUCCESS;
	}

	if (tclass_datum->comdatum == NULL)
		goto out;

	perm_datum = (perm_datum_t *)
			hashtab_search(tclass_datum->comdatum->permissions.table,
			(hashtab_key_t)perm_name);

	if (perm_datum != NULL) {
		*av = 0x1 << (perm_datum->s.value - 1);
		return STATUS_SUCCESS;
	}
out:
	ERR(NULL, "could not convert %s to av bit", perm_name);
	return STATUS_ERR;
}

/*
 * Write the security context string representation of 
 * the context associated with `sid' into a dynamically
 * allocated string of the correct size.  Set `*scontext'
 * to point to this string and set `*scontext_len' to
 * the length of the string.
 */
int hidden sepol_sid_to_context(sepol_security_id_t sid,
				sepol_security_context_t * scontext,
				size_t * scontext_len)
{
	context_struct_t *context;
	int rc = 0;

	context = sepol_sidtab_search(sidtab, sid);
	if (!context) {
		ERR(NULL, "unrecognized SID %d", sid);
		rc = -EINVAL;
		goto out;
	}
	rc = context_to_string(NULL, policydb, context, scontext, scontext_len);
      out:
	return rc;

}

/*
 * Return a SID associated with the security context that
 * has the string representation specified by `scontext'.
 */
int hidden sepol_context_to_sid(const sepol_security_context_t scontext,
				size_t scontext_len, sepol_security_id_t * sid)
{

	context_struct_t *context = NULL;

	/* First, create the context */
	if (context_from_string(NULL, policydb, &context,
				scontext, scontext_len) < 0)
		goto err;

	/* Obtain the new sid */
	if (sid && (sepol_sidtab_context_to_sid(sidtab, context, sid) < 0))
		goto err;

	context_destroy(context);
	free(context);
	return STATUS_SUCCESS;

      err:
	if (context) {
		context_destroy(context);
		free(context);
	}
	ERR(NULL, "could not convert %s to sid", scontext);
	return STATUS_ERR;
}

static inline int compute_sid_handle_invalid_context(context_struct_t *
						     scontext,
						     context_struct_t *
						     tcontext,
						     sepol_security_class_t
						     tclass,
						     context_struct_t *
						     newcontext)
{
	if (selinux_enforcing) {
		return -EACCES;
	} else {
		sepol_security_context_t s, t, n;
		size_t slen, tlen, nlen;

		context_to_string(NULL, policydb, scontext, &s, &slen);
		context_to_string(NULL, policydb, tcontext, &t, &tlen);
		context_to_string(NULL, policydb, newcontext, &n, &nlen);
		ERR(NULL, "invalid context %s for "
		    "scontext=%s tcontext=%s tclass=%s",
		    n, s, t, policydb->p_class_val_to_name[tclass - 1]);
		free(s);
		free(t);
		free(n);
		return 0;
	}
}

static int sepol_compute_sid(sepol_security_id_t ssid,
			     sepol_security_id_t tsid,
			     sepol_security_class_t tclass,
			     uint32_t specified, sepol_security_id_t * out_sid)
{
	context_struct_t *scontext = 0, *tcontext = 0, newcontext;
	struct role_trans *roletr = 0;
	avtab_key_t avkey;
	avtab_datum_t *avdatum;
	avtab_ptr_t node;
	int rc = 0;

	scontext = sepol_sidtab_search(sidtab, ssid);
	if (!scontext) {
		ERR(NULL, "unrecognized SID %d", ssid);
		rc = -EINVAL;
		goto out;
	}
	tcontext = sepol_sidtab_search(sidtab, tsid);
	if (!tcontext) {
		ERR(NULL, "unrecognized SID %d", tsid);
		rc = -EINVAL;
		goto out;
	}

	context_init(&newcontext);

	/* Set the user identity. */
	switch (specified) {
	case AVTAB_TRANSITION:
	case AVTAB_CHANGE:
		/* Use the process user identity. */
		newcontext.user = scontext->user;
		break;
	case AVTAB_MEMBER:
		/* Use the related object owner. */
		newcontext.user = tcontext->user;
		break;
	}

	/* Set the role and type to default values. */
	switch (tclass) {
	case SECCLASS_PROCESS:
		/* Use the current role and type of process. */
		newcontext.role = scontext->role;
		newcontext.type = scontext->type;
		break;
	default:
		/* Use the well-defined object role. */
		newcontext.role = OBJECT_R_VAL;
		/* Use the type of the related object. */
		newcontext.type = tcontext->type;
	}

	/* Look for a type transition/member/change rule. */
	avkey.source_type = scontext->type;
	avkey.target_type = tcontext->type;
	avkey.target_class = tclass;
	avkey.specified = specified;
	avdatum = avtab_search(&policydb->te_avtab, &avkey);

	/* If no permanent rule, also check for enabled conditional rules */
	if (!avdatum) {
		node = avtab_search_node(&policydb->te_cond_avtab, &avkey);
		for (; node != NULL;
		     node = avtab_search_node_next(node, specified)) {
			if (node->key.specified & AVTAB_ENABLED) {
				avdatum = &node->datum;
				break;
			}
		}
	}

	if (avdatum) {
		/* Use the type from the type transition/member/change rule. */
		newcontext.type = avdatum->data;
	}

	/* Check for class-specific changes. */
	switch (tclass) {
	case SECCLASS_PROCESS:
		if (specified & AVTAB_TRANSITION) {
			/* Look for a role transition rule. */
			for (roletr = policydb->role_tr; roletr;
			     roletr = roletr->next) {
				if (roletr->role == scontext->role &&
				    roletr->type == tcontext->type) {
					/* Use the role transition rule. */
					newcontext.role = roletr->new_role;
					break;
				}
			}
		}
		break;
	default:
		break;
	}

	/* Set the MLS attributes.
	   This is done last because it may allocate memory. */
	rc = mls_compute_sid(policydb, scontext, tcontext, tclass, specified,
			     &newcontext);
	if (rc)
		goto out;

	/* Check the validity of the context. */
	if (!policydb_context_isvalid(policydb, &newcontext)) {
		rc = compute_sid_handle_invalid_context(scontext,
							tcontext,
							tclass, &newcontext);
		if (rc)
			goto out;
	}
	/* Obtain the sid for the context. */
	rc = sepol_sidtab_context_to_sid(sidtab, &newcontext, out_sid);
      out:
	context_destroy(&newcontext);
	return rc;
}

/*
 * Compute a SID to use for labeling a new object in the 
 * class `tclass' based on a SID pair.  
 */
int hidden sepol_transition_sid(sepol_security_id_t ssid,
				sepol_security_id_t tsid,
				sepol_security_class_t tclass,
				sepol_security_id_t * out_sid)
{
	return sepol_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
}

/*
 * Compute a SID to use when selecting a member of a 
 * polyinstantiated object of class `tclass' based on 
 * a SID pair.
 */
int hidden sepol_member_sid(sepol_security_id_t ssid,
			    sepol_security_id_t tsid,
			    sepol_security_class_t tclass,
			    sepol_security_id_t * out_sid)
{
	return sepol_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
}

/*
 * Compute a SID to use for relabeling an object in the 
 * class `tclass' based on a SID pair.  
 */
int hidden sepol_change_sid(sepol_security_id_t ssid,
			    sepol_security_id_t tsid,
			    sepol_security_class_t tclass,
			    sepol_security_id_t * out_sid)
{
	return sepol_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
}

/*
 * Verify that each permission that is defined under the
 * existing policy is still defined with the same value
 * in the new policy.
 */
static int validate_perm(hashtab_key_t key, hashtab_datum_t datum, void *p)
{
	hashtab_t h;
	perm_datum_t *perdatum, *perdatum2;

	h = (hashtab_t) p;
	perdatum = (perm_datum_t *) datum;

	perdatum2 = (perm_datum_t *) hashtab_search(h, key);
	if (!perdatum2) {
		ERR(NULL, "permission %s disappeared", key);
		return -1;
	}
	if (perdatum->s.value != perdatum2->s.value) {
		ERR(NULL, "the value of permissions %s changed", key);
		return -1;
	}
	return 0;
}

/*
 * Verify that each class that is defined under the
 * existing policy is still defined with the same 
 * attributes in the new policy.
 */
static int validate_class(hashtab_key_t key, hashtab_datum_t datum, void *p)
{
	policydb_t *newp;
	class_datum_t *cladatum, *cladatum2;

	newp = (policydb_t *) p;
	cladatum = (class_datum_t *) datum;

	cladatum2 =
	    (class_datum_t *) hashtab_search(newp->p_classes.table, key);
	if (!cladatum2) {
		ERR(NULL, "class %s disappeared", key);
		return -1;
	}
	if (cladatum->s.value != cladatum2->s.value) {
		ERR(NULL, "the value of class %s changed", key);
		return -1;
	}
	if ((cladatum->comdatum && !cladatum2->comdatum) ||
	    (!cladatum->comdatum && cladatum2->comdatum)) {
		ERR(NULL, "the inherits clause for the access "
		    "vector definition for class %s changed", key);
		return -1;
	}
	if (cladatum->comdatum) {
		if (hashtab_map
		    (cladatum->comdatum->permissions.table, validate_perm,
		     cladatum2->comdatum->permissions.table)) {
			ERR(NULL,
			    " in the access vector definition "
			    "for class %s\n", key);
			return -1;
		}
	}
	if (hashtab_map(cladatum->permissions.table, validate_perm,
			cladatum2->permissions.table)) {
		ERR(NULL, " in access vector definition for class %s", key);
		return -1;
	}
	return 0;
}

/* Clone the SID into the new SID table. */
static int clone_sid(sepol_security_id_t sid,
		     context_struct_t * context, void *arg)
{
	sidtab_t *s = arg;

	return sepol_sidtab_insert(s, sid, context);
}

static inline int convert_context_handle_invalid_context(context_struct_t *
							 context)
{
	if (selinux_enforcing) {
		return -EINVAL;
	} else {
		sepol_security_context_t s;
		size_t len;

		context_to_string(NULL, policydb, context, &s, &len);
		ERR(NULL, "context %s is invalid", s);
		free(s);
		return 0;
	}
}

typedef struct {
	policydb_t *oldp;
	policydb_t *newp;
} convert_context_args_t;

/*
 * Convert the values in the security context
 * structure `c' from the values specified
 * in the policy `p->oldp' to the values specified
 * in the policy `p->newp'.  Verify that the
 * context is valid under the new policy.
 */
static int convert_context(sepol_security_id_t key __attribute__ ((unused)),
			   context_struct_t * c, void *p)
{
	convert_context_args_t *args;
	context_struct_t oldc;
	role_datum_t *role;
	type_datum_t *typdatum;
	user_datum_t *usrdatum;
	sepol_security_context_t s;
	size_t len;
	int rc = -EINVAL;

	args = (convert_context_args_t *) p;

	if (context_cpy(&oldc, c))
		return -ENOMEM;

	/* Convert the user. */
	usrdatum = (user_datum_t *) hashtab_search(args->newp->p_users.table,
						   args->oldp->
						   p_user_val_to_name[c->user -
								      1]);

	if (!usrdatum) {
		goto bad;
	}
	c->user = usrdatum->s.value;

	/* Convert the role. */
	role = (role_datum_t *) hashtab_search(args->newp->p_roles.table,
					       args->oldp->
					       p_role_val_to_name[c->role - 1]);
	if (!role) {
		goto bad;
	}
	c->role = role->s.value;

	/* Convert the type. */
	typdatum = (type_datum_t *)
	    hashtab_search(args->newp->p_types.table,
			   args->oldp->p_type_val_to_name[c->type - 1]);
	if (!typdatum) {
		goto bad;
	}
	c->type = typdatum->s.value;

	rc = mls_convert_context(args->oldp, args->newp, c);
	if (rc)
		goto bad;

	/* Check the validity of the new context. */
	if (!policydb_context_isvalid(args->newp, c)) {
		rc = convert_context_handle_invalid_context(&oldc);
		if (rc)
			goto bad;
	}

	context_destroy(&oldc);
	return 0;

      bad:
	context_to_string(NULL, policydb, &oldc, &s, &len);
	context_destroy(&oldc);
	ERR(NULL, "invalidating context %s", s);
	free(s);
	return rc;
}

/* Reading from a policy "file". */
int hidden next_entry(void *buf, struct policy_file *fp, size_t bytes)
{
	size_t nread;

	switch (fp->type) {
	case PF_USE_STDIO:
		nread = fread(buf, bytes, 1, fp->fp);

		if (nread != 1)
			return -1;
		break;
	case PF_USE_MEMORY:
		if (bytes > fp->len)
			return -1;
		memcpy(buf, fp->data, bytes);
		fp->data += bytes;
		fp->len -= bytes;
		break;
	default:
		return -1;
	}
	return 0;
}

size_t hidden put_entry(const void *ptr, size_t size, size_t n,
			struct policy_file *fp)
{
	size_t bytes = size * n;

	switch (fp->type) {
	case PF_USE_STDIO:
		return fwrite(ptr, size, n, fp->fp);
	case PF_USE_MEMORY:
		if (bytes > fp->len) {
			errno = ENOSPC;
			return 0;
		}

		memcpy(fp->data, ptr, bytes);
		fp->data += bytes;
		fp->len -= bytes;
		return n;
	case PF_LEN:
		fp->len += bytes;
		return n;
	default:
		return 0;
	}
	return 0;
}

/*
 * Read a new set of configuration data from 
 * a policy database binary representation file.
 *
 * Verify that each class that is defined under the
 * existing policy is still defined with the same 
 * attributes in the new policy.  
 *
 * Convert the context structures in the SID table to the
 * new representation and verify that all entries
 * in the SID table are valid under the new policy. 
 *
 * Change the active policy database to use the new 
 * configuration data.  
 *
 * Reset the access vector cache.
 */
int hidden sepol_load_policy(void *data, size_t len)
{
	policydb_t oldpolicydb, newpolicydb;
	sidtab_t oldsidtab, newsidtab;
	convert_context_args_t args;
	int rc = 0;
	struct policy_file file, *fp;

	policy_file_init(&file);
	file.type = PF_USE_MEMORY;
	file.data = data;
	file.len = len;
	fp = &file;

	if (policydb_init(&newpolicydb))
		return -ENOMEM;

	if (policydb_read(&newpolicydb, fp, 1)) {
		policydb_destroy(&mypolicydb);
		return -EINVAL;
	}

	sepol_sidtab_init(&newsidtab);

	/* Verify that the existing classes did not change. */
	if (hashtab_map
	    (policydb->p_classes.table, validate_class, &newpolicydb)) {
		ERR(NULL, "the definition of an existing class changed");
		rc = -EINVAL;
		goto err;
	}

	/* Clone the SID table. */
	sepol_sidtab_shutdown(sidtab);
	if (sepol_sidtab_map(sidtab, clone_sid, &newsidtab)) {
		rc = -ENOMEM;
		goto err;
	}

	/* Convert the internal representations of contexts 
	   in the new SID table and remove invalid SIDs. */
	args.oldp = policydb;
	args.newp = &newpolicydb;
	sepol_sidtab_map_remove_on_error(&newsidtab, convert_context, &args);

	/* Save the old policydb and SID table to free later. */
	memcpy(&oldpolicydb, policydb, sizeof *policydb);
	sepol_sidtab_set(&oldsidtab, sidtab);

	/* Install the new policydb and SID table. */
	memcpy(policydb, &newpolicydb, sizeof *policydb);
	sepol_sidtab_set(sidtab, &newsidtab);

	/* Free the old policydb and SID table. */
	policydb_destroy(&oldpolicydb);
	sepol_sidtab_destroy(&oldsidtab);

	return 0;

      err:
	sepol_sidtab_destroy(&newsidtab);
	policydb_destroy(&newpolicydb);
	return rc;

}

/*
 * Return the SIDs to use for an unlabeled file system
 * that is being mounted from the device with the
 * the kdevname `name'.  The `fs_sid' SID is returned for 
 * the file system and the `file_sid' SID is returned
 * for all files within that file system.
 */
int hidden sepol_fs_sid(char *name,
			sepol_security_id_t * fs_sid,
			sepol_security_id_t * file_sid)
{
	int rc = 0;
	ocontext_t *c;

	c = policydb->ocontexts[OCON_FS];
	while (c) {
		if (strcmp(c->u.name, name) == 0)
			break;
		c = c->next;
	}

	if (c) {
		if (!c->sid[0] || !c->sid[1]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[1],
							 &c->sid[1]);
			if (rc)
				goto out;
		}
		*fs_sid = c->sid[0];
		*file_sid = c->sid[1];
	} else {
		*fs_sid = SECINITSID_FS;
		*file_sid = SECINITSID_FILE;
	}

      out:
	return rc;
}

/*
 * Return the SID of the port specified by
 * `domain', `type', `protocol', and `port'.
 */
int hidden sepol_port_sid(uint16_t domain __attribute__ ((unused)),
			  uint16_t type __attribute__ ((unused)),
			  uint8_t protocol,
			  uint16_t port, sepol_security_id_t * out_sid)
{
	ocontext_t *c;
	int rc = 0;

	c = policydb->ocontexts[OCON_PORT];
	while (c) {
		if (c->u.port.protocol == protocol &&
		    c->u.port.low_port <= port && c->u.port.high_port >= port)
			break;
		c = c->next;
	}

	if (c) {
		if (!c->sid[0]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
		}
		*out_sid = c->sid[0];
	} else {
		*out_sid = SECINITSID_PORT;
	}

      out:
	return rc;
}

/*
 * Return the SIDs to use for a network interface
 * with the name `name'.  The `if_sid' SID is returned for 
 * the interface and the `msg_sid' SID is returned as 
 * the default SID for messages received on the
 * interface.
 */
int hidden sepol_netif_sid(char *name,
			   sepol_security_id_t * if_sid,
			   sepol_security_id_t * msg_sid)
{
	int rc = 0;
	ocontext_t *c;

	c = policydb->ocontexts[OCON_NETIF];
	while (c) {
		if (strcmp(name, c->u.name) == 0)
			break;
		c = c->next;
	}

	if (c) {
		if (!c->sid[0] || !c->sid[1]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[1],
							 &c->sid[1]);
			if (rc)
				goto out;
		}
		*if_sid = c->sid[0];
		*msg_sid = c->sid[1];
	} else {
		*if_sid = SECINITSID_NETIF;
		*msg_sid = SECINITSID_NETMSG;
	}

      out:
	return rc;
}

static int match_ipv6_addrmask(uint32_t * input, uint32_t * addr,
			       uint32_t * mask)
{
	int i, fail = 0;

	for (i = 0; i < 4; i++)
		if (addr[i] != (input[i] & mask[i])) {
			fail = 1;
			break;
		}

	return !fail;
}

/*
 * Return the SID of the node specified by the address
 * `addrp' where `addrlen' is the length of the address
 * in bytes and `domain' is the communications domain or
 * address family in which the address should be interpreted.
 */
int hidden sepol_node_sid(uint16_t domain,
			  void *addrp,
			  size_t addrlen, sepol_security_id_t * out_sid)
{
	int rc = 0;
	ocontext_t *c;

	switch (domain) {
	case AF_INET:{
			uint32_t addr;

			if (addrlen != sizeof(uint32_t)) {
				rc = -EINVAL;
				goto out;
			}

			addr = *((uint32_t *) addrp);

			c = policydb->ocontexts[OCON_NODE];
			while (c) {
				if (c->u.node.addr == (addr & c->u.node.mask))
					break;
				c = c->next;
			}
			break;
		}

	case AF_INET6:
		if (addrlen != sizeof(uint64_t) * 2) {
			rc = -EINVAL;
			goto out;
		}

		c = policydb->ocontexts[OCON_NODE6];
		while (c) {
			if (match_ipv6_addrmask(addrp, c->u.node6.addr,
						c->u.node6.mask))
				break;
			c = c->next;
		}
		break;

	default:
		*out_sid = SECINITSID_NODE;
		goto out;
	}

	if (c) {
		if (!c->sid[0]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
		}
		*out_sid = c->sid[0];
	} else {
		*out_sid = SECINITSID_NODE;
	}

      out:
	return rc;
}

/*
 * Generate the set of SIDs for legal security contexts
 * for a given user that can be reached by `fromsid'.
 * Set `*sids' to point to a dynamically allocated 
 * array containing the set of SIDs.  Set `*nel' to the
 * number of elements in the array.
 */
#define SIDS_NEL 25

int hidden sepol_get_user_sids(sepol_security_id_t fromsid,
			       char *username,
			       sepol_security_id_t ** sids, uint32_t * nel)
{
	context_struct_t *fromcon, usercon;
	sepol_security_id_t *mysids, *mysids2, sid;
	uint32_t mynel = 0, maxnel = SIDS_NEL;
	user_datum_t *user;
	role_datum_t *role;
	struct sepol_av_decision avd;
	int rc = 0;
	unsigned int i, j, reason;
	ebitmap_node_t *rnode, *tnode;

	fromcon = sepol_sidtab_search(sidtab, fromsid);
	if (!fromcon) {
		rc = -EINVAL;
		goto out;
	}

	user = (user_datum_t *) hashtab_search(policydb->p_users.table,
					       username);
	if (!user) {
		rc = -EINVAL;
		goto out;
	}
	usercon.user = user->s.value;

	mysids = malloc(maxnel * sizeof(sepol_security_id_t));
	if (!mysids) {
		rc = -ENOMEM;
		goto out;
	}
	memset(mysids, 0, maxnel * sizeof(sepol_security_id_t));

	ebitmap_for_each_bit(&user->roles.roles, rnode, i) {
		if (!ebitmap_node_get_bit(rnode, i))
			continue;
		role = policydb->role_val_to_struct[i];
		usercon.role = i + 1;
		ebitmap_for_each_bit(&role->types.types, tnode, j) {
			if (!ebitmap_node_get_bit(tnode, j))
				continue;
			usercon.type = j + 1;
			if (usercon.type == fromcon->type)
				continue;

			if (mls_setup_user_range
			    (fromcon, user, &usercon, policydb->mls))
				continue;

			rc = context_struct_compute_av(fromcon, &usercon,
						       SECCLASS_PROCESS,
						       PROCESS__TRANSITION,
						       &avd, &reason, NULL, 0);
			if (rc || !(avd.allowed & PROCESS__TRANSITION))
				continue;
			rc = sepol_sidtab_context_to_sid(sidtab, &usercon,
							 &sid);
			if (rc) {
				free(mysids);
				goto out;
			}
			if (mynel < maxnel) {
				mysids[mynel++] = sid;
			} else {
				maxnel += SIDS_NEL;
				mysids2 =
				    malloc(maxnel *
					   sizeof(sepol_security_id_t));

				if (!mysids2) {
					rc = -ENOMEM;
					free(mysids);
					goto out;
				}
				memset(mysids2, 0,
				       maxnel * sizeof(sepol_security_id_t));
				memcpy(mysids2, mysids,
				       mynel * sizeof(sepol_security_id_t));
				free(mysids);
				mysids = mysids2;
				mysids[mynel++] = sid;
			}
		}
	}

	*sids = mysids;
	*nel = mynel;

      out:
	return rc;
}

/*
 * Return the SID to use for a file in a filesystem
 * that cannot support a persistent label mapping or use another
 * fixed labeling behavior like transition SIDs or task SIDs.
 */
int hidden sepol_genfs_sid(const char *fstype,
			   char *path,
			   sepol_security_class_t sclass,
			   sepol_security_id_t * sid)
{
	size_t len;
	genfs_t *genfs;
	ocontext_t *c;
	int rc = 0, cmp = 0;

	for (genfs = policydb->genfs; genfs; genfs = genfs->next) {
		cmp = strcmp(fstype, genfs->fstype);
		if (cmp <= 0)
			break;
	}

	if (!genfs || cmp) {
		*sid = SECINITSID_UNLABELED;
		rc = -ENOENT;
		goto out;
	}

	for (c = genfs->head; c; c = c->next) {
		len = strlen(c->u.name);
		if ((!c->v.sclass || sclass == c->v.sclass) &&
		    (strncmp(c->u.name, path, len) == 0))
			break;
	}

	if (!c) {
		*sid = SECINITSID_UNLABELED;
		rc = -ENOENT;
		goto out;
	}

	if (!c->sid[0]) {
		rc = sepol_sidtab_context_to_sid(sidtab,
						 &c->context[0], &c->sid[0]);
		if (rc)
			goto out;
	}

	*sid = c->sid[0];
      out:
	return rc;
}

int hidden sepol_fs_use(const char *fstype,
			unsigned int *behavior, sepol_security_id_t * sid)
{
	int rc = 0;
	ocontext_t *c;

	c = policydb->ocontexts[OCON_FSUSE];
	while (c) {
		if (strcmp(fstype, c->u.name) == 0)
			break;
		c = c->next;
	}

	if (c) {
		*behavior = c->v.behavior;
		if (!c->sid[0]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
		}
		*sid = c->sid[0];
	} else {
		rc = sepol_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
		if (rc) {
			*behavior = SECURITY_FS_USE_NONE;
			rc = 0;
		} else {
			*behavior = SECURITY_FS_USE_GENFS;
		}
	}

      out:
	return rc;
}

/* FLASK */
