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