18c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/*
28c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
38c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */
48c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
58c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/*
68c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
78c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *
88c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *	Support for enhanced MLS infrastructure.
98c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *
108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Updated: David Caplan, <dac@tresys.com>
118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *
128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * 	Added conditional policy language extensions
138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *
148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Updated: Joshua Brindle <jbrindle@tresys.com>
158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *	    Karl MacMillan <kmacmillan@mentalrootkit.com>
168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *          Jason Tang     <jtang@tresys.com>
178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *
188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *	Added support for binary policy modules
198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *
208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Copyright (C) 2003 - 2008 Tresys Technology, LLC
228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * Copyright (C) 2007 Red Hat Inc.
238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *	This program is free software; you can redistribute it and/or modify
248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *  	it under the terms of the GNU General Public License as published by
258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android *	the Free Software Foundation, version 2.
268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */
278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* FLASK */
298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sys/types.h>
318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <assert.h>
328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <stdarg.h>
338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <stdint.h>
348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <stdio.h>
358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <stdlib.h>
368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <string.h>
378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sys/socket.h>
388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <netinet/in.h>
398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <arpa/inet.h>
408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <stdlib.h>
418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/expand.h>
438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/policydb.h>
448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/services.h>
458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/conditional.h>
468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/flask.h>
478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/hierarchy.h>
488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include <sepol/policydb/polcaps.h>
498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include "queue.h"
508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include "checkpolicy.h"
518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include "module_compiler.h"
528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#include "policy_define.h"
538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidpolicydb_t *policydbp;
558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidqueue_t id_queue = 0;
568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidunsigned int pass;
578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidchar *curfile = 0;
588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint mlspol = 0;
598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern unsigned long policydb_lineno;
618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern unsigned long source_lineno;
628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern unsigned int policydb_errors;
638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern int yywarn(char *msg);
658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidextern int yyerror(char *msg);
668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android#define ERRORMSG_LEN 255
688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic char errormsg[ERRORMSG_LEN + 1] = {0};
698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int id_has_dot(char *id);
718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int parse_security_context(context_struct_t *c);
728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* initialize all of the state variables for the scanner/parser */
748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidvoid init_parser(int pass_number)
758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	policydb_lineno = 1;
778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	source_lineno = 1;
788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	policydb_errors = 0;
798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	pass = pass_number;
808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidvoid yyerror2(char *fmt, ...)
838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	va_list ap;
858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	va_start(ap, fmt);
868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	yyerror(errormsg);
888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	va_end(ap);
898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint insert_separator(int push)
928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int error;
948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (push)
968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		error = queue_push(id_queue, 0);
978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		error = queue_insert(id_queue, 0);
998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (error) {
1018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("queue overflow");
1028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
1038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
1048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
1058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
1068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint insert_id(char *id, int push)
1088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
1098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *newid = 0;
1108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int error;
1118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newid = (char *)malloc(strlen(id) + 1);
1138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newid) {
1148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
1158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
1168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
1178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	strcpy(newid, id);
1188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (push)
1198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		error = queue_push(id_queue, (queue_element_t) newid);
1208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
1218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		error = queue_insert(id_queue, (queue_element_t) newid);
1228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (error) {
1248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("queue overflow");
1258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newid);
1268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
1278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
1288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
1298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
1308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* If the identifier has a dot within it and that its first character
1328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android   is not a dot then return 1, else return 0. */
1338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int id_has_dot(char *id)
1348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
1358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (strchr(id, '.') >= id + 1) {
1368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 1;
1378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
1388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
1398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
1408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_class(void)
1428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
1438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id = 0;
1448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_datum_t *datum = 0;
1458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int ret;
1468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	uint32_t value;
1478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
1498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
1508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
1518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
1528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
1538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
1558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
1568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no class name for class definition?");
1578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
1588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
1598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum = (class_datum_t *) malloc(sizeof(class_datum_t));
1608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!datum) {
1618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
1628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
1638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
1648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(datum, 0, sizeof(class_datum_t));
1658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
1668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	switch (ret) {
1678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -3:{
1688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
1698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
1708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
1718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -2:{
1728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate declaration of class %s", id);
1738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
1748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
1758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -1:{
1768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("could not declare class here");
1778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
1788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
1798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case 0:
1808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case 1:{
1818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
1828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
1838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	default:{
1848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			assert(0);	/* should never get here */
1858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
1868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
1878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum->s.value = value;
1888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
1898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
1918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id)
1928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
1938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (datum)
1948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(datum);
1958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
1968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
1978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_permissive(void)
1998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
2008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *type = NULL;
2018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct type_datum *t;
2028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int rc = 0;
2038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type = queue_remove(id_queue);
2058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!type) {
2078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("forgot to include type in permissive definition?");
2088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
2098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
2108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1)
2138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
2148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, type)) {
2168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", type);
2178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
2188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
2198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	t = hashtab_search(policydbp->p_types.table, type);
2228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!t) {
2238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type is not defined: %s", type);
2248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
2258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
2268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (t->flavor == TYPE_ATTRIB) {
2298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("attributes may not be permissive: %s\n", type);
2308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
2318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
2328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	t->flags |= TYPE_FLAGS_PERMISSIVE;
2358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidout:
2378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(type);
2388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return rc;
2398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
2408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_polcap(void)
2428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
2438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id = 0;
2448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int capnum;
2458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
2478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
2488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
2498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
2508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
2538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
2548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no capability name for policycap definition?");
2558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
2568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Check for valid cap name -> number mapping */
2598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	capnum = sepol_polcap_getnum(id);
2608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (capnum < 0) {
2618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("invalid policy capability name %s", id);
2628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
2638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Store it */
2668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
2678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
2688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
2698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
2728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
2738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
2758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
2768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
2778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
2788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_initial_sid(void)
2808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
2818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id = 0;
2828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc = 0, *c, *head;
2838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
2858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
2868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
2878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
2888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
2918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
2928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no sid name for SID definition?");
2938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
2948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
2958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
2968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
2978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
2988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
2998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
3008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
3018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.name = id;
3028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	context_init(&newc->context[0]);
3038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_ISID];
3048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
3058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (c = head; c; c = c->next) {
3068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!strcmp(newc->u.name, c->u.name)) {
3078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate initial SID %s", id);
3088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
3098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
3108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
3118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
3128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (head) {
3138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newc->sid[0] = head->sid[0] + 1;
3148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else {
3158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newc->sid[0] = 1;
3168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
3178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->next = head;
3188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	policydbp->ocontexts[OCON_ISID] = newc;
3198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
3208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
3218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
3228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
3238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id)
3248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
3258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (newc)
3268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
3278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
3288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
3298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
330cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalleystatic int read_classes(ebitmap_t *e_classes)
331cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley{
332cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	char *id;
333cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	class_datum_t *cladatum;
334cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley
335cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	while ((id = queue_remove(id_queue))) {
336cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		if (!is_id_in_scope(SYM_CLASSES, id)) {
337cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley			yyerror2("class %s is not within scope", id);
338cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley			return -1;
339cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		}
340cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		cladatum = hashtab_search(policydbp->p_classes.table, id);
341cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		if (!cladatum) {
342cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley			yyerror2("unknown class %s", id);
343cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley			return -1;
344cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		}
345cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) {
346cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley			yyerror("Out of memory");
347cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley			return -1;
348cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		}
349cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		free(id);
350cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	}
351cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	return 0;
352cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley}
353cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley
354ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalleyint define_default_user(int which)
355ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley{
356ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	char *id;
357ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	class_datum_t *cladatum;
358ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
359ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	if (pass == 1) {
360ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		while ((id = queue_remove(id_queue)))
361ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			free(id);
362ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		return 0;
363ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	}
364ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
365ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	while ((id = queue_remove(id_queue))) {
366ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (!is_id_in_scope(SYM_CLASSES, id)) {
367ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("class %s is not within scope", id);
368ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
369ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
370ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		cladatum = hashtab_search(policydbp->p_classes.table, id);
371ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (!cladatum) {
372ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("unknown class %s", id);
373ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
374ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
375ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (cladatum->default_user && cladatum->default_user != which) {
376ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("conflicting default user information for class %s", id);
377ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
378ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
379ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		cladatum->default_user = which;
380ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		free(id);
381ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	}
382ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
383ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	return 0;
384ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley}
385ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
386ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalleyint define_default_role(int which)
387ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley{
388ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	char *id;
389ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	class_datum_t *cladatum;
390ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
391ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	if (pass == 1) {
392ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		while ((id = queue_remove(id_queue)))
393ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			free(id);
394ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		return 0;
395ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	}
396ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
397ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	while ((id = queue_remove(id_queue))) {
398ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (!is_id_in_scope(SYM_CLASSES, id)) {
399ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("class %s is not within scope", id);
400ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
401ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
402ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		cladatum = hashtab_search(policydbp->p_classes.table, id);
403ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (!cladatum) {
404ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("unknown class %s", id);
405ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
406ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
407ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (cladatum->default_role && cladatum->default_role != which) {
408ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("conflicting default role information for class %s", id);
409ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
410ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
411ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		cladatum->default_role = which;
412ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		free(id);
413ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	}
414ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
415ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	return 0;
416ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley}
417ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
418ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalleyint define_default_range(int which)
419ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley{
420ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	char *id;
421ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	class_datum_t *cladatum;
422ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
423ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	if (pass == 1) {
424ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		while ((id = queue_remove(id_queue)))
425ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			free(id);
426ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		return 0;
427ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	}
428ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
429ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	while ((id = queue_remove(id_queue))) {
430ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (!is_id_in_scope(SYM_CLASSES, id)) {
431ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("class %s is not within scope", id);
432ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
433ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
434ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		cladatum = hashtab_search(policydbp->p_classes.table, id);
435ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (!cladatum) {
436ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("unknown class %s", id);
437ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
438ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
439ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (cladatum->default_range && cladatum->default_range != which) {
440ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror2("conflicting default range information for class %s", id);
441ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
442ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
443ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		cladatum->default_range = which;
444ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		free(id);
445ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	}
446ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
447ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley	return 0;
448ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley}
449ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley
4508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_common_perms(void)
4518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
4528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id = 0, *perm = 0;
4538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	common_datum_t *comdatum = 0;
4548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	perm_datum_t *perdatum = 0;
4558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int ret;
4568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
4578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
4588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
4598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
4608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
4618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
4628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
4638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
4648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
4658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no common name for common perm definition?");
4668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
4678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
4688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	comdatum = hashtab_search(policydbp->p_commons.table, id);
4698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (comdatum) {
4708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("duplicate declaration for common %s\n", id);
4718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
4728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
4738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
4748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!comdatum) {
4758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
4768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
4778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
4788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(comdatum, 0, sizeof(common_datum_t));
4798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ret = hashtab_insert(policydbp->p_commons.table,
4808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			     (hashtab_key_t) id, (hashtab_datum_t) comdatum);
4818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
4828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (ret == SEPOL_EEXIST) {
4838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("duplicate common definition");
4848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
4858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
4868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (ret == SEPOL_ENOMEM) {
4878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("hash table overflow");
4888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
4898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
4908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	comdatum->s.value = policydbp->p_commons.nprim + 1;
4918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
4928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
4938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
4948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
4958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	policydbp->p_commons.nprim++;
4968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((perm = queue_remove(id_queue))) {
4978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
4988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!perdatum) {
4998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
5008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad_perm;
5018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
5028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		memset(perdatum, 0, sizeof(perm_datum_t));
5038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		perdatum->s.value = comdatum->permissions.nprim + 1;
5048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
5068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror
5078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    ("too many permissions to fit in an access vector");
5088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad_perm;
5098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
5108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ret = hashtab_insert(comdatum->permissions.table,
5118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				     (hashtab_key_t) perm,
5128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				     (hashtab_datum_t) perdatum);
5138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ret == SEPOL_EEXIST) {
5158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate permission %s in common %s", perm,
5168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 id);
5178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad_perm;
5188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
5198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ret == SEPOL_ENOMEM) {
5208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("hash table overflow");
5218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad_perm;
5228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
5238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		comdatum->permissions.nprim++;
5248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
5258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
5278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
5298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id)
5308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
5318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (comdatum)
5328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(comdatum);
5338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
5348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad_perm:
5368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (perm)
5378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(perm);
5388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (perdatum)
5398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(perdatum);
5408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
5418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
5428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_av_perms(int inherits)
5448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
5458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
5468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_datum_t *cladatum;
5478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	common_datum_t *comdatum;
5488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	perm_datum_t *perdatum = 0, *perdatum2 = 0;
5498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int ret;
5508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
5528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
5538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
5548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
5558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
5568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
5588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
5598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no tclass name for av perm definition?");
5608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
5618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
5628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
5638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						    (hashtab_key_t) id);
5648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!cladatum) {
5658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("class %s is not defined", id);
5668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
5678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
5688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
5698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (cladatum->comdatum || cladatum->permissions.nprim) {
5718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("duplicate access vector definition");
5728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
5738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
5748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
5758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
5768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
5778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
5788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (inherits) {
5798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_remove(id_queue);
5808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!id) {
5818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror
5828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    ("no inherits name for access vector definition?");
5838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
5848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
5858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		comdatum =
5868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (common_datum_t *) hashtab_search(policydbp->p_commons.
5878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						      table,
5888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						      (hashtab_key_t) id);
5898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!comdatum) {
5918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("common %s is not defined", id);
5928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
5938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
5948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum->comkey = id;
5958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum->comdatum = comdatum;
5968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
5978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/*
5988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 * Class-specific permissions start with values
5998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 * after the last common permission.
6008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 */
6018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum->permissions.nprim += comdatum->permissions.nprim;
6028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
6038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
6048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
6058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!perdatum) {
6068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
6078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
6088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
6098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		memset(perdatum, 0, sizeof(perm_datum_t));
6108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		perdatum->s.value = ++cladatum->permissions.nprim;
6118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
6138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror
6148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    ("too many permissions to fit in an access vector");
6158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
6168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
6178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (inherits) {
6188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/*
6198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 * Class-specific permissions and
6208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 * common permissions exist in the same
6218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 * name space.
6228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 */
6238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			perdatum2 =
6248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    (perm_datum_t *) hashtab_search(cladatum->comdatum->
6258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							    permissions.table,
6268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							    (hashtab_key_t) id);
6278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (perdatum2) {
6288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror2("permission %s conflicts with an "
6298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					 "inherited permission", id);
6308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto bad;
6318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
6328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
6338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ret = hashtab_insert(cladatum->permissions.table,
6348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				     (hashtab_key_t) id,
6358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				     (hashtab_datum_t) perdatum);
6368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ret == SEPOL_EEXIST) {
6388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate permission %s", id);
6398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
6408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
6418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ret == SEPOL_ENOMEM) {
6428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("hash table overflow");
6438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
6448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
6458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
6468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
6478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
6488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
6498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
6508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
6528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
6548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id)
6558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
6568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (perdatum)
6578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(perdatum);
6588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
6598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
6608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_sens(void)
6628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
6638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
6648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	mls_level_t *level = 0;
6658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level_datum_t *datum = 0, *aliasdatum = 0;
6668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int ret;
6678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	uint32_t value;		/* dummy variable -- its value is never used */
6688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!mlspol) {
6708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("sensitivity definition in non-MLS configuration");
6718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
6728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
6738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
6758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
6768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
6778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
6788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
6798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
6818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
6828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no sensitivity name for sensitivity definition?");
6838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
6848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
6858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id_has_dot(id)) {
6868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("sensitivity identifiers may not contain periods");
6878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
6888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
6898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level = (mls_level_t *) malloc(sizeof(mls_level_t));
6908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!level) {
6918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
6928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
6938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
6948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	mls_level_init(level);
6958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level->sens = 0;	/* actual value set in define_dominance */
6968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&level->cat);	/* actual value set in define_level */
6978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
6988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum = (level_datum_t *) malloc(sizeof(level_datum_t));
6998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!datum) {
7008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
7018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
7028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
7038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level_datum_init(datum);
7048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum->isalias = FALSE;
7058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum->level = level;
7068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
7078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
7088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	switch (ret) {
7098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -3:{
7108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
7118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
7128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
7138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -2:{
7148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("duplicate declaration of sensitivity level");
7158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
7168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
7178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -1:{
7188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("could not declare sensitivity level here");
7198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
7208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
7218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case 0:
7228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case 1:{
7238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
7248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
7258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	default:{
7268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			assert(0);	/* should never get here */
7278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
7288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
7298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
7308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
7318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (id_has_dot(id)) {
7328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("sensitivity aliases may not contain periods");
7338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad_alias;
7348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
7358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
7368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!aliasdatum) {
7378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
7388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad_alias;
7398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
7408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		level_datum_init(aliasdatum);
7418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		aliasdatum->isalias = TRUE;
7428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		aliasdatum->level = level;
7438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
7448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
7458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		switch (ret) {
7468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -3:{
7478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("Out of memory!");
7488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto bad_alias;
7498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
7508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -2:{
7518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror
7528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    ("duplicate declaration of sensitivity alias");
7538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto bad_alias;
7548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
7558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -1:{
7568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror
7578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    ("could not declare sensitivity alias here");
7588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto bad_alias;
7598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
7608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 0:
7618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 1:{
7628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				break;
7638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
7648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		default:{
7658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				assert(0);	/* should never get here */
7668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
7678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
7688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
7698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
7708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
7718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
7728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
7738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id)
7748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
7758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (level)
7768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(level);
7778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (datum) {
7788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		level_datum_destroy(datum);
7798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(datum);
7808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
7818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
7828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
7838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad_alias:
7848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id)
7858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
7868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (aliasdatum) {
7878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		level_datum_destroy(aliasdatum);
7888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(aliasdatum);
7898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
7908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
7918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
7928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
7938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_dominance(void)
7948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
7958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level_datum_t *datum;
7968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int order;
7978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
7988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
7998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!mlspol) {
8008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("dominance definition in non-MLS configuration");
8018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
8028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
8058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
8068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
8078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
8088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	order = 0;
8118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = (char *)queue_remove(id_queue))) {
8128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		datum =
8138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (level_datum_t *) hashtab_search(policydbp->p_levels.table,
8148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						     (hashtab_key_t) id);
8158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!datum) {
8168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown sensitivity %s used in dominance "
8178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 "definition", id);
8188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
8198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
8208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
8218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (datum->level->sens != 0) {
8228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("sensitivity %s occurs multiply in dominance "
8238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 "definition", id);
8248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
8258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
8268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
8278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		datum->level->sens = ++order;
8288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* no need to keep sensitivity name */
8308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
8318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (order != policydbp->p_levels.nprim) {
8348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror
8358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    ("all sensitivities must be specified in dominance definition");
8368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
8378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
8398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
8408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_category(void)
8428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
8438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
8448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cat_datum_t *datum = 0, *aliasdatum = 0;
8458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int ret;
8468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	uint32_t value;
8478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!mlspol) {
8498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("category definition in non-MLS configuration");
8508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
8518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
8548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
8558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
8568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
8578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
8608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
8618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no category name for category definition?");
8628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
8638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id_has_dot(id)) {
8658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("category identifiers may not contain periods");
8668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
8678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
8698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!datum) {
8708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
8718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
8728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cat_datum_init(datum);
8748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum->isalias = FALSE;
8758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
8768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
8778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	switch (ret) {
8788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -3:{
8798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
8808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
8818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
8828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -2:{
8838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("duplicate declaration of category");
8848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
8858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
8868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -1:{
8878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("could not declare category here");
8888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
8898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
8908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case 0:
8918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case 1:{
8928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
8938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
8948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	default:{
8958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			assert(0);	/* should never get here */
8968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
8978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
8988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum->s.value = value;
8998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
9018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (id_has_dot(id)) {
9028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("category aliases may not contain periods");
9038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad_alias;
9048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
9058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
9068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!aliasdatum) {
9078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
9088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad_alias;
9098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
9108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cat_datum_init(aliasdatum);
9118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		aliasdatum->isalias = TRUE;
9128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		aliasdatum->s.value = datum->s.value;
9138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ret =
9158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    declare_symbol(SYM_CATS, id, aliasdatum, NULL,
9168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				   &datum->s.value);
9178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		switch (ret) {
9188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -3:{
9198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("Out of memory!");
9208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto bad_alias;
9218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
9228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -2:{
9238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror
9248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    ("duplicate declaration of category aliases");
9258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto bad_alias;
9268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
9278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -1:{
9288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror
9298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    ("could not declare category aliases here");
9308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto bad_alias;
9318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
9328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 0:
9338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 1:{
9348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				break;
9358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
9368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		default:{
9378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				assert(0);	/* should never get here */
9388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
9398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
9408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
9418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
9438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
9458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id)
9468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
9478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (datum) {
9488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cat_datum_destroy(datum);
9498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(datum);
9508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
9518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
9528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad_alias:
9548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id)
9558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
9568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (aliasdatum) {
9578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cat_datum_destroy(aliasdatum);
9588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(aliasdatum);
9598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
9608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
9618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
9628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
9648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
9658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level_datum_t *levdatum = (level_datum_t *) datum;
9668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	mls_level_t *level = (mls_level_t *) arg, *newlevel;
9678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (levdatum->level == level) {
9698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		levdatum->defined = 1;
9708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!levdatum->isalias)
9718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return 0;
9728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
9738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!newlevel)
9748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
9758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (mls_level_cpy(newlevel, level)) {
9768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(newlevel);
9778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
9788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
9798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		levdatum->level = newlevel;
9808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
9818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
9828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
9838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_level(void)
9858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
9868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
9878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level_datum_t *levdatum;
9888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!mlspol) {
9908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("level definition in non-MLS configuration");
9918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
9928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
9938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
9948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
9958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
9968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
9978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
9988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
9998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
10018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
10028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no level name for level definition?");
10038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
10048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
10058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
10068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						    (hashtab_key_t) id);
10078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!levdatum) {
10088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown sensitivity %s used in level definition", id);
10098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
10108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
10118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
10128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (ebitmap_length(&levdatum->level->cat)) {
10138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("sensitivity %s used in multiple level definitions",
10148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 id);
10158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
10168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
10178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
10188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
10198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	levdatum->defined = 1;
10218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
10238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cat_datum_t *cdatum;
10248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		int range_start, range_end, i;
10258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (id_has_dot(id)) {
10278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			char *id_start = id;
10288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			char *id_end = strchr(id, '.');
10298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			*(id_end++) = '\0';
10318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			cdatum =
10338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
10348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   table,
10358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   (hashtab_key_t)
10368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   id_start);
10378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!cdatum) {
10388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror2("unknown category %s", id_start);
10398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
10408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
10418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
10428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			range_start = cdatum->s.value - 1;
10438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			cdatum =
10448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
10458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   table,
10468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   (hashtab_key_t)
10478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   id_end);
10488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!cdatum) {
10498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror2("unknown category %s", id_end);
10508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
10518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
10528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
10538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			range_end = cdatum->s.value - 1;
10548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (range_end < range_start) {
10568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror2("category range is invalid");
10578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
10588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
10598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
10608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		} else {
10618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			cdatum =
10628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
10638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   table,
10648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   (hashtab_key_t) id);
10658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			range_start = range_end = cdatum->s.value - 1;
10668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
10678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		for (i = range_start; i <= range_end; i++) {
10698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
10708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("out of memory");
10718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
10728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
10738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
10748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
10758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
10778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
10788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (hashtab_map
10808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	    (policydbp->p_levels.table, clone_level, levdatum->level)) {
10818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
10828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
10838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
10848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
10868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
10878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_attrib(void)
10898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
10908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
10918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
10928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
10938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
10948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
10958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (declare_type(TRUE, TRUE) == NULL) {
10968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
10978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
10988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
10998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
11008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int add_aliases_to_type(type_datum_t * type)
11028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
11038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
11048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *aliasdatum = NULL;
11058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int ret;
11068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
11078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (id_has_dot(id)) {
11088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
11098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror
11108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    ("type alias identifiers may not contain periods");
11118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
11128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
11138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
11148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!aliasdatum) {
11158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
11168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
11178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
11188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
11198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		memset(aliasdatum, 0, sizeof(type_datum_t));
11208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		aliasdatum->s.value = type->s.value;
11218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ret = declare_symbol(SYM_TYPES, id, aliasdatum,
11238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				     NULL, &aliasdatum->s.value);
11248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		switch (ret) {
11258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -3:{
11268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("Out of memory!");
11278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto cleanup;
11288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
11298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -2:{
11308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror2("duplicate declaration of alias %s",
11318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					 id);
11328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto cleanup;
11338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
11348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -1:{
11358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("could not declare alias here");
11368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto cleanup;
11378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
11388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 0:	 	break;
11398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 1:{
11408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				/* ret == 1 means the alias was required and therefore already
11418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 * has a value. Set it up as an alias with a different primary. */
11428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				type_datum_destroy(aliasdatum);
11438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(aliasdatum);
11448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id);
11468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				assert(aliasdatum);
11478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				aliasdatum->primary = type->s.value;
11498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				aliasdatum->flavor = TYPE_ALIAS;
11508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				break;
11528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
11538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		default:{
11548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				assert(0);	/* should never get here */
11558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
11568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
11578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
11588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
11598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      cleanup:
11608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
11618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_destroy(aliasdatum);
11628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(aliasdatum);
11638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
11648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
11658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_typealias(void)
11678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
11688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
11698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *t;
11708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
11728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
11738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
11748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
11758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
11768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
11788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
11798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no type name for typealias definition?");
11808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
11818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
11828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, id)) {
11848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", id);
11858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
11868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
11878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
11888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	t = hashtab_search(policydbp->p_types.table, id);
11898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!t || t->flavor == TYPE_ATTRIB) {
11908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown type %s, or it was already declared as an "
11918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 "attribute", id);
11928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
11938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
11948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
11958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return add_aliases_to_type(t);
11968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
11978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
11988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_typeattribute(void)
11998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
12008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
12018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *t, *attr;
12028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
12048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
12058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
12068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
12078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
12108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
12118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no type name for typeattribute definition?");
12128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
12138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, id)) {
12168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", id);
12178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
12188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
12198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	t = hashtab_search(policydbp->p_types.table, id);
12218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!t || t->flavor == TYPE_ATTRIB) {
12228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown type %s", id);
12238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
12248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
12258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
12288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!is_id_in_scope(SYM_TYPES, id)) {
12298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("attribute %s is not within scope", id);
12308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
12318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
12328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
12338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		attr = hashtab_search(policydbp->p_types.table, id);
12348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!attr) {
12358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/* treat it as a fatal error */
12368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("attribute %s is not declared", id);
12378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
12388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
12398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
12408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (attr->flavor != TYPE_ATTRIB) {
12428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("%s is a type, not an attribute", id);
12438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
12448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
12458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
12468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
12488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
12498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
12508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
12518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
12538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
12548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
12558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
12568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
12598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
12608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int define_typebounds_helper(char *bounds_id, char *type_id)
12628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
12638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *bounds, *type;
12648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, bounds_id)) {
12668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", bounds_id);
12678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
12688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	bounds = hashtab_search(policydbp->p_types.table, bounds_id);
12718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!bounds || bounds->flavor == TYPE_ATTRIB) {
12728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("hoge unknown type %s", bounds_id);
12738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
12748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, type_id)) {
12778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", type_id);
12788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
12798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type = hashtab_search(policydbp->p_types.table, type_id);
12828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!type || type->flavor == TYPE_ATTRIB) {
12838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not declared", type_id);
12848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
12858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (type->flavor == TYPE_TYPE && !type->primary) {
12888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		type = policydbp->type_val_to_struct[type->s.value - 1];
12898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else if (type->flavor == TYPE_ALIAS) {
12908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		type = policydbp->type_val_to_struct[type->primary - 1];
12918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
12928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
12938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!type->bounds)
12948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		type->bounds = bounds->s.value;
12958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else if (type->bounds != bounds->s.value) {
12968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s has inconsistent master {%s,%s}",
12978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 type_id,
12988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 policydbp->p_type_val_to_name[type->bounds - 1],
12998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			 policydbp->p_type_val_to_name[bounds->s.value - 1]);
13008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
13018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
13028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
13048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
13058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_typebounds(void)
13078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
13088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *bounds, *id;
13098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
13118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
13128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
13138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
13148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
13158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	bounds = (char *) queue_remove(id_queue);
13178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!bounds) {
13188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no type name for typebounds definition?");
13198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
13208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
13218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
13238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (define_typebounds_helper(bounds, id))
13248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
13258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
13268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
13278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(bounds);
13288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
13308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
13318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_type(int alias)
13338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
13348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
13358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *datum, *attr;
13368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
13388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/*
13398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 * If type name contains ".", we have to define boundary
13408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 * relationship implicitly to keep compatibility with
13418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 * old name based hierarchy.
13428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 */
13438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if ((id = queue_remove(id_queue))) {
13448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			char *bounds, *delim;
13458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if ((delim = strrchr(id, '.'))
13478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    && (bounds = strdup(id))) {
13488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				bounds[(size_t)(delim - id)] = '\0';
13498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (define_typebounds_helper(bounds, id))
13518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return -1;
13528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(bounds);
13538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
13548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
13558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
13568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (alias) {
13588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue)))
13598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
13608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
13618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
13638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
13648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
13658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
13668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if ((datum = declare_type(TRUE, FALSE)) == NULL) {
13688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
13698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
13708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (alias) {
13728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (add_aliases_to_type(datum) == -1) {
13738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
13748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
13758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
13768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
13788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!is_id_in_scope(SYM_TYPES, id)) {
13798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("attribute %s is not within scope", id);
13808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
13818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
13828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
13838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		attr = hashtab_search(policydbp->p_types.table, id);
13848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!attr) {
13858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/* treat it as a fatal error */
13868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("attribute %s is not declared", id);
13878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
13888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
13898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (attr->flavor != TYPE_ATTRIB) {
13918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("%s is a type, not an attribute", id);
13928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
13938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
13948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
13958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
13968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
13978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
13988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
13998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
14018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory");
14028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
14038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
14048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
14058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
14078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
14088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstruct val_to_name {
14108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int val;
14118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *name;
14128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android};
14138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* Adds a type, given by its textual name, to a typeset.  If *add is
14158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android   0, then add the type to the negative set; otherwise if *add is 1
14168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android   then add it to the positive side. */
14178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int set_types(type_set_t * set, char *id, int *add, char starallowed)
14188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
14198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *t;
14208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (strcmp(id, "*") == 0) {
14228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!starallowed) {
14238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("* not allowed in this type of rule");
14248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
14258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
14268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* set TYPE_STAR flag */
14278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		set->flags = TYPE_STAR;
14288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
14298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		*add = 1;
14308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
14318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
14328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (strcmp(id, "~") == 0) {
14348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!starallowed) {
14358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("~ not allowed in this type of rule");
14368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
14378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
14388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* complement the set */
14398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		set->flags = TYPE_COMP;
14408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
14418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		*add = 1;
14428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
14438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
14448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (strcmp(id, "-") == 0) {
14468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		*add = 0;
14478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
14488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
14498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
14508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, id)) {
14528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", id);
14538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
14548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
14558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
14568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	t = hashtab_search(policydbp->p_types.table, id);
14578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!t) {
14588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown type %s", id);
14598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
14608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
14618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
14628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (*add == 0) {
14648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
14658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto oom;
14668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else {
14678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
14688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto oom;
14698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
14708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
14718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	*add = 1;
14728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
14738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      oom:
14748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	yyerror("Out of memory");
14758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
14768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
14778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
14788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_compute_type_helper(int which, avrule_t ** rule)
14808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
14818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
14828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *datum;
14838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_t tclasses;
14848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_node_t *node;
14858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_t *avrule;
14868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_perm_node_t *perm;
14878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int i, add = 1;
14888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule = malloc(sizeof(avrule_t));
14908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!avrule) {
14918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
14928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
14938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
14948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_init(avrule);
14958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule->specified = which;
14968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule->line = policydb_lineno;
14978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
14988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
14998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types(&avrule->stypes, id, &add, 0))
15000d73ef7049feee794f14cf1af88d05dae8139914Alice Chu			goto bad;
15018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
15028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	add = 1;
15038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
15048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types(&avrule->ttypes, id, &add, 0))
15050d73ef7049feee794f14cf1af88d05dae8139914Alice Chu			goto bad;
15068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
15078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&tclasses);
1509cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	if (read_classes(&tclasses))
1510cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		goto bad;
15118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
15138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
15148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no newtype?");
15158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
15168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
15178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, id)) {
15188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", id);
15198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
15208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
15218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
15228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
15238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						(hashtab_key_t) id);
15248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!datum || datum->flavor == TYPE_ATTRIB) {
15258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown type %s", id);
15268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
15278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
15288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_for_each_bit(&tclasses, node, i) {
15308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_node_get_bit(node, i)) {
15318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			perm = malloc(sizeof(class_perm_node_t));
15328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!perm) {
15338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("out of memory");
15340d73ef7049feee794f14cf1af88d05dae8139914Alice Chu				goto bad;
15358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
15368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			class_perm_node_init(perm);
15378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			perm->class = i + 1;
15388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			perm->data = datum->s.value;
15398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			perm->next = avrule->perms;
15408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			avrule->perms = perm;
15418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
15428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
15438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&tclasses);
15448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	*rule = avrule;
15468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
15478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
15498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_destroy(avrule);
15508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(avrule);
15518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
15528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
15538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_compute_type(int which)
15558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
15568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
15578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_t *avrule;
15588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
15608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
15618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
15628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
15638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
15648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
15658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
15668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
15678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
15688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
15698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
15708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (define_compute_type_helper(which, &avrule))
15728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
15738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	append_avrule(avrule);
15758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
15768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
15778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidavrule_t *define_cond_compute_type(int which)
15798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
15808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
15818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_t *avrule;
15828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
15848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
15858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
15868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
15878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
15888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
15898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
15908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
15918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
15928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (avrule_t *) 1;
15938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
15948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (define_compute_type_helper(which, &avrule))
15968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return COND_ERR;
15978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
15988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return avrule;
15998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
16008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
1601cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalleyint define_bool_tunable(int is_tunable)
16028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
16038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id, *bool_value;
16048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cond_bool_datum_t *datum;
16058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int ret;
16068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	uint32_t value;
16078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
16088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
16098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
16108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
16118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
16128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
16138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
16148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
16158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
16168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no identifier for bool definition?");
16178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
16188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
16198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id_has_dot(id)) {
16208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
16218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("boolean identifiers may not contain periods");
16228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
16238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
16248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
16258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!datum) {
16268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
16278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
16288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
16298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
16308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(datum, 0, sizeof(cond_bool_datum_t));
1631cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	if (is_tunable)
1632cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		datum->flags |= COND_BOOL_FLAGS_TUNABLE;
16338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
16348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	switch (ret) {
16358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -3:{
16368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
16378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto cleanup;
16388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
16398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -2:{
16408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate declaration of boolean %s", id);
16418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto cleanup;
16428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
16438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case -1:{
16448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("could not declare boolean here");
16458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto cleanup;
16468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
16478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case 0:
16488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case 1:{
16498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
16508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
16518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	default:{
16528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			assert(0);	/* should never get here */
16538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
16548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
16558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum->s.value = value;
16568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
16578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	bool_value = (char *)queue_remove(id_queue);
16588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!bool_value) {
16598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no default value for bool definition?");
16608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
16618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
16628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
16638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
16648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
16658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
16668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      cleanup:
16678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cond_destroy_bool(id, datum, NULL);
16688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
16698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
16708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
16718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidavrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
16728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
16738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
16748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* return something so we get through pass 1 */
16758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (avrule_t *) 1;
16768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
16778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
16788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (sl == NULL) {
16798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* This is a require block, return previous list */
16808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return avlist;
16818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
16828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
16838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* prepend the new avlist to the pre-existing one */
16848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	sl->next = avlist;
16858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return sl;
16868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
16878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
16888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_te_avtab_helper(int which, avrule_t ** rule)
16898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
16908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
16918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_datum_t *cladatum;
16928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	perm_datum_t *perdatum = NULL;
16938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
16948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_t tclasses;
16958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_node_t *node;
16968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_t *avrule;
16978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int i;
16988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int add = 1, ret = 0;
16998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int suppress = 0;
17008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
17018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule = (avrule_t *) malloc(sizeof(avrule_t));
17028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!avrule) {
17038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("memory error");
17048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ret = -1;
17058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
17068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
17078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_init(avrule);
17088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule->specified = which;
17098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule->line = policydb_lineno;
17108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
17118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
17128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types
17138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (&avrule->stypes, id, &add,
17148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
17158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ret = -1;
17168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto out;
17178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
17188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
17198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	add = 1;
17208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
17218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (strcmp(id, "self") == 0) {
17228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
17238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			avrule->flags |= RULE_SELF;
17248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			continue;
17258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
17268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types
17278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (&avrule->ttypes, id, &add,
17288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
17298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ret = -1;
17308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto out;
17318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
17328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
17338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
17348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&tclasses);
1735cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	ret = read_classes(&tclasses);
1736cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	if (ret)
1737cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		goto out;
17388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
17398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	perms = NULL;
17408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_for_each_bit(&tclasses, node, i) {
17418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!ebitmap_node_get_bit(node, i))
17428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			continue;
17438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cur_perms =
17448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
17458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cur_perms) {
17468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
17478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ret = -1;
17488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto out;
17498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
17508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		class_perm_node_init(cur_perms);
17518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cur_perms->class = i + 1;
17528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!perms)
17538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			perms = cur_perms;
17548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (tail)
17558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			tail->next = cur_perms;
17568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		tail = cur_perms;
17578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
17588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
17598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
17608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cur_perms = perms;
17618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_for_each_bit(&tclasses, node, i) {
17628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!ebitmap_node_get_bit(node, i))
17638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				continue;
17648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			cladatum = policydbp->class_val_to_struct[i];
17658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
17668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (strcmp(id, "*") == 0) {
17678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				/* set all permissions in the class */
17688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				cur_perms->data = ~0U;
17698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto next;
17708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
17718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
17728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (strcmp(id, "~") == 0) {
17738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				/* complement the set */
17748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (which == AVRULE_DONTAUDIT)
17758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yywarn("dontaudit rule with a ~?");
17768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				cur_perms->data = ~cur_perms->data;
17778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto next;
17788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
17798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
17808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			perdatum =
17818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    hashtab_search(cladatum->permissions.table, id);
17828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!perdatum) {
17838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (cladatum->comdatum) {
17848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					perdatum =
17858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					    hashtab_search(cladatum->comdatum->
17868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   permissions.table,
17878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							   id);
17888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
17898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
17908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!perdatum) {
17918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!suppress)
17928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror2("permission %s is not defined"
17938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					     " for class %s", id,
17948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					     policydbp->p_class_val_to_name[i]);
17958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				continue;
17968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			} else
17978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    if (!is_perm_in_scope
17988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				(id, policydbp->p_class_val_to_name[i])) {
17998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!suppress) {
18008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror2("permission %s of class %s is"
18018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					     " not within scope", id,
18028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					     policydbp->p_class_val_to_name[i]);
18038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
18048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				continue;
18058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			} else {
18068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				cur_perms->data |= 1U << (perdatum->s.value - 1);
18078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
18088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		      next:
18098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			cur_perms = cur_perms->next;
18108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
18118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
18138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
18148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&tclasses);
18168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule->perms = perms;
18188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	*rule = avrule;
18198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      out:
18218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return ret;
18228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
18248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidavrule_t *define_cond_te_avtab(int which)
18268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
18278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
18288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_t *avrule;
18298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int i;
18308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
18328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		for (i = 0; i < 4; i++) {
18338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue)))
18348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
18358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
18368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (avrule_t *) 1;	/* any non-NULL value */
18378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
18388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (define_te_avtab_helper(which, &avrule))
18408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return COND_ERR;
18418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return avrule;
18438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
18448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_te_avtab(int which)
18468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
18478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
18488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	avrule_t *avrule;
18498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int i;
18508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
18528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		for (i = 0; i < 4; i++) {
18538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue)))
18548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
18558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
18568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
18578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
18588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (define_te_avtab_helper(which, &avrule))
18608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
18618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* append this avrule to the end of the current rules list */
18638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	append_avrule(avrule);
18648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
18658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
18668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* The role-types rule is no longer used to declare regular role or
18688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android * role attribute, but solely aimed for declaring role-types associations.
18698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android */
18708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_role_types(void)
18718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
18728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *role;
18738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
18748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int add = 1;
18758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
18778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
18788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
18798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
18808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
18818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
18838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
18848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no role name for role-types rule?");
18858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
18868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
18878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_ROLES, id)) {
18898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("role %s is not within scope", id);
18908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
18918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
18928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
18938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
18948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role = hashtab_search(policydbp->p_roles.table, id);
18958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!role) {
18968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown role %s", id);
18978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
18988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
18998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
19008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
19028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types(&role->types, id, &add, 0))
19038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
19048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
19058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
19078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
19088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_attrib_role(void)
19108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
19118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
19128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
19138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
19148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
19158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Declare a role attribute */
19178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (declare_role(TRUE) == NULL)
19188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
19198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
19218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
19228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_role_attr(void)
19248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
19258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
19268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *r, *attr;
19278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
19298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
19308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
19318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
19328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
19338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Declare a regular role */
19358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if ((r = declare_role(FALSE)) == NULL)
19368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
19378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
19398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!is_id_in_scope(SYM_ROLES, id)) {
19408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("attribute %s is not within scope", id);
19418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
19428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
19438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
19448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		attr = hashtab_search(policydbp->p_roles.table, id);
19458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!attr) {
19468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/* treat it as a fatal error */
19478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("role attribute %s is not declared", id);
19488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
19498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
19508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
19518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (attr->flavor != ROLE_ATTRIB) {
19538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("%s is a regular role, not an attribute", id);
19548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
19558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
19568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
19578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
19598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
19608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
19618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
19628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
19648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
19658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
19668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
19678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
19688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
19708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
19718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_roleattribute(void)
19738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
19748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
19758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *r, *attr;
19768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 2) {
19788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
19798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
19808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
19818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
19828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
19848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
19858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no role name for roleattribute definition?");
19868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
19878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
19888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
19898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_ROLES, id)) {
19908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("role %s is not within scope", id);
19918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
19928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
19938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
19948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	r = hashtab_search(policydbp->p_roles.table, id);
19958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* We support adding one role attribute into another */
19968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!r) {
19978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown role %s", id);
19988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
19998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
20008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
20018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
20038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!is_id_in_scope(SYM_ROLES, id)) {
20048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("attribute %s is not within scope", id);
20058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
20068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
20078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
20088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		attr = hashtab_search(policydbp->p_roles.table, id);
20098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!attr) {
20108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/* treat it as a fatal error */
20118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("role attribute %s is not declared", id);
20128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
20138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
20148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
20158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (attr->flavor != ROLE_ATTRIB) {
20178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("%s is a regular role, not an attribute", id);
20188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
20198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
20208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
20218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
20238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
20248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
20258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
20268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
20288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
20298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
20308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
20318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
20328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
20348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
20358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidrole_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
20378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
20388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *new;
20398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
20418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (role_datum_t *) 1;	/* any non-NULL value */
20428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
20438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	new = malloc(sizeof(role_datum_t));
20458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!new) {
20468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
20478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return NULL;
20488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
20498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(new, 0, sizeof(role_datum_t));
20508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	new->s.value = 0;		/* temporary role */
20518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
20528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
20530d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		free(new);
20548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return NULL;
20558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
20568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
20578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
20580d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		free(new);
20598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return NULL;
20608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
20618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!r1->s.value) {
20628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* free intermediate result */
20638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		type_set_destroy(&r1->types);
20648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_destroy(&r1->dominates);
20658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(r1);
20668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
20678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!r2->s.value) {
20688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* free intermediate result */
20698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("right hand role is temporary?");
20708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		type_set_destroy(&r2->types);
20718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_destroy(&r2->dominates);
20728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(r2);
20738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
20748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return new;
20758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
20768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* This function eliminates the ordering dependency of role dominance rule */
20788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum,
20798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 void *arg)
20808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
20818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *rdp = (role_datum_t *) arg;
20828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *rdatum = (role_datum_t *) datum;
20838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_node_t *node;
20848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int i;
20858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Don't bother to process against self role */
20878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (rdatum->s.value == rdp->s.value)
20888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
20898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
20908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* If a dominating role found */
20918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
20928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_t types;
20938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_init(&types);
20948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
20958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_destroy(&types);
20968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
20978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
20988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* raise types and dominates from dominated role */
20998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_for_each_bit(&rdp->dominates, node, i) {
21008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_node_get_bit(node, i))
21018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (ebitmap_set_bit
21028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    (&rdatum->dominates, i, TRUE))
21038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					goto oom;
21048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
21058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_for_each_bit(&types, node, i) {
21068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_node_get_bit(node, i))
21078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (ebitmap_set_bit
21088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    (&rdatum->types.types, i, TRUE))
21098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					goto oom;
21108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
21118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_destroy(&types);
21128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
21138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
21148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* go through all the roles */
21158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
21168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      oom:
21178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	yyerror("Out of memory");
21188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
21198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
21208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
21218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidrole_datum_t *define_role_dom(role_datum_t * r)
21228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
21238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *role;
21248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *role_id;
21258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_node_t *node;
21268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int i;
21278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int ret;
21288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
21298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
21308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		role_id = queue_remove(id_queue);
21318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(role_id);
21328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (role_datum_t *) 1;	/* any non-NULL value */
21338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
21348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
21358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	yywarn("Role dominance has been deprecated");
21368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
21378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_id = queue_remove(id_queue);
21388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_ROLES, role_id)) {
21398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("role %s is not within scope", role_id);
21408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(role_id);
21418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return NULL;
21428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
21438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
21448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					       role_id);
21458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!role) {
21468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		role = (role_datum_t *) malloc(sizeof(role_datum_t));
21478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!role) {
21488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
21498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(role_id);
21508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return NULL;
21518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
21528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		memset(role, 0, sizeof(role_datum_t));
21538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ret =
21548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
21558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				   (hashtab_datum_t) role, &role->s.value,
21568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				   &role->s.value);
21578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		switch (ret) {
21588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -3:{
21598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("Out of memory!");
21608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto cleanup;
21618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
21628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -2:{
21638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror2("duplicate declaration of role %s",
21648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					 role_id);
21658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto cleanup;
21668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
21678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case -1:{
21688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("could not declare role here");
21698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto cleanup;
21708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
21718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 0:
21728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 1:{
21738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				break;
21748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
21758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		default:{
21768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				assert(0);	/* should never get here */
21778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
21788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
21798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
21808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("Out of memory!");
21818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto cleanup;
21828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
21838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
21848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (r) {
21858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_t types;
21868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_init(&types);
21878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_for_each_bit(&r->dominates, node, i) {
21888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_node_get_bit(node, i))
21898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (ebitmap_set_bit(&role->dominates, i, TRUE))
21908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					goto oom;
21918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
21928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (type_set_expand(&r->types, &types, policydbp, 1)) {
21938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_destroy(&types);
21948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return NULL;
21958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
21968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_for_each_bit(&types, node, i) {
21978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_node_get_bit(node, i))
21988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (ebitmap_set_bit
21998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    (&role->types.types, i, TRUE))
22008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					goto oom;
22018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
22028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_destroy(&types);
22038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!r->s.value) {
22048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/* free intermediate result */
22058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			type_set_destroy(&r->types);
22068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_destroy(&r->dominates);
22078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(r);
22088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
22098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/*
22108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 * Now go through all the roles and escalate this role's
22118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 * dominates and types if a role dominates this role.
22128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		 */
22138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		hashtab_map(policydbp->p_roles.table,
22148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    dominate_role_recheck, role);
22158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
22168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return role;
22178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      cleanup:
22188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(role_id);
22198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_destroy(role);
22208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(role);
22218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return NULL;
22228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      oom:
22238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	yyerror("Out of memory");
22248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	goto cleanup;
22258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
22268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
22288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				   void *p)
22298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
22308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct val_to_name *v = p;
22318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *roldatum;
22328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	roldatum = (role_datum_t *) datum;
22348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (v->val == roldatum->s.value) {
22368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		v->name = key;
22378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 1;
22388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
22398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
22418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
22428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic char *role_val_to_name(unsigned int val)
22448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
22458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct val_to_name v;
22468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int rc;
22478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	v.val = val;
22498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
22508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (rc)
22518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return v.name;
22528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return NULL;
22538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
22548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int set_roles(role_set_t * set, char *id)
22568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
22578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *r;
22588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (strcmp(id, "*") == 0) {
22608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
22618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("* is not allowed for role sets");
22628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
22638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
22648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (strcmp(id, "~") == 0) {
22668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
22678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("~ is not allowed for role sets");
22688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
22698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
22708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_ROLES, id)) {
22718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("role %s is not within scope", id);
22728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
22738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
22748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
22758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	r = hashtab_search(policydbp->p_roles.table, id);
22768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!r) {
22778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown role %s", id);
22788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
22798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
22808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
22818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
22838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
22848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
22858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
22868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
22878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
22888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
22898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
22908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
22918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_role_trans(int class_specified)
22928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
22938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
22948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *role;
22958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_set_t roles;
22968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_set_t types;
22978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_datum_t *cladatum;
22988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_t e_types, e_roles, e_classes;
22998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_node_t *tnode, *rnode, *cnode;
23008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct role_trans *tr = NULL;
23018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct role_trans_rule *rule = NULL;
23028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int i, j, k;
23038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int add = 1;
23048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
23068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
23078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
23088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
23098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
23108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (class_specified)
23118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue)))
23128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
23138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
23148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
23158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
23168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
23178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_set_init(&roles);
23198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&e_roles);
23208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_set_init(&types);
23218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&e_types);
23228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&e_classes);
23238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
23258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_roles(&roles, id))
23268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
23278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
23288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	add = 1;
23298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
23308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types(&types, id, &add, 0))
23318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
23328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
23338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (class_specified) {
2335cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		if (read_classes(&e_classes))
2336cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley			return -1;
23378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else {
23388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum = hashtab_search(policydbp->p_classes.table,
23398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					  "process");
23408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cladatum) {
23418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("could not find process class for "
23428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 "legacy role_transition statement");
23438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
23448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
23458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
2346ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) {
2347ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			yyerror("out of memory");
2348ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley			return -1;
2349ba8e9924f575e267f1503b7669fe3120d68d4e1fStephen Smalley		}
23508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
23518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
23538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
23548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no new role in transition definition?");
23558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
23568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
23578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_ROLES, id)) {
23588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("role %s is not within scope", id);
23598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
23608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
23618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
23628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role = hashtab_search(policydbp->p_roles.table, id);
23638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!role) {
23648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown role %s used in transition definition", id);
23658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
23668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
23678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (role->flavor != ROLE_ROLE) {
23698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("the new role %s must be a regular role", id);
23708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
23718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
23728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
23748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
23758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
23768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (type_set_expand(&types, &e_types, policydbp, 1))
23788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
23798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
23808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_for_each_bit(&e_roles, rnode, i) {
23818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!ebitmap_node_get_bit(rnode, i))
23828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			continue;
23838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_for_each_bit(&e_types, tnode, j) {
23848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!ebitmap_node_get_bit(tnode, j))
23858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				continue;
23868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_for_each_bit(&e_classes, cnode, k) {
23878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!ebitmap_node_get_bit(cnode, k))
23888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					continue;
23898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				for (tr = policydbp->role_tr; tr;
23908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				     tr = tr->next) {
23918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					if (tr->role == (i + 1) &&
23928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					    tr->type == (j + 1) &&
23938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					    tr->tclass == (k + 1)) {
23948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						yyerror2("duplicate role "
23958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 "transition for "
23968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 "(%s,%s,%s)",
23978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 role_val_to_name(i+1),
23988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 policydbp->p_type_val_to_name[j],
23998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 policydbp->p_class_val_to_name[k]);
24008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						goto bad;
24018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					}
24028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
24038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				tr = malloc(sizeof(struct role_trans));
24058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!tr) {
24068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror("out of memory");
24078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return -1;
24088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
24098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				memset(tr, 0, sizeof(struct role_trans));
24108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				tr->role = i + 1;
24118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				tr->type = j + 1;
24128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				tr->tclass = k + 1;
24138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				tr->new_role = role->s.value;
24148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				tr->next = policydbp->role_tr;
24158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				policydbp->role_tr = tr;
24168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
24178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
24188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
24198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Now add the real rule */
24208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rule = malloc(sizeof(struct role_trans_rule));
24218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!rule) {
24228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
24238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
24248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
24258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(rule, 0, sizeof(struct role_trans_rule));
24268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rule->roles = roles;
24278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rule->types = types;
24288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rule->classes = e_classes;
24298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rule->new_role = role->s.value;
24308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	append_role_trans(rule);
24328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&e_roles);
24348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&e_types);
24358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
24378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
24398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
24408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
24418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_role_allow(void)
24438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
24448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
24458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct role_allow_rule *ra = 0;
24468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
24488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
24498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
24508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
24518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
24528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
24538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
24548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ra = malloc(sizeof(role_allow_rule_t));
24568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!ra) {
24578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
24588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
24598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
24608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_allow_rule_init(ra);
24618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
24630d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		if (set_roles(&ra->roles, id)) {
24640d73ef7049feee794f14cf1af88d05dae8139914Alice Chu			free(ra);
24658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
24660d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		}
24678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
24688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
24700d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		if (set_roles(&ra->new_roles, id)) {
24710d73ef7049feee794f14cf1af88d05dae8139914Alice Chu			free(ra);
24728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
24730d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		}
24748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
24758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	append_role_allow(ra);
24778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
24788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
24798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidavrule_t *define_cond_filename_trans(void)
24818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
24828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	yyerror("type transitions with a filename not allowed inside "
24838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		"conditionals\n");
24848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return COND_ERR;
24858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
24868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
24878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_filename_trans(void)
24888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
24898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id, *name = NULL;
24908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_set_t stypes, ttypes;
24918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_t e_stypes, e_ttypes;
24928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_t e_tclasses;
24938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_node_t *snode, *tnode, *cnode;
24948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	filename_trans_t *ft;
24958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	filename_trans_rule_t *ftr;
24968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *typdatum;
24978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	uint32_t otype;
24988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int c, s, t;
24998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int add;
25008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
25028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* stype */
25038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
25048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
25058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* ttype */
25068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
25078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
25088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* tclass */
25098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
25108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
25118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* otype */
25128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
25138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
25148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* name */
25158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
25168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
25178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
25188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
25198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	add = 1;
25228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_set_init(&stypes);
25238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
25248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types(&stypes, id, &add, 0))
25258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
25268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
25278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	add =1;
25298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_set_init(&ttypes);
25308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
25318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types(&ttypes, id, &add, 0))
25328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
25338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
25348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&e_tclasses);
2536cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley	if (read_classes(&e_tclasses))
2537cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		goto bad;
25388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
25408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
25418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no otype in transition definition?");
25428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
25438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
25448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, id)) {
25458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", id);
25468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
25478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
25488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
25498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	typdatum = hashtab_search(policydbp->p_types.table, id);
25508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!typdatum) {
25518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown type %s used in transition definition", id);
25528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
25538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
25548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
25558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	otype = typdatum->s.value;
25568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	name = queue_remove(id_queue);
25588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!name) {
25598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no pathname specified in filename_trans definition?");
25608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
25618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
25628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* We expand the class set into seperate rules.  We expand the types
25648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	 * just to make sure there are not duplicates.  They will get turned
25658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	 * into seperate rules later */
25668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&e_stypes);
25678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
25688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
25698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&e_ttypes);
25718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
25728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
25738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_for_each_bit(&e_tclasses, cnode, c) {
25758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!ebitmap_node_get_bit(cnode, c))
25768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			continue;
25778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_for_each_bit(&e_stypes, snode, s) {
25788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!ebitmap_node_get_bit(snode, s))
25798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				continue;
25808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_for_each_bit(&e_ttypes, tnode, t) {
25818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!ebitmap_node_get_bit(tnode, t))
25828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					continue;
25838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				for (ft = policydbp->filename_trans; ft; ft = ft->next) {
25858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					if (ft->stype == (s + 1) &&
25868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					    ft->ttype == (t + 1) &&
25878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					    ft->tclass == (c + 1) &&
25888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					    !strcmp(ft->name, name)) {
25898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
25908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 name,
25918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 policydbp->p_type_val_to_name[s],
25928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 policydbp->p_type_val_to_name[t],
25938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 policydbp->p_class_val_to_name[c]);
25948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						goto bad;
25958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					}
25968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
25978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
25988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				ft = malloc(sizeof(*ft));
25998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!ft) {
26008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror("out of memory");
26018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					goto bad;
26028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
26038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				memset(ft, 0, sizeof(*ft));
26048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				ft->next = policydbp->filename_trans;
26068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				policydbp->filename_trans = ft;
26078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				ft->name = strdup(name);
26098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!ft->name) {
26108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror("out of memory");
26118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					goto bad;
26128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
26138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				ft->stype = s + 1;
26148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				ft->ttype = t + 1;
26158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				ft->tclass = c + 1;
26168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				ft->otype = otype;
26178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
26188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
26198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* Now add the real rule since we didn't find any duplicates */
26218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ftr = malloc(sizeof(*ftr));
26228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!ftr) {
26238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
26248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
26258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
26268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		filename_trans_rule_init(ftr);
26278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		append_filename_trans(ftr);
26288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ftr->name = strdup(name);
26308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ftr->stypes = stypes;
26318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ftr->ttypes = ttypes;
26328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ftr->tclass = c + 1;
26338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ftr->otype = otype;
26348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
26358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(name);
26378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&e_stypes);
26388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&e_ttypes);
26398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&e_tclasses);
26408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
26428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidbad:
26448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(name);
26458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
26468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
26478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
26498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
26508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
26518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (e = expr; e; e = e->next) {
26528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newe = malloc(sizeof(*newe));
26538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!newe)
26548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto oom;
26558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (constraint_expr_init(newe) == -1) {
26568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(newe);
26578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto oom;
26588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
26598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (l)
26608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			l->next = newe;
26618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		else
26628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			h = newe;
26638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l = newe;
26648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newe->expr_type = e->expr_type;
26658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newe->attr = e->attr;
26668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newe->op = e->op;
26678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (newe->expr_type == CEXPR_NAMES) {
26688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (newe->attr & CEXPR_TYPE) {
26698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (type_set_cpy
26708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    (newe->type_names, e->type_names))
26718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					goto oom;
26728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			} else {
26738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (ebitmap_cpy(&newe->names, &e->names))
26748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					goto oom;
26758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
26768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
26778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
26788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return h;
26808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      oom:
26818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	e = h;
26828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while (e) {
26838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l = e;
26848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e = e->next;
26858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		constraint_expr_destroy(l);
26868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
26878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return NULL;
26888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
26898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
26908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_constraint(constraint_expr_t * expr)
26918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
26928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct constraint_node *node;
26938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
26948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_datum_t *cladatum;
26958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	perm_datum_t *perdatum;
26968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_t classmap;
26978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_node_t *enode;
26988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	constraint_expr_t *e;
26998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int i;
27008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int depth;
27018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned char useexpr = 1;
27028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
27038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
27048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
27058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
27068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
27078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
27088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
27098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
27108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
27118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	depth = -1;
27128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (e = expr; e; e = e->next) {
27138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		switch (e->expr_type) {
27148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_NOT:
27158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth < 0) {
27168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("illegal constraint expression");
27178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
27188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
27198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
27208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_AND:
27218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_OR:
27228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth < 1) {
27238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("illegal constraint expression");
27248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
27258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
27268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			depth--;
27278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
27288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_ATTR:
27298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_NAMES:
27308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (e->attr & CEXPR_XTARGET) {
27318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("illegal constraint expression");
27328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;	/* only for validatetrans rules */
27338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
27348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth == (CEXPR_MAXDEPTH - 1)) {
27358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("constraint expression is too deep");
27368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
27378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
27388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			depth++;
27398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
27408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		default:
27418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("illegal constraint expression");
27428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
27438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
27448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
27458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (depth != 0) {
27468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("illegal constraint expression");
27478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
27488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
27498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
27508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&classmap);
27518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
27528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!is_id_in_scope(SYM_CLASSES, id)) {
27538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("class %s is not within scope", id);
27548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
27558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
27568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
27578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum =
27588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
27598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						     (hashtab_key_t) id);
27608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cladatum) {
27618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("class %s is not defined", id);
27628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_destroy(&classmap);
27638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
27648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
27658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
27668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
27678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
27688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_destroy(&classmap);
27698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
27708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
27718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
27728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		node = malloc(sizeof(struct constraint_node));
27738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!node) {
27748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
27758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
27768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
27778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		memset(node, 0, sizeof(constraint_node_t));
27788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (useexpr) {
27798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			node->expr = expr;
27808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			useexpr = 0;
27818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		} else {
27828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			node->expr = constraint_expr_clone(expr);
27838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
27848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!node->expr) {
27858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
27860d73ef7049feee794f14cf1af88d05dae8139914Alice Chu			free(node);
27878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
27888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
27898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		node->permissions = 0;
27908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
27918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		node->next = cladatum->constraints;
27928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum->constraints = node;
27938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
27948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
27958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
27968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
27978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
27988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_for_each_bit(&classmap, enode, i) {
27998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_node_get_bit(enode, i)) {
28008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				cladatum = policydbp->class_val_to_struct[i];
28018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				node = cladatum->constraints;
28028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
28038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				perdatum =
28048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    (perm_datum_t *) hashtab_search(cladatum->
28058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    permissions.
28068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    table,
28078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    (hashtab_key_t)
28088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    id);
28098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!perdatum) {
28108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					if (cladatum->comdatum) {
28118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						perdatum =
28128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						    (perm_datum_t *)
28138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						    hashtab_search(cladatum->
28148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								   comdatum->
28158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								   permissions.
28168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								   table,
28178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								   (hashtab_key_t)
28188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								   id);
28198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					}
28208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					if (!perdatum) {
28218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						yyerror2("permission %s is not"
28228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 " defined", id);
28238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						free(id);
28248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						ebitmap_destroy(&classmap);
28258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						return -1;
28268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					}
28278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
28288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				node->permissions |=
28298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    (1 << (perdatum->s.value - 1));
28308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
28318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
28328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
28338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
28348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
28358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&classmap);
28368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
28378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
28388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
28398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
28408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_validatetrans(constraint_expr_t * expr)
28418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
28428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct constraint_node *node;
28438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
28448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_datum_t *cladatum;
28458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_t classmap;
28468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	constraint_expr_t *e;
28478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int depth;
28488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned char useexpr = 1;
28498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
28508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
28518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
28528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
28538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
28548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
28558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
28568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	depth = -1;
28578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (e = expr; e; e = e->next) {
28588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		switch (e->expr_type) {
28598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_NOT:
28608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth < 0) {
28618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("illegal validatetrans expression");
28628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
28638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
28648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
28658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_AND:
28668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_OR:
28678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth < 1) {
28688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("illegal validatetrans expression");
28698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
28708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
28718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			depth--;
28728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
28738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_ATTR:
28748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case CEXPR_NAMES:
28758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth == (CEXPR_MAXDEPTH - 1)) {
28768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("validatetrans expression is too deep");
28778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
28788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
28798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			depth++;
28808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
28818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		default:
28828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("illegal validatetrans expression");
28838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
28848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
28858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
28868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (depth != 0) {
28878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("illegal validatetrans expression");
28888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
28898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
28908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
28918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_init(&classmap);
28928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
28938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!is_id_in_scope(SYM_CLASSES, id)) {
28948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("class %s is not within scope", id);
28958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
28968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
28978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
28988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum =
28998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
29008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						     (hashtab_key_t) id);
29018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cladatum) {
29028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("class %s is not defined", id);
29038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_destroy(&classmap);
29048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
29058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
29068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
29088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
29098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			ebitmap_destroy(&classmap);
29108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
29118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
29128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		node = malloc(sizeof(struct constraint_node));
29158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!node) {
29168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
29178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
29188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		memset(node, 0, sizeof(constraint_node_t));
29208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (useexpr) {
29218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			node->expr = expr;
29228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			useexpr = 0;
29238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		} else {
29248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			node->expr = constraint_expr_clone(expr);
29258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		node->permissions = 0;
29278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		node->next = cladatum->validatetrans;
29298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum->validatetrans = node;
29308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
29328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
29338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_destroy(&classmap);
29358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
29378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
29388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androiduintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
29408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
29418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct constraint_expr *expr, *e1 = NULL, *e2;
29428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	user_datum_t *user;
29438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *role;
29448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_t negset;
29458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
29468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	uint32_t val;
29478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int add = 1;
29488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
29508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (expr_type == CEXPR_NAMES) {
29518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue)))
29528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
29538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 1;	/* any non-NULL value */
29558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
29568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if ((expr = malloc(sizeof(*expr))) == NULL ||
29588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	    constraint_expr_init(expr) == -1) {
29598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
29608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(expr);
29618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
29628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
29638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	expr->expr_type = expr_type;
29648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	switch (expr_type) {
29668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case CEXPR_NOT:
29678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1 = NULL;
29688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e2 = (struct constraint_expr *)arg1;
29698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while (e2) {
29708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e1 = e2;
29718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e2 = e2->next;
29728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!e1 || e1->next) {
29748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("illegal constraint expression");
29758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			constraint_expr_destroy(expr);
29768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return 0;
29778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1->next = expr;
29798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return arg1;
29808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case CEXPR_AND:
29818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case CEXPR_OR:
29828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1 = NULL;
29838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e2 = (struct constraint_expr *)arg1;
29848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while (e2) {
29858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e1 = e2;
29868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e2 = e2->next;
29878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!e1 || e1->next) {
29898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("illegal constraint expression");
29908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			constraint_expr_destroy(expr);
29918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return 0;
29928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
29938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1->next = (struct constraint_expr *)arg2;
29948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
29958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1 = NULL;
29968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e2 = (struct constraint_expr *)arg2;
29978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while (e2) {
29988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e1 = e2;
29998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e2 = e2->next;
30008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
30018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!e1 || e1->next) {
30028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("illegal constraint expression");
30038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			constraint_expr_destroy(expr);
30048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return 0;
30058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
30068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1->next = expr;
30078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return arg1;
30088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case CEXPR_ATTR:
30098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		expr->attr = arg1;
30108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		expr->op = arg2;
30118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (uintptr_t) expr;
30128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case CEXPR_NAMES:
30138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		add = 1;
30148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		expr->attr = arg1;
30158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		expr->op = arg2;
30168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_init(&negset);
30178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = (char *)queue_remove(id_queue))) {
30188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (expr->attr & CEXPR_USER) {
30198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!is_id_in_scope(SYM_USERS, id)) {
30208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror2("user %s is not within scope",
30218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						 id);
30228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					constraint_expr_destroy(expr);
30238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return 0;
30248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
30258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				user =
30268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    (user_datum_t *) hashtab_search(policydbp->
30278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    p_users.
30288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    table,
30298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    (hashtab_key_t)
30308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    id);
30318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!user) {
30328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror2("unknown user %s", id);
30338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					constraint_expr_destroy(expr);
30348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return 0;
30358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
30368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				val = user->s.value;
30378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			} else if (expr->attr & CEXPR_ROLE) {
30388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!is_id_in_scope(SYM_ROLES, id)) {
30398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror2("role %s is not within scope",
30408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						 id);
30418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					constraint_expr_destroy(expr);
30428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return 0;
30438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
30448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				role =
30458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    (role_datum_t *) hashtab_search(policydbp->
30468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    p_roles.
30478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    table,
30488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    (hashtab_key_t)
30498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android								    id);
30508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!role) {
30518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					yyerror2("unknown role %s", id);
30528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					constraint_expr_destroy(expr);
30538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return 0;
30548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
30558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				val = role->s.value;
30568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			} else if (expr->attr & CEXPR_TYPE) {
30578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (set_types(expr->type_names, id, &add, 0)) {
30588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					constraint_expr_destroy(expr);
30598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return 0;
30608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
30618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				continue;
30628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			} else {
30638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("invalid constraint expression");
30648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				constraint_expr_destroy(expr);
30658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return 0;
30668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
30678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
30688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("out of memory");
30698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				ebitmap_destroy(&expr->names);
30708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				constraint_expr_destroy(expr);
30718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return 0;
30728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
30738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
30748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
30758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_destroy(&negset);
30768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (uintptr_t) expr;
30778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	default:
30788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("invalid constraint expression");
30798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		constraint_expr_destroy(expr);
30808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
30818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
30828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
30838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	yyerror("invalid constraint expression");
30848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(expr);
30858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
30868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
30878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
30888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
30898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
30908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cond_expr_t *e;
30918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int depth;
30928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cond_node_t cn, *cn_old;
30938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
30948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* expression cannot be NULL */
30958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!expr) {
30968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("illegal conditional expression");
30978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
30988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
30998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!t) {
31008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!f) {
31018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/* empty is fine, destroy expression and return */
31028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			cond_expr_destroy(expr);
31038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return 0;
31048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
31058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* Invert */
31068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		t = f;
31078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		f = 0;
31088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		expr = define_cond_expr(COND_NOT, expr, 0);
31098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!expr) {
31108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("unable to invert");
31118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
31128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
31138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
31148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* verify expression */
31168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	depth = -1;
31178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (e = expr; e; e = e->next) {
31188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		switch (e->expr_type) {
31198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case COND_NOT:
31208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth < 0) {
31218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror
31228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    ("illegal conditional expression; Bad NOT");
31238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
31248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
31258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
31268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case COND_AND:
31278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case COND_OR:
31288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case COND_XOR:
31298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case COND_EQ:
31308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case COND_NEQ:
31318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth < 1) {
31328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror
31338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    ("illegal conditional expression; Bad binary op");
31348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
31358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
31368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			depth--;
31378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
31388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case COND_BOOL:
31398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (depth == (COND_EXPR_MAXDEPTH - 1)) {
31408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror
31418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				    ("conditional expression is like totally too deep");
31428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
31438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
31448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			depth++;
31458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
31468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		default:
31478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("illegal conditional expression");
31488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
31498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
31508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
31518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (depth != 0) {
31528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("illegal conditional expression");
31538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
31548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
31558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/*  use tmp conditional node to partially build new node */
31578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(&cn, 0, sizeof(cn));
31588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cn.expr = expr;
31598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cn.avtrue_list = t;
31608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cn.avfalse_list = f;
31618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* normalize/precompute expression */
31638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (cond_normalize_expr(policydbp, &cn) < 0) {
31648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("problem normalizing conditional expression");
31658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
31668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
31678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* get the existing conditional node, or create a new one */
31698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cn_old = get_current_cond_list(&cn);
31708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!cn_old) {
31718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
31728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
31738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	append_cond_list(&cn);
31758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* note that there is no check here for duplicate rules, nor
31778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	 * check that rule already exists in base -- that will be
31788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	 * handled during conditional expansion, in expand.c */
31798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cn.avtrue_list = NULL;
31818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cn.avfalse_list = NULL;
31828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cond_node_destroy(&cn);
31838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
31858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
31868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidcond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
31888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
31898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct cond_expr *expr, *e1 = NULL, *e2;
31908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cond_bool_datum_t *bool_var;
31918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
31928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
31938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* expressions are handled in the second pass */
31948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
31958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (expr_type == COND_BOOL) {
31968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue))) {
31978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
31988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
31998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (cond_expr_t *) 1;	/* any non-NULL value */
32018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
32028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
32038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* create a new expression struct */
32048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	expr = malloc(sizeof(struct cond_expr));
32058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!expr) {
32068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
32078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return NULL;
32088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
32098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(expr, 0, sizeof(cond_expr_t));
32108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	expr->expr_type = expr_type;
32118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
32128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* create the type asked for */
32138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	switch (expr_type) {
32148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case COND_NOT:
32158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1 = NULL;
32168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e2 = (struct cond_expr *)arg1;
32178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while (e2) {
32188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e1 = e2;
32198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e2 = e2->next;
32208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!e1 || e1->next) {
32228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("illegal conditional NOT expression");
32238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(expr);
32248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return NULL;
32258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1->next = expr;
32278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (struct cond_expr *)arg1;
32288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case COND_AND:
32298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case COND_OR:
32308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case COND_XOR:
32318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case COND_EQ:
32328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case COND_NEQ:
32338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1 = NULL;
32348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e2 = (struct cond_expr *)arg1;
32358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while (e2) {
32368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e1 = e2;
32378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e2 = e2->next;
32388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!e1 || e1->next) {
32408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror
32418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    ("illegal left side of conditional binary op expression");
32428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(expr);
32438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return NULL;
32448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1->next = (struct cond_expr *)arg2;
32468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
32478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1 = NULL;
32488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e2 = (struct cond_expr *)arg2;
32498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while (e2) {
32508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e1 = e2;
32518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			e2 = e2->next;
32528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!e1 || e1->next) {
32548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror
32558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    ("illegal right side of conditional binary op expression");
32568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(expr);
32578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return NULL;
32588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		e1->next = expr;
32608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return (struct cond_expr *)arg1;
32618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	case COND_BOOL:
32628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_remove(id_queue);
32638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!id) {
32648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("bad conditional; expected boolean id");
32658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
32668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(expr);
32678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return NULL;
32688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!is_id_in_scope(SYM_BOOLS, id)) {
32708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("boolean %s is not within scope", id);
32718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
32728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(expr);
32738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return NULL;
32748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		bool_var =
32768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
32778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 table,
32788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							 (hashtab_key_t) id);
32798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!bool_var) {
32808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown boolean %s in conditional expression",
32818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 id);
32828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(expr);
32838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
32848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return NULL;
32858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
32868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		expr->bool = bool_var->s.value;
32878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
32888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return expr;
32898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	default:
32908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("illegal conditional expression");
32910d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		free(expr);
32928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return NULL;
32938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
32948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
32958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
32968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int set_user_roles(role_set_t * set, char *id)
32978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
32988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *r;
32998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int i;
33008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_node_t *node;
33018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (strcmp(id, "*") == 0) {
33038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
33048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("* is not allowed in user declarations");
33058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
33068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
33078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (strcmp(id, "~") == 0) {
33098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
33108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("~ is not allowed in user declarations");
33118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
33128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
33138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_ROLES, id)) {
33158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("role %s is not within scope", id);
33168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
33178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
33188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
33198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	r = hashtab_search(policydbp->p_roles.table, id);
33208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!r) {
33218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unknown role %s", id);
33228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
33238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
33248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
33258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* set the role and every role it dominates */
33278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ebitmap_for_each_bit(&r->dominates, node, i) {
33288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_node_get_bit(node, i))
33298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_set_bit(&set->roles, i, TRUE))
33308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto oom;
33318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
33328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
33338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
33348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      oom:
33358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	yyerror("out of memory");
33368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
33378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
33388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
33408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
33418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cat_datum_t *cdatum;
33428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int range_start, range_end, i;
33438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id_has_dot(id)) {
33458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		char *id_start = id;
33468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		char *id_end = strchr(id, '.');
33478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		*(id_end++) = '\0';
33498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
33518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							(hashtab_key_t)
33528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							id_start);
33538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cdatum) {
33548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown category %s", id_start);
33558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
33568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
33578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		range_start = cdatum->s.value - 1;
33588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
33598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							(hashtab_key_t) id_end);
33608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cdatum) {
33618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown category %s", id_end);
33628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
33638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
33648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		range_end = cdatum->s.value - 1;
33658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (range_end < range_start) {
33678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("category range is invalid");
33688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
33698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
33708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else {
33718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
33728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							(hashtab_key_t) id);
33738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cdatum) {
33748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown category %s", id);
33758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
33768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
33778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		range_start = range_end = cdatum->s.value - 1;
33788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
33798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (i = range_start; i <= range_end; i++) {
33818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
33828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			uint32_t level_value = levdatum->level->sens - 1;
33838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			policydb_index_others(NULL, policydbp, 0);
33848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("category %s can not be associated "
33858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 "with level %s",
33868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 policydbp->p_cat_val_to_name[i],
33878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 policydbp->p_sens_val_to_name[level_value]);
33888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
33898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
33908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (ebitmap_set_bit(cats, i, TRUE)) {
33918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
33928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
33938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
33948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
33958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
33978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
33988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
33998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int parse_semantic_categories(char *id, level_datum_t * levdatum,
34008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				     mls_semantic_cat_t ** cats)
34018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
34028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	cat_datum_t *cdatum;
34038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	mls_semantic_cat_t *newcat;
34048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int range_start, range_end;
34058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (id_has_dot(id)) {
34078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		char *id_start = id;
34088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		char *id_end = strchr(id, '.');
34098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		*(id_end++) = '\0';
34118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
34138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							(hashtab_key_t)
34148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							id_start);
34158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cdatum) {
34168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown category %s", id_start);
34178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
34188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
34198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		range_start = cdatum->s.value;
34208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
34228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							(hashtab_key_t) id_end);
34238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cdatum) {
34248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown category %s", id_end);
34258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
34268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
34278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		range_end = cdatum->s.value;
34288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else {
34298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
34308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android							(hashtab_key_t) id);
34318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cdatum) {
34328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown category %s", id);
34338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
34348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
34358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		range_start = range_end = cdatum->s.value;
34368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
34378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
34398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newcat) {
34408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
34418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
34428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
34438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	mls_semantic_cat_init(newcat);
34458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newcat->next = *cats;
34468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newcat->low = range_start;
34478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newcat->high = range_end;
34488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	*cats = newcat;
34508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
34528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
34538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_user(void)
34558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
34568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
34578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	user_datum_t *usrdatum;
34588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level_datum_t *levdatum;
34598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int l;
34608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
34628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
34638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
34648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (mlspol) {
34658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue)))
34668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
34678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			id = queue_remove(id_queue);
34688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
34698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			for (l = 0; l < 2; l++) {
34708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				while ((id = queue_remove(id_queue))) {
34718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					free(id);
34728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
34738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				id = queue_remove(id_queue);
34748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!id)
34758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					break;
34768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
34778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
34788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
34798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
34808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
34818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if ((usrdatum = declare_user()) == NULL) {
34838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
34848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
34858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
34878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_user_roles(&usrdatum->roles, id))
34888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			continue;
34898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
34908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (mlspol) {
34928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
34938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!id) {
34948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("no default level specified for user");
34958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
34968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
34978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
34988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		levdatum = (level_datum_t *)
34998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    hashtab_search(policydbp->p_levels.table,
35008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				   (hashtab_key_t) id);
35018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!levdatum) {
35028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown sensitivity %s used in user"
35038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 " level definition", id);
35048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
35058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
35068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
35078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
35088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		usrdatum->dfltlevel.sens = levdatum->level->sens;
35108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue))) {
35128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (parse_semantic_categories(id, levdatum,
35138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			                            &usrdatum->dfltlevel.cat)) {
35148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
35158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
35168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
35178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
35188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
35198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
35218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		for (l = 0; l < 2; l++) {
35238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			levdatum = (level_datum_t *)
35248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    hashtab_search(policydbp->p_levels.table,
35258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					   (hashtab_key_t) id);
35268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!levdatum) {
35278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror2("unknown sensitivity %s used in user"
35288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					 " range definition", id);
35298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
35308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
35318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
35328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
35338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			usrdatum->range.level[l].sens = levdatum->level->sens;
35358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue))) {
35378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (parse_semantic_categories(id, levdatum,
35388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				               &usrdatum->range.level[l].cat)) {
35398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					free(id);
35408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return -1;
35418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
35428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
35438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
35448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			id = queue_remove(id_queue);
35468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!id)
35478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				break;
35488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
35498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (l == 0) {
35518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (mls_semantic_level_cpy(&usrdatum->range.level[1],
35528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			                           &usrdatum->range.level[0])) {
35538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("out of memory");
35548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
35558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
35568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
35578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
35588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
35598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
35608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidstatic int parse_security_context(context_struct_t * c)
35628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
35638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
35648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role_datum_t *role;
35658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	type_datum_t *typdatum;
35668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	user_datum_t *usrdatum;
35678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level_datum_t *levdatum;
35688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int l;
35698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
35718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
35728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);	/* user  */
35738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
35748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);	/* role  */
35758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
35768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);	/* type  */
35778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (mlspol) {
35788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			id = queue_remove(id_queue);
35798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
35808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			for (l = 0; l < 2; l++) {
35818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				while ((id = queue_remove(id_queue))) {
35828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					free(id);
35838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
35848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				id = queue_remove(id_queue);
35858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (!id)
35868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					break;
35878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
35888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
35898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
35908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
35918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
35928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
35930d73ef7049feee794f14cf1af88d05dae8139914Alice Chu	/* check context c to make sure ok to dereference c later */
35940d73ef7049feee794f14cf1af88d05dae8139914Alice Chu	if (c == NULL) {
35950d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		yyerror("null context pointer!");
35960d73ef7049feee794f14cf1af88d05dae8139914Alice Chu		return -1;
35970d73ef7049feee794f14cf1af88d05dae8139914Alice Chu	}
35980d73ef7049feee794f14cf1af88d05dae8139914Alice Chu
35998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	context_init(c);
36008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* extract the user */
36028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = queue_remove(id_queue);
36038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
36048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no effective user?");
36058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
36068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_USERS, id)) {
36088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("user %s is not within scope", id);
36098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
36108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
36118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
36138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						   (hashtab_key_t) id);
36148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!usrdatum) {
36158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("user %s is not defined", id);
36168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
36178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
36188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	c->user = usrdatum->s.value;
36208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* no need to keep the user name */
36228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
36238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* extract the role */
36258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
36268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
36278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no role name for sid context definition?");
36288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
36298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_ROLES, id)) {
36318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("role %s is not within scope", id);
36328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
36338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
36348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
36368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					       (hashtab_key_t) id);
36378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!role) {
36388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("role %s is not defined", id);
36398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
36408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
36418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	c->role = role->s.value;
36438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* no need to keep the role name */
36458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
36468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* extract the type */
36488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
36498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
36508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no type name for sid context definition?");
36518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
36528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!is_id_in_scope(SYM_TYPES, id)) {
36548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not within scope", id);
36558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
36568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
36578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
36598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						   (hashtab_key_t) id);
36608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
36618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("type %s is not defined or is an attribute", id);
36628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
36638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
36648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
36658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	c->type = typdatum->s.value;
36668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* no need to keep the type name */
36688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
36698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (mlspol) {
36718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		/* extract the low sensitivity */
36728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_head(id_queue);
36738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!id) {
36748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("no sensitivity name for sid context"
36758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				" definition?");
36768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
36778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
36788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_remove(id_queue);
36808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		for (l = 0; l < 2; l++) {
36818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			levdatum = (level_datum_t *)
36828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			    hashtab_search(policydbp->p_levels.table,
36838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					   (hashtab_key_t) id);
36848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!levdatum) {
36858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror2("Sensitivity %s is not defined", id);
36868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
36878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				return -1;
36888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
36898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
36908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			c->range.level[l].sens = levdatum->level->sens;
36918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
36928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/* extract low category set */
36938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue))) {
36948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				if (parse_categories(id, levdatum,
36958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android						     &c->range.level[l].cat)) {
36968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					free(id);
36978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					return -1;
36988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				}
36998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
37008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
37018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			/* extract high sensitivity */
37038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			id = (char *)queue_remove(id_queue);
37048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!id)
37058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				break;
37068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
37078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (l == 0) {
37098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			c->range.level[1].sens = c->range.level[0].sens;
37108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (ebitmap_cpy(&c->range.level[1].cat,
37118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android					&c->range.level[0].cat)) {
37128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				yyerror("out of memory");
37148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto bad;
37158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
37168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
37178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!policydb_context_isvalid(policydbp, c)) {
37208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("invalid security context");
37218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto bad;
37228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
37248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
37268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	context_destroy(c);
37278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
37298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
37308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_initial_sid_context(void)
37328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
37338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
37348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *c, *head;
37358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
37378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_remove(id_queue);
37388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
37398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
37408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
37418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
37448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
37458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no sid name for SID context definition?");
37468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
37478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_ISID];
37498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (c = head; c; c = c->next) {
37508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!strcmp(id, c->u.name))
37518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
37528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!c) {
37558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("SID %s is not defined", id);
37568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
37578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
37588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (c->context[0].user) {
37608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("The context for SID %s is multiply defined", id);
37618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
37628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
37638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* no need to keep the sid name */
37658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
37668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&c->context[0]))
37688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
37698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
37718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
37728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_fs_context(unsigned int major, unsigned int minor)
37748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
37758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *head;
37768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
37788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("fscon not supported for target");
37798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
37808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
37838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
37848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
37858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
37868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
37898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
37908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
37918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
37928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
37938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
37948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
37958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.name = (char *)malloc(6);
37968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc->u.name) {
37978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
37988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
37998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
38008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	sprintf(newc->u.name, "%02x:%02x", major, minor);
38028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
38048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc->u.name);
38058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
38068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
38078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[1])) {
38098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		context_destroy(&newc->context[0]);
38108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc->u.name);
38118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
38128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
38138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_FS];
38158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (c = head; c; c = c->next) {
38178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!strcmp(newc->u.name, c->u.name)) {
38188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate entry for file system %s",
38198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 newc->u.name);
38208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			context_destroy(&newc->context[0]);
38218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			context_destroy(&newc->context[1]);
38228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(newc->u.name);
38238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(newc);
38248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
38258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
38268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->next = head;
38298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	policydbp->ocontexts[OCON_FS] = newc;
38308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
38328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
38338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_pirq_context(unsigned int pirq)
38358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
38368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *l, *head;
38378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
38388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
38408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("pirqcon not supported for target");
38418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
38428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
38458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *) queue_remove(id_queue);
38468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
38478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
38488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
38498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = malloc(sizeof(ocontext_t));
38528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
38538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
38548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
38558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
38578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.pirq = pirq;
38598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
38618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
38628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
38638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_XEN_PIRQ];
38668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (l = NULL, c = head; c; l = c, c = c->next) {
38678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		unsigned int pirq2;
38688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		pirq2 = c->u.pirq;
38708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (pirq == pirq2) {
38718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate pirqcon entry for %d ", pirq);
38728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
38738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
38748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (l)
38778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l->next = newc;
38788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
38798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
38808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
38828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidbad:
38848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(newc);
38858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
38868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
38878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_iomem_context(unsigned long low, unsigned long high)
38898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
38908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *l, *head;
38918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
38928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
38948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("iomemcon not supported for target");
38958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
38968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
38978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
38988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
38998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_remove(id_queue);
39008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
39018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
39028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
39038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = malloc(sizeof(ocontext_t));
39068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
39078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
39088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
39098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
39118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.iomem.low_iomem  = low;
39138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.iomem.high_iomem = high;
39148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (low > high) {
39168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high);
39178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
39188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
39198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
39228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
39238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
39248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_XEN_IOMEM];
39278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (l = NULL, c = head; c; l = c, c = c->next) {
39288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		unsigned int low2, high2;
39298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		low2 = c->u.iomem.low_iomem;
39318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		high2 = c->u.iomem.high_iomem;
39328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (low <= high2 && low2 <= high) {
39338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("iomemcon entry for 0x%x-0x%x overlaps with "
39348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				"earlier entry 0x%x-0x%x", low, high,
39358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				low2, high2);
39368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
39378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
39388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (l)
39418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l->next = newc;
39428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
39438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
39448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
39468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidbad:
39488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(newc);
39498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
39508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
39518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_ioport_context(unsigned long low, unsigned long high)
39538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
39548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *l, *head;
39558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
39568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
39588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("ioportcon not supported for target");
39598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
39608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
39638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_remove(id_queue);
39648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
39658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
39668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
39678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = malloc(sizeof(ocontext_t));
39708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
39718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
39728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
39738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
39758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.ioport.low_ioport  = low;
39778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.ioport.high_ioport = high;
39788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (low > high) {
39808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high);
39818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
39828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
39838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
39868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
39878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
39888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
39898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_XEN_IOPORT];
39918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (l = NULL, c = head; c; l = c, c = c->next) {
39928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		unsigned int low2, high2;
39938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
39948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		low2 = c->u.ioport.low_ioport;
39958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		high2 = c->u.ioport.high_ioport;
39968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (low <= high2 && low2 <= high) {
39978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("ioportcon entry for 0x%x-0x%x overlaps with"
39988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				"earlier entry 0x%x-0x%x", low, high,
39998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				low2, high2);
40008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
40018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
40028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (l)
40058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l->next = newc;
40068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
40078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
40088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
40108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidbad:
40128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(newc);
40138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
40148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
40158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_pcidevice_context(unsigned long device)
40178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
40188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *l, *head;
40198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
40208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
40228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("pcidevicecon not supported for target");
40238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
40248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
40278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *) queue_remove(id_queue);
40288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
40298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
40308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
40318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = malloc(sizeof(ocontext_t));
40348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
40358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
40368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
40378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
40398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.device = device;
40418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
40438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
40448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
40458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
40488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (l = NULL, c = head; c; l = c, c = c->next) {
40498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		unsigned int device2;
40508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		device2 = c->u.device;
40528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (device == device2) {
40538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate pcidevicecon entry for 0x%x ",
40548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 device);
40558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
40568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
40578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (l)
40608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l->next = newc;
40618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
40628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
40638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
40658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidbad:
40678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(newc);
40688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
40698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
40708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_port_context(unsigned int low, unsigned int high)
40728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
40738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *l, *head;
40748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	unsigned int protocol;
40758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
40768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
40788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("portcon not supported for target");
40798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
40808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
40838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_remove(id_queue);
40848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
40858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
40868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
40878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = malloc(sizeof(ocontext_t));
40908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
40918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
40928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
40938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
40948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
40958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
40968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
40978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
40988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
40998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
41028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		protocol = IPPROTO_TCP;
41038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
41048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		protocol = IPPROTO_UDP;
41058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else {
41068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("unrecognized protocol %s", id);
41078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
41088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.port.protocol = protocol;
41128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.port.low_port = low;
41138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.port.high_port = high;
41148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (low > high) {
41168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror2("low port %d exceeds high port %d", low, high);
41178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
41188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
41228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
41238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Preserve the matching order specified in the configuration. */
41278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_PORT];
41288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (l = NULL, c = head; c; l = c, c = c->next) {
41298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		unsigned int prot2, low2, high2;
41308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		prot2 = c->u.port.protocol;
41328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		low2 = c->u.port.low_port;
41338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		high2 = c->u.port.high_port;
41348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (protocol != prot2)
41358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			continue;
41368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (low == low2 && high == high2) {
41378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate portcon entry for %s %d-%d ", id,
41388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 low, high);
41398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
41408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
41418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (low2 <= low && high2 >= high) {
41428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("portcon entry for %s %d-%d hidden by earlier "
41438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 "entry for %d-%d", id, low, high, low2, high2);
41448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto bad;
41458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
41468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (l)
41498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l->next = newc;
41508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
41518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		policydbp->ocontexts[OCON_PORT] = newc;
41528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
41548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      bad:
41568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(newc);
41578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
41588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
41598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_netif_context(void)
41618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
41628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *head;
41638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
41658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("netifcon not supported for target");
41668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
41708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
41718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
41728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
41738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
41748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
41778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
41788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
41798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
41828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
41838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.name = (char *)queue_remove(id_queue);
41848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc->u.name) {
41858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
41868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
41898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc->u.name);
41908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
41918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[1])) {
41948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		context_destroy(&newc->context[0]);
41958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc->u.name);
41968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
41978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
41988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
41998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_NETIF];
42008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (c = head; c; c = c->next) {
42028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!strcmp(newc->u.name, c->u.name)) {
42038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate entry for network interface %s",
42048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 newc->u.name);
42058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			context_destroy(&newc->context[0]);
42068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			context_destroy(&newc->context[1]);
42078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(newc->u.name);
42088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(newc);
42098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
42108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
42118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->next = head;
42148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	policydbp->ocontexts[OCON_NETIF] = newc;
42158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
42168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
42178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_ipv4_node_context()
42198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
42208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
42218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int rc = 0;
42228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct in_addr addr, mask;
42238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *l, *head;
42248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
42268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("nodecon not supported for target");
42278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
42288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
42318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
42328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
42338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
42348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
42358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = queue_remove(id_queue);
42388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
42398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("failed to read ipv4 address");
42408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
42418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
42428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rc = inet_pton(AF_INET, id, &addr);
42458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
42468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (rc < 1) {
42478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("failed to parse ipv4 address");
42488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (rc == 0)
42498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			rc = -1;
42508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
42518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = queue_remove(id_queue);
42548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
42558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("failed to read ipv4 address");
42568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
42578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
42588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rc = inet_pton(AF_INET, id, &mask);
42618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
42628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (rc < 1) {
42638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("failed to parse ipv4 mask");
42648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (rc == 0)
42658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			rc = -1;
42668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
42678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = malloc(sizeof(ocontext_t));
42708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
42718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
42728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
42738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
42748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
42778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.node.addr = addr.s_addr;
42788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.node.mask = mask.s_addr;
42798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
42818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
42828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
42838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Create order of most specific to least retaining
42868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	   the order specified in the configuration. */
42878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_NODE];
42888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (l = NULL, c = head; c; l = c, c = c->next) {
42898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (newc->u.node.mask > c->u.node.mask)
42908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
42918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
42928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->next = c;
42948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
42958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (l)
42968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l->next = newc;
42978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
42988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		policydbp->ocontexts[OCON_NODE] = newc;
42998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rc = 0;
43008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidout:
43018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return rc;
43028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
43038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_ipv6_node_context(void)
43058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
43068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
43078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int rc = 0;
43088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct in6_addr addr, mask;
43098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *l, *head;
43108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
43128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("nodecon not supported for target");
43138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
43148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
43178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
43188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
43198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
43208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
43218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = queue_remove(id_queue);
43248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
43258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("failed to read ipv6 address");
43268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
43278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
43288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rc = inet_pton(AF_INET6, id, &addr);
43318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
43328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (rc < 1) {
43338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("failed to parse ipv6 address");
43348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (rc == 0)
43358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			rc = -1;
43368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
43378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = queue_remove(id_queue);
43408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
43418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("failed to read ipv6 address");
43428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
43438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
43448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rc = inet_pton(AF_INET6, id, &mask);
43478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(id);
43488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (rc < 1) {
43498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("failed to parse ipv6 mask");
43508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (rc == 0)
43518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			rc = -1;
43528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
43538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = malloc(sizeof(ocontext_t));
43568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
43578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
43588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
43598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
43608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
43633fab9cdeebb5bd40681a59f9f3f3406ff600cfebStephen Smalley
43643fab9cdeebb5bd40681a59f9f3f3406ff600cfebStephen Smalley#ifdef DARWIN
43653fab9cdeebb5bd40681a59f9f3f3406ff600cfebStephen Smalley	memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
43663fab9cdeebb5bd40681a59f9f3f3406ff600cfebStephen Smalley	memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
43673fab9cdeebb5bd40681a59f9f3f3406ff600cfebStephen Smalley#else
43688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
43698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
43703fab9cdeebb5bd40681a59f9f3f3406ff600cfebStephen Smalley#endif
43718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
43738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
43748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rc = -1;
43758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
43768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	/* Create order of most specific to least retaining
43798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	   the order specified in the configuration. */
43808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_NODE6];
43818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (l = NULL, c = head; c; l = c, c = c->next) {
43828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
43838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
43848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
43858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->next = c;
43878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (l)
43898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		l->next = newc;
43908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
43918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		policydbp->ocontexts[OCON_NODE6] = newc;
43928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rc = 0;
43948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      out:
43958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return rc;
43968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
43978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
43988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_fs_use(int behavior)
43998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
44008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *head;
44018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
44038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("fsuse not supported for target");
44048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
44058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
44088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
44098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
44108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
44118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
44148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
44158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
44168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
44178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
44198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.name = (char *)queue_remove(id_queue);
44218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc->u.name) {
44228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
44238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
44248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->v.behavior = behavior;
44268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0])) {
44278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc->u.name);
44288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc);
44298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
44308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = policydbp->ocontexts[OCON_FSUSE];
44338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (c = head; c; c = c->next) {
44358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!strcmp(newc->u.name, c->u.name)) {
44368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate fs_use entry for filesystem type %s",
44378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 newc->u.name);
44388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			context_destroy(&newc->context[0]);
44398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(newc->u.name);
44408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(newc);
44418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
44428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
44438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->next = head;
44468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	policydbp->ocontexts[OCON_FSUSE] = newc;
44478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
44488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
44498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_genfs_context_helper(char *fstype, int has_type)
44518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
44528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	struct genfs *genfs_p, *genfs, *newgenfs;
44538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	ocontext_t *newc, *c, *head, *p;
44548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *type = NULL;
44558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int len, len2;
44568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
44588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("genfs not supported for target");
44598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
44608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
44638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(fstype);
44648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(queue_remove(id_queue));
44658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (has_type)
44668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(queue_remove(id_queue));
44678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		parse_security_context(NULL);
44688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
44698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (genfs_p = NULL, genfs = policydbp->genfs;
44728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	     genfs; genfs_p = genfs, genfs = genfs->next) {
44738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (strcmp(fstype, genfs->fstype) <= 0)
44748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
44758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!genfs || strcmp(fstype, genfs->fstype)) {
44788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newgenfs = malloc(sizeof(struct genfs));
44798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!newgenfs) {
44808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
44818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			return -1;
44828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
44838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		memset(newgenfs, 0, sizeof(struct genfs));
44848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newgenfs->fstype = fstype;
44858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		newgenfs->next = genfs;
44868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (genfs_p)
44878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			genfs_p->next = newgenfs;
44888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		else
44898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			policydbp->genfs = newgenfs;
44908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		genfs = newgenfs;
44918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
44938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
44948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc) {
44958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
44968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
44978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
44988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	memset(newc, 0, sizeof(ocontext_t));
44998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
45008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->u.name = (char *)queue_remove(id_queue);
45018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!newc->u.name)
45028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto fail;
45038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (has_type) {
45048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		type = (char *)queue_remove(id_queue);
45058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!type)
45068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto fail;
45078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (type[1] != 0) {
45088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("invalid type %s", type);
45098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto fail;
45108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
45118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		switch (type[0]) {
45128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 'b':
45138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			newc->v.sclass = SECCLASS_BLK_FILE;
45148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
45158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 'c':
45168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			newc->v.sclass = SECCLASS_CHR_FILE;
45178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
45188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 'd':
45198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			newc->v.sclass = SECCLASS_DIR;
45208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
45218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 'p':
45228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			newc->v.sclass = SECCLASS_FIFO_FILE;
45238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
45248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 'l':
45258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			newc->v.sclass = SECCLASS_LNK_FILE;
45268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
45278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case 's':
45288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			newc->v.sclass = SECCLASS_SOCK_FILE;
45298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
45308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		case '-':
45318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			newc->v.sclass = SECCLASS_FILE;
45328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
45338c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		default:
45348c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("invalid type %s", type);
45358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto fail;
45368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
45378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
45388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (parse_security_context(&newc->context[0]))
45398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto fail;
45408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
45418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	head = genfs->head;
45428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
45438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (p = NULL, c = head; c; p = c, c = c->next) {
45448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!strcmp(newc->u.name, c->u.name) &&
45458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		    (!newc->v.sclass || !c->v.sclass
45468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		     || newc->v.sclass == c->v.sclass)) {
45478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("duplicate entry for genfs entry (%s, %s)",
45488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				 fstype, newc->u.name);
45498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto fail;
45508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
45518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		len = strlen(newc->u.name);
45528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		len2 = strlen(c->u.name);
45538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (len > len2)
45548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
45558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
45568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
45578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	newc->next = c;
45588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (p)
45598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		p->next = newc;
45608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	else
45618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		genfs->head = newc;
45628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
45638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android      fail:
45648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (type)
45658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(type);
45668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	context_destroy(&newc->context[0]);
45678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (fstype)
45688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(fstype);
45698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (newc->u.name)
45708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(newc->u.name);
45718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	free(newc);
45728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
45738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
45748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
45758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_genfs_context(int has_type)
45768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
45778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return define_genfs_context_helper(queue_remove(id_queue), has_type);
45788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
45798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
45808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidint define_range_trans(int class_specified)
45818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android{
45828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	char *id;
45838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	level_datum_t *levdatum = 0;
45848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	class_datum_t *cladatum;
45858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	range_trans_rule_t *rule;
45868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	int l, add = 1;
45878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
45888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!mlspol) {
45898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("range_transition rule in non-MLS configuration");
45908c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
45918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
45928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
45938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (pass == 1) {
45948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
45958c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
45968c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue)))
45978c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
45988c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (class_specified)
45998c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue)))
46008c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
46018c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = queue_remove(id_queue);
46028c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
46038c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		for (l = 0; l < 2; l++) {
46048c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			while ((id = queue_remove(id_queue))) {
46058c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
46068c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
46078c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			id = queue_remove(id_queue);
46088c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (!id)
46098c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				break;
46108c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
46118c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
46128c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return 0;
46138c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
46148c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46158c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	rule = malloc(sizeof(struct range_trans_rule));
46168c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!rule) {
46178c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("out of memory");
46188c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		return -1;
46198c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
46208c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	range_trans_rule_init(rule);
46218c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46228c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
46238c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types(&rule->stypes, id, &add, 0))
46248c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto out;
46258c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
46268c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	add = 1;
46278c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	while ((id = queue_remove(id_queue))) {
46288c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (set_types(&rule->ttypes, id, &add, 0))
46298c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto out;
46308c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
46318c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46328c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (class_specified) {
4633cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley		if (read_classes(&rule->tclasses))
4634cd88c5c44f93ca14828bdae024fae6e0287ba71dStephen Smalley			goto out;
46358c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	} else {
46368c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		cladatum = hashtab_search(policydbp->p_classes.table,
46378c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		                          "process");
46388c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!cladatum) {
46398c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("could not find process class for "
46408c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			         "legacy range_transition statement");
46418c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto out;
46428c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
46438c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46448c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
46458c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
46468c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46478c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	id = (char *)queue_remove(id_queue);
46488c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (!id) {
46498c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		yyerror("no range in range_transition definition?");
46508c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		goto out;
46518c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
46528c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	for (l = 0; l < 2; l++) {
46538c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		levdatum = hashtab_search(policydbp->p_levels.table, id);
46548c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!levdatum) {
46558c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror2("unknown level %s used in range_transition "
46568c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			         "definition", id);
46578c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
46588c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto out;
46598c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
46608c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		free(id);
46618c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46628c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		rule->trange.level[l].sens = levdatum->level->sens;
46638c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46648c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		while ((id = queue_remove(id_queue))) {
46658c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			if (parse_semantic_categories(id, levdatum,
46668c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			                          &rule->trange.level[l].cat)) {
46678c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				free(id);
46688c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android				goto out;
46698c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			}
46708c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			free(id);
46718c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
46728c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46738c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		id = (char *)queue_remove(id_queue);
46748c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (!id)
46758c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			break;
46768c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
46778c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	if (l == 0) {
46788c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		if (mls_semantic_level_cpy(&rule->trange.level[1],
46798c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		                           &rule->trange.level[0])) {
46808c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			yyerror("out of memory");
46818c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android			goto out;
46828c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android		}
46838c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	}
46848c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46858c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	append_range_trans(rule);
46868c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return 0;
46878c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46888c48de15b1afeb1cd01a753195a29b1a7811dbfSE Androidout:
46898c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	range_trans_rule_destroy(rule);
46900d73ef7049feee794f14cf1af88d05dae8139914Alice Chu	free(rule);
46918c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android	return -1;
46928c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android}
46938c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android
46948c48de15b1afeb1cd01a753195a29b1a7811dbfSE Android/* FLASK */
4695