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