policy_define.c revision 09c783c9a36cd47216df827c5d2c21ec8cd613e2
1ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/*
2ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
3ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue */
4ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
5ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/*
6ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
7ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *
8ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *	Support for enhanced MLS infrastructure.
9ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *
10ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Updated: David Caplan, <dac@tresys.com>
11ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *
12ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * 	Added conditional policy language extensions
13ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *
14ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Updated: Joshua Brindle <jbrindle@tresys.com>
15ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *	    Karl MacMillan <kmacmillan@mentalrootkit.com>
16ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *          Jason Tang     <jtang@tresys.com>
17ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *
18ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *	Added support for binary policy modules
19ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *
20ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
21ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Copyright (C) 2003 - 2008 Tresys Technology, LLC
22ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Copyright (C) 2007 Red Hat Inc.
23ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *	This program is free software; you can redistribute it and/or modify
24ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *  	it under the terms of the GNU General Public License as published by
25ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue *	the Free Software Foundation, version 2.
26ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue */
27ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
28ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/* FLASK */
29ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
30ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sys/types.h>
31ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <assert.h>
32ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdarg.h>
33ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdint.h>
34ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdio.h>
35ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdlib.h>
36ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <string.h>
37ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sys/socket.h>
38ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <netinet/in.h>
39ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <arpa/inet.h>
40ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdlib.h>
41ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
42ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/expand.h>
43ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/policydb.h>
44ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/services.h>
45ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/conditional.h>
46ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/flask.h>
47ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/hierarchy.h>
48ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/polcaps.h>
49ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include "queue.h"
50ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include "checkpolicy.h"
51ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include "module_compiler.h"
52ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include "policy_define.h"
53ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
54ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuepolicydb_t *policydbp;
55ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuequeue_t id_queue = 0;
56ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueunsigned int pass;
57ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuechar *curfile = 0;
58ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueint mlspol = 0;
59ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
60ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern unsigned long policydb_lineno;
61ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern unsigned long source_lineno;
62ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern unsigned int policydb_errors;
63ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
64ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern int yywarn(char *msg);
65ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern int yyerror(char *msg);
66ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
67ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#define ERRORMSG_LEN 255
68ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuestatic char errormsg[ERRORMSG_LEN + 1] = {0};
69ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
70ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuestatic int id_has_dot(char *id);
71ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuestatic int parse_security_context(context_struct_t *c);
72ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
73ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/* initialize all of the state variables for the scanner/parser */
74ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuevoid init_parser(int pass_number)
75ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{
76ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	policydb_lineno = 1;
77ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	source_lineno = 1;
78ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	policydb_errors = 0;
79ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	pass = pass_number;
80ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue}
81ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
82ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuevoid yyerror2(char *fmt, ...)
83ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{
84ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	va_list ap;
85ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	va_start(ap, fmt);
86ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
87ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	yyerror(errormsg);
88ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	va_end(ap);
89ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue}
90ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
91ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueint insert_separator(int push)
92ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{
93ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	int error;
94ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
95ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (push)
96ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		error = queue_push(id_queue, 0);
97ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	else
98ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		error = queue_insert(id_queue, 0);
99ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
100ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (error) {
101ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		yyerror("queue overflow");
102ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		return -1;
103ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	}
104ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	return 0;
105ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue}
106ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
107ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueint insert_id(char *id, int push)
108ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{
109ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	char *newid = 0;
110ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	int error;
111ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
112ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	newid = (char *)malloc(strlen(id) + 1);
113ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (!newid) {
114ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		yyerror("out of memory");
115ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		return -1;
116ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	}
117ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	strcpy(newid, id);
118ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (push)
119ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		error = queue_push(id_queue, (queue_element_t) newid);
120ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	else
121ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		error = queue_insert(id_queue, (queue_element_t) newid);
122ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
123ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (error) {
124ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		yyerror("queue overflow");
125ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		free(newid);
126ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		return -1;
127ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	}
128ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	return 0;
129ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue}
130ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
131ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/* If the identifier has a dot within it and that its first character
132ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue   is not a dot then return 1, else return 0. */
133ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuestatic int id_has_dot(char *id)
134ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{
135ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (strchr(id, '.') >= id + 1) {
136ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		return 1;
137ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	}
138ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	return 0;
139ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue}
140ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
141ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueint define_class(void)
142ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{
143ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	char *id = 0;
144ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	class_datum_t *datum = 0;
145ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	int ret;
146ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	uint32_t value;
147ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
148ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (pass == 2) {
149ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		id = queue_remove(id_queue);
150ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		free(id);
151ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		return 0;
152ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	}
153ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue
154ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	id = (char *)queue_remove(id_queue);
155ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (!id) {
156ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		yyerror("no class name for class definition?");
157ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		return -1;
158ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	}
159ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	datum = (class_datum_t *) malloc(sizeof(class_datum_t));
160ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	if (!datum) {
161ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		yyerror("out of memory");
162ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		goto bad;
163ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	}
164ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	memset(datum, 0, sizeof(class_datum_t));
165ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
166ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	switch (ret) {
167ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	case -3:{
168ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue			yyerror("Out of memory!");
169ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue			goto bad;
170ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue		}
171ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue	case -2:{
172ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue			yyerror2("duplicate declaration of class %s", id);
173			goto bad;
174		}
175	case -1:{
176			yyerror("could not declare class here");
177			goto bad;
178		}
179	case 0:
180	case 1:{
181			break;
182		}
183	default:{
184			assert(0);	/* should never get here */
185		}
186	}
187	datum->s.value = value;
188	return 0;
189
190      bad:
191	if (id)
192		free(id);
193	if (datum)
194		free(datum);
195	return -1;
196}
197
198int define_permissive(void)
199{
200	char *type = NULL;
201	struct type_datum *t;
202	int rc = 0;
203
204	type = queue_remove(id_queue);
205
206	if (!type) {
207		yyerror2("forgot to include type in permissive definition?");
208		rc = -1;
209		goto out;
210	}
211
212	if (pass == 1)
213		goto out;
214
215	if (!is_id_in_scope(SYM_TYPES, type)) {
216		yyerror2("type %s is not within scope", type);
217		rc = -1;
218		goto out;
219	}
220
221	t = hashtab_search(policydbp->p_types.table, type);
222	if (!t) {
223		yyerror2("type is not defined: %s", type);
224		rc = -1;
225		goto out;
226	}
227
228	if (t->flavor == TYPE_ATTRIB) {
229		yyerror2("attributes may not be permissive: %s\n", type);
230		rc = -1;
231		goto out;
232	}
233
234	t->flags |= TYPE_FLAGS_PERMISSIVE;
235
236out:
237	free(type);
238	return rc;
239}
240
241int define_polcap(void)
242{
243	char *id = 0;
244	int capnum;
245
246	if (pass == 2) {
247		id = queue_remove(id_queue);
248		free(id);
249		return 0;
250	}
251
252	id = (char *)queue_remove(id_queue);
253	if (!id) {
254		yyerror("no capability name for policycap definition?");
255		goto bad;
256	}
257
258	/* Check for valid cap name -> number mapping */
259	capnum = sepol_polcap_getnum(id);
260	if (capnum < 0) {
261		yyerror2("invalid policy capability name %s", id);
262		goto bad;
263	}
264
265	/* Store it */
266	if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
267		yyerror("out of memory");
268		goto bad;
269	}
270
271	free(id);
272	return 0;
273
274      bad:
275	free(id);
276	return -1;
277}
278
279int define_initial_sid(void)
280{
281	char *id = 0;
282	ocontext_t *newc = 0, *c, *head;
283
284	if (pass == 2) {
285		id = queue_remove(id_queue);
286		free(id);
287		return 0;
288	}
289
290	id = (char *)queue_remove(id_queue);
291	if (!id) {
292		yyerror("no sid name for SID definition?");
293		return -1;
294	}
295	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
296	if (!newc) {
297		yyerror("out of memory");
298		goto bad;
299	}
300	memset(newc, 0, sizeof(ocontext_t));
301	newc->u.name = id;
302	context_init(&newc->context[0]);
303	head = policydbp->ocontexts[OCON_ISID];
304
305	for (c = head; c; c = c->next) {
306		if (!strcmp(newc->u.name, c->u.name)) {
307			yyerror2("duplicate initial SID %s", id);
308			goto bad;
309		}
310	}
311
312	if (head) {
313		newc->sid[0] = head->sid[0] + 1;
314	} else {
315		newc->sid[0] = 1;
316	}
317	newc->next = head;
318	policydbp->ocontexts[OCON_ISID] = newc;
319
320	return 0;
321
322      bad:
323	if (id)
324		free(id);
325	if (newc)
326		free(newc);
327	return -1;
328}
329
330static int read_classes(ebitmap_t *e_classes)
331{
332	char *id;
333	class_datum_t *cladatum;
334
335	while ((id = queue_remove(id_queue))) {
336		if (!is_id_in_scope(SYM_CLASSES, id)) {
337			yyerror2("class %s is not within scope", id);
338			return -1;
339		}
340		cladatum = hashtab_search(policydbp->p_classes.table, id);
341		if (!cladatum) {
342			yyerror2("unknown class %s", id);
343			return -1;
344		}
345		if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) {
346			yyerror("Out of memory");
347			return -1;
348		}
349		free(id);
350	}
351	return 0;
352}
353
354int define_default_user(int which)
355{
356	char *id;
357	class_datum_t *cladatum;
358
359	if (pass == 1) {
360		while ((id = queue_remove(id_queue)))
361			free(id);
362		return 0;
363	}
364
365	while ((id = queue_remove(id_queue))) {
366		if (!is_id_in_scope(SYM_CLASSES, id)) {
367			yyerror2("class %s is not within scope", id);
368			return -1;
369		}
370		cladatum = hashtab_search(policydbp->p_classes.table, id);
371		if (!cladatum) {
372			yyerror2("unknown class %s", id);
373			return -1;
374		}
375		if (cladatum->default_user && cladatum->default_user != which) {
376			yyerror2("conflicting default user information for class %s", id);
377			return -1;
378		}
379		cladatum->default_user = which;
380		free(id);
381	}
382
383	return 0;
384}
385
386int define_default_role(int which)
387{
388	char *id;
389	class_datum_t *cladatum;
390
391	if (pass == 1) {
392		while ((id = queue_remove(id_queue)))
393			free(id);
394		return 0;
395	}
396
397	while ((id = queue_remove(id_queue))) {
398		if (!is_id_in_scope(SYM_CLASSES, id)) {
399			yyerror2("class %s is not within scope", id);
400			return -1;
401		}
402		cladatum = hashtab_search(policydbp->p_classes.table, id);
403		if (!cladatum) {
404			yyerror2("unknown class %s", id);
405			return -1;
406		}
407		if (cladatum->default_role && cladatum->default_role != which) {
408			yyerror2("conflicting default role information for class %s", id);
409			return -1;
410		}
411		cladatum->default_role = which;
412		free(id);
413	}
414
415	return 0;
416}
417
418int define_default_range(int which)
419{
420	char *id;
421	class_datum_t *cladatum;
422
423	if (pass == 1) {
424		while ((id = queue_remove(id_queue)))
425			free(id);
426		return 0;
427	}
428
429	while ((id = queue_remove(id_queue))) {
430		if (!is_id_in_scope(SYM_CLASSES, id)) {
431			yyerror2("class %s is not within scope", id);
432			return -1;
433		}
434		cladatum = hashtab_search(policydbp->p_classes.table, id);
435		if (!cladatum) {
436			yyerror2("unknown class %s", id);
437			return -1;
438		}
439		if (cladatum->default_range && cladatum->default_range != which) {
440			yyerror2("conflicting default range information for class %s", id);
441			return -1;
442		}
443		cladatum->default_range = which;
444		free(id);
445	}
446
447	return 0;
448}
449
450int define_common_perms(void)
451{
452	char *id = 0, *perm = 0;
453	common_datum_t *comdatum = 0;
454	perm_datum_t *perdatum = 0;
455	int ret;
456
457	if (pass == 2) {
458		while ((id = queue_remove(id_queue)))
459			free(id);
460		return 0;
461	}
462
463	id = (char *)queue_remove(id_queue);
464	if (!id) {
465		yyerror("no common name for common perm definition?");
466		return -1;
467	}
468	comdatum = hashtab_search(policydbp->p_commons.table, id);
469	if (comdatum) {
470		yyerror2("duplicate declaration for common %s\n", id);
471		return -1;
472	}
473	comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
474	if (!comdatum) {
475		yyerror("out of memory");
476		goto bad;
477	}
478	memset(comdatum, 0, sizeof(common_datum_t));
479	ret = hashtab_insert(policydbp->p_commons.table,
480			     (hashtab_key_t) id, (hashtab_datum_t) comdatum);
481
482	if (ret == SEPOL_EEXIST) {
483		yyerror("duplicate common definition");
484		goto bad;
485	}
486	if (ret == SEPOL_ENOMEM) {
487		yyerror("hash table overflow");
488		goto bad;
489	}
490	comdatum->s.value = policydbp->p_commons.nprim + 1;
491	if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
492		yyerror("out of memory");
493		goto bad;
494	}
495	policydbp->p_commons.nprim++;
496	while ((perm = queue_remove(id_queue))) {
497		perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
498		if (!perdatum) {
499			yyerror("out of memory");
500			goto bad_perm;
501		}
502		memset(perdatum, 0, sizeof(perm_datum_t));
503		perdatum->s.value = comdatum->permissions.nprim + 1;
504
505		if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
506			yyerror
507			    ("too many permissions to fit in an access vector");
508			goto bad_perm;
509		}
510		ret = hashtab_insert(comdatum->permissions.table,
511				     (hashtab_key_t) perm,
512				     (hashtab_datum_t) perdatum);
513
514		if (ret == SEPOL_EEXIST) {
515			yyerror2("duplicate permission %s in common %s", perm,
516				 id);
517			goto bad_perm;
518		}
519		if (ret == SEPOL_ENOMEM) {
520			yyerror("hash table overflow");
521			goto bad_perm;
522		}
523		comdatum->permissions.nprim++;
524	}
525
526	return 0;
527
528      bad:
529	if (id)
530		free(id);
531	if (comdatum)
532		free(comdatum);
533	return -1;
534
535      bad_perm:
536	if (perm)
537		free(perm);
538	if (perdatum)
539		free(perdatum);
540	return -1;
541}
542
543int define_av_perms(int inherits)
544{
545	char *id;
546	class_datum_t *cladatum;
547	common_datum_t *comdatum;
548	perm_datum_t *perdatum = 0, *perdatum2 = 0;
549	int ret;
550
551	if (pass == 2) {
552		while ((id = queue_remove(id_queue)))
553			free(id);
554		return 0;
555	}
556
557	id = (char *)queue_remove(id_queue);
558	if (!id) {
559		yyerror("no tclass name for av perm definition?");
560		return -1;
561	}
562	cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
563						    (hashtab_key_t) id);
564	if (!cladatum) {
565		yyerror2("class %s is not defined", id);
566		goto bad;
567	}
568	free(id);
569
570	if (cladatum->comdatum || cladatum->permissions.nprim) {
571		yyerror("duplicate access vector definition");
572		return -1;
573	}
574	if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
575		yyerror("out of memory");
576		return -1;
577	}
578	if (inherits) {
579		id = (char *)queue_remove(id_queue);
580		if (!id) {
581			yyerror
582			    ("no inherits name for access vector definition?");
583			return -1;
584		}
585		comdatum =
586		    (common_datum_t *) hashtab_search(policydbp->p_commons.
587						      table,
588						      (hashtab_key_t) id);
589
590		if (!comdatum) {
591			yyerror2("common %s is not defined", id);
592			goto bad;
593		}
594		cladatum->comkey = id;
595		cladatum->comdatum = comdatum;
596
597		/*
598		 * Class-specific permissions start with values
599		 * after the last common permission.
600		 */
601		cladatum->permissions.nprim += comdatum->permissions.nprim;
602	}
603	while ((id = queue_remove(id_queue))) {
604		perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
605		if (!perdatum) {
606			yyerror("out of memory");
607			goto bad;
608		}
609		memset(perdatum, 0, sizeof(perm_datum_t));
610		perdatum->s.value = ++cladatum->permissions.nprim;
611
612		if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
613			yyerror
614			    ("too many permissions to fit in an access vector");
615			goto bad;
616		}
617		if (inherits) {
618			/*
619			 * Class-specific permissions and
620			 * common permissions exist in the same
621			 * name space.
622			 */
623			perdatum2 =
624			    (perm_datum_t *) hashtab_search(cladatum->comdatum->
625							    permissions.table,
626							    (hashtab_key_t) id);
627			if (perdatum2) {
628				yyerror2("permission %s conflicts with an "
629					 "inherited permission", id);
630				goto bad;
631			}
632		}
633		ret = hashtab_insert(cladatum->permissions.table,
634				     (hashtab_key_t) id,
635				     (hashtab_datum_t) perdatum);
636
637		if (ret == SEPOL_EEXIST) {
638			yyerror2("duplicate permission %s", id);
639			goto bad;
640		}
641		if (ret == SEPOL_ENOMEM) {
642			yyerror("hash table overflow");
643			goto bad;
644		}
645		if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
646			yyerror("out of memory");
647			goto bad;
648		}
649	}
650
651	return 0;
652
653      bad:
654	if (id)
655		free(id);
656	if (perdatum)
657		free(perdatum);
658	return -1;
659}
660
661int define_sens(void)
662{
663	char *id;
664	mls_level_t *level = 0;
665	level_datum_t *datum = 0, *aliasdatum = 0;
666	int ret;
667	uint32_t value;		/* dummy variable -- its value is never used */
668
669	if (!mlspol) {
670		yyerror("sensitivity definition in non-MLS configuration");
671		return -1;
672	}
673
674	if (pass == 2) {
675		while ((id = queue_remove(id_queue)))
676			free(id);
677		return 0;
678	}
679
680	id = (char *)queue_remove(id_queue);
681	if (!id) {
682		yyerror("no sensitivity name for sensitivity definition?");
683		return -1;
684	}
685	if (id_has_dot(id)) {
686		yyerror("sensitivity identifiers may not contain periods");
687		goto bad;
688	}
689	level = (mls_level_t *) malloc(sizeof(mls_level_t));
690	if (!level) {
691		yyerror("out of memory");
692		goto bad;
693	}
694	mls_level_init(level);
695	level->sens = 0;	/* actual value set in define_dominance */
696	ebitmap_init(&level->cat);	/* actual value set in define_level */
697
698	datum = (level_datum_t *) malloc(sizeof(level_datum_t));
699	if (!datum) {
700		yyerror("out of memory");
701		goto bad;
702	}
703	level_datum_init(datum);
704	datum->isalias = FALSE;
705	datum->level = level;
706
707	ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
708	switch (ret) {
709	case -3:{
710			yyerror("Out of memory!");
711			goto bad;
712		}
713	case -2:{
714			yyerror("duplicate declaration of sensitivity level");
715			goto bad;
716		}
717	case -1:{
718			yyerror("could not declare sensitivity level here");
719			goto bad;
720		}
721	case 0:
722	case 1:{
723			break;
724		}
725	default:{
726			assert(0);	/* should never get here */
727		}
728	}
729
730	while ((id = queue_remove(id_queue))) {
731		if (id_has_dot(id)) {
732			yyerror("sensitivity aliases may not contain periods");
733			goto bad_alias;
734		}
735		aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
736		if (!aliasdatum) {
737			yyerror("out of memory");
738			goto bad_alias;
739		}
740		level_datum_init(aliasdatum);
741		aliasdatum->isalias = TRUE;
742		aliasdatum->level = level;
743
744		ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
745		switch (ret) {
746		case -3:{
747				yyerror("Out of memory!");
748				goto bad_alias;
749			}
750		case -2:{
751				yyerror
752				    ("duplicate declaration of sensitivity alias");
753				goto bad_alias;
754			}
755		case -1:{
756				yyerror
757				    ("could not declare sensitivity alias here");
758				goto bad_alias;
759			}
760		case 0:
761		case 1:{
762				break;
763			}
764		default:{
765				assert(0);	/* should never get here */
766			}
767		}
768	}
769
770	return 0;
771
772      bad:
773	if (id)
774		free(id);
775	if (level)
776		free(level);
777	if (datum) {
778		level_datum_destroy(datum);
779		free(datum);
780	}
781	return -1;
782
783      bad_alias:
784	if (id)
785		free(id);
786	if (aliasdatum) {
787		level_datum_destroy(aliasdatum);
788		free(aliasdatum);
789	}
790	return -1;
791}
792
793int define_dominance(void)
794{
795	level_datum_t *datum;
796	int order;
797	char *id;
798
799	if (!mlspol) {
800		yyerror("dominance definition in non-MLS configuration");
801		return -1;
802	}
803
804	if (pass == 2) {
805		while ((id = queue_remove(id_queue)))
806			free(id);
807		return 0;
808	}
809
810	order = 0;
811	while ((id = (char *)queue_remove(id_queue))) {
812		datum =
813		    (level_datum_t *) hashtab_search(policydbp->p_levels.table,
814						     (hashtab_key_t) id);
815		if (!datum) {
816			yyerror2("unknown sensitivity %s used in dominance "
817				 "definition", id);
818			free(id);
819			return -1;
820		}
821		if (datum->level->sens != 0) {
822			yyerror2("sensitivity %s occurs multiply in dominance "
823				 "definition", id);
824			free(id);
825			return -1;
826		}
827		datum->level->sens = ++order;
828
829		/* no need to keep sensitivity name */
830		free(id);
831	}
832
833	if (order != policydbp->p_levels.nprim) {
834		yyerror
835		    ("all sensitivities must be specified in dominance definition");
836		return -1;
837	}
838	return 0;
839}
840
841int define_category(void)
842{
843	char *id;
844	cat_datum_t *datum = 0, *aliasdatum = 0;
845	int ret;
846	uint32_t value;
847
848	if (!mlspol) {
849		yyerror("category definition in non-MLS configuration");
850		return -1;
851	}
852
853	if (pass == 2) {
854		while ((id = queue_remove(id_queue)))
855			free(id);
856		return 0;
857	}
858
859	id = (char *)queue_remove(id_queue);
860	if (!id) {
861		yyerror("no category name for category definition?");
862		return -1;
863	}
864	if (id_has_dot(id)) {
865		yyerror("category identifiers may not contain periods");
866		goto bad;
867	}
868	datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
869	if (!datum) {
870		yyerror("out of memory");
871		goto bad;
872	}
873	cat_datum_init(datum);
874	datum->isalias = FALSE;
875
876	ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
877	switch (ret) {
878	case -3:{
879			yyerror("Out of memory!");
880			goto bad;
881		}
882	case -2:{
883			yyerror("duplicate declaration of category");
884			goto bad;
885		}
886	case -1:{
887			yyerror("could not declare category here");
888			goto bad;
889		}
890	case 0:
891	case 1:{
892			break;
893		}
894	default:{
895			assert(0);	/* should never get here */
896		}
897	}
898	datum->s.value = value;
899
900	while ((id = queue_remove(id_queue))) {
901		if (id_has_dot(id)) {
902			yyerror("category aliases may not contain periods");
903			goto bad_alias;
904		}
905		aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
906		if (!aliasdatum) {
907			yyerror("out of memory");
908			goto bad_alias;
909		}
910		cat_datum_init(aliasdatum);
911		aliasdatum->isalias = TRUE;
912		aliasdatum->s.value = datum->s.value;
913
914		ret =
915		    declare_symbol(SYM_CATS, id, aliasdatum, NULL,
916				   &datum->s.value);
917		switch (ret) {
918		case -3:{
919				yyerror("Out of memory!");
920				goto bad_alias;
921			}
922		case -2:{
923				yyerror
924				    ("duplicate declaration of category aliases");
925				goto bad_alias;
926			}
927		case -1:{
928				yyerror
929				    ("could not declare category aliases here");
930				goto bad_alias;
931			}
932		case 0:
933		case 1:{
934				break;
935			}
936		default:{
937				assert(0);	/* should never get here */
938			}
939		}
940	}
941
942	return 0;
943
944      bad:
945	if (id)
946		free(id);
947	if (datum) {
948		cat_datum_destroy(datum);
949		free(datum);
950	}
951	return -1;
952
953      bad_alias:
954	if (id)
955		free(id);
956	if (aliasdatum) {
957		cat_datum_destroy(aliasdatum);
958		free(aliasdatum);
959	}
960	return -1;
961}
962
963static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
964{
965	level_datum_t *levdatum = (level_datum_t *) datum;
966	mls_level_t *level = (mls_level_t *) arg, *newlevel;
967
968	if (levdatum->level == level) {
969		levdatum->defined = 1;
970		if (!levdatum->isalias)
971			return 0;
972		newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
973		if (!newlevel)
974			return -1;
975		if (mls_level_cpy(newlevel, level)) {
976			free(newlevel);
977			return -1;
978		}
979		levdatum->level = newlevel;
980	}
981	return 0;
982}
983
984int define_level(void)
985{
986	char *id;
987	level_datum_t *levdatum;
988
989	if (!mlspol) {
990		yyerror("level definition in non-MLS configuration");
991		return -1;
992	}
993
994	if (pass == 2) {
995		while ((id = queue_remove(id_queue)))
996			free(id);
997		return 0;
998	}
999
1000	id = (char *)queue_remove(id_queue);
1001	if (!id) {
1002		yyerror("no level name for level definition?");
1003		return -1;
1004	}
1005	levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
1006						    (hashtab_key_t) id);
1007	if (!levdatum) {
1008		yyerror2("unknown sensitivity %s used in level definition", id);
1009		free(id);
1010		return -1;
1011	}
1012	if (ebitmap_length(&levdatum->level->cat)) {
1013		yyerror2("sensitivity %s used in multiple level definitions",
1014			 id);
1015		free(id);
1016		return -1;
1017	}
1018	free(id);
1019
1020	levdatum->defined = 1;
1021
1022	while ((id = queue_remove(id_queue))) {
1023		cat_datum_t *cdatum;
1024		int range_start, range_end, i;
1025
1026		if (id_has_dot(id)) {
1027			char *id_start = id;
1028			char *id_end = strchr(id, '.');
1029
1030			*(id_end++) = '\0';
1031
1032			cdatum =
1033			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
1034							   table,
1035							   (hashtab_key_t)
1036							   id_start);
1037			if (!cdatum) {
1038				yyerror2("unknown category %s", id_start);
1039				free(id);
1040				return -1;
1041			}
1042			range_start = cdatum->s.value - 1;
1043			cdatum =
1044			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
1045							   table,
1046							   (hashtab_key_t)
1047							   id_end);
1048			if (!cdatum) {
1049				yyerror2("unknown category %s", id_end);
1050				free(id);
1051				return -1;
1052			}
1053			range_end = cdatum->s.value - 1;
1054
1055			if (range_end < range_start) {
1056				yyerror2("category range is invalid");
1057				free(id);
1058				return -1;
1059			}
1060		} else {
1061			cdatum =
1062			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
1063							   table,
1064							   (hashtab_key_t) id);
1065			range_start = range_end = cdatum->s.value - 1;
1066		}
1067
1068		for (i = range_start; i <= range_end; i++) {
1069			if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
1070				yyerror("out of memory");
1071				free(id);
1072				return -1;
1073			}
1074		}
1075
1076		free(id);
1077	}
1078
1079	if (hashtab_map
1080	    (policydbp->p_levels.table, clone_level, levdatum->level)) {
1081		yyerror("out of memory");
1082		return -1;
1083	}
1084
1085	return 0;
1086}
1087
1088int define_attrib(void)
1089{
1090	if (pass == 2) {
1091		free(queue_remove(id_queue));
1092		return 0;
1093	}
1094
1095	if (declare_type(TRUE, TRUE) == NULL) {
1096		return -1;
1097	}
1098	return 0;
1099}
1100
1101static int add_aliases_to_type(type_datum_t * type)
1102{
1103	char *id;
1104	type_datum_t *aliasdatum = NULL;
1105	int ret;
1106	while ((id = queue_remove(id_queue))) {
1107		if (id_has_dot(id)) {
1108			free(id);
1109			yyerror
1110			    ("type alias identifiers may not contain periods");
1111			return -1;
1112		}
1113		aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
1114		if (!aliasdatum) {
1115			free(id);
1116			yyerror("Out of memory!");
1117			return -1;
1118		}
1119		memset(aliasdatum, 0, sizeof(type_datum_t));
1120		aliasdatum->s.value = type->s.value;
1121
1122		ret = declare_symbol(SYM_TYPES, id, aliasdatum,
1123				     NULL, &aliasdatum->s.value);
1124		switch (ret) {
1125		case -3:{
1126				yyerror("Out of memory!");
1127				goto cleanup;
1128			}
1129		case -2:{
1130				yyerror2("duplicate declaration of alias %s",
1131					 id);
1132				goto cleanup;
1133			}
1134		case -1:{
1135				yyerror("could not declare alias here");
1136				goto cleanup;
1137			}
1138		case 0:	 	break;
1139		case 1:{
1140				/* ret == 1 means the alias was required and therefore already
1141				 * has a value. Set it up as an alias with a different primary. */
1142				type_datum_destroy(aliasdatum);
1143				free(aliasdatum);
1144
1145				aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id);
1146				assert(aliasdatum);
1147
1148				aliasdatum->primary = type->s.value;
1149				aliasdatum->flavor = TYPE_ALIAS;
1150
1151				break;
1152			}
1153		default:{
1154				assert(0);	/* should never get here */
1155			}
1156		}
1157	}
1158	return 0;
1159      cleanup:
1160	free(id);
1161	type_datum_destroy(aliasdatum);
1162	free(aliasdatum);
1163	return -1;
1164}
1165
1166int define_typealias(void)
1167{
1168	char *id;
1169	type_datum_t *t;
1170
1171	if (pass == 2) {
1172		while ((id = queue_remove(id_queue)))
1173			free(id);
1174		return 0;
1175	}
1176
1177	id = (char *)queue_remove(id_queue);
1178	if (!id) {
1179		yyerror("no type name for typealias definition?");
1180		return -1;
1181	}
1182
1183	if (!is_id_in_scope(SYM_TYPES, id)) {
1184		yyerror2("type %s is not within scope", id);
1185		free(id);
1186		return -1;
1187	}
1188	t = hashtab_search(policydbp->p_types.table, id);
1189	if (!t || t->flavor == TYPE_ATTRIB) {
1190		yyerror2("unknown type %s, or it was already declared as an "
1191			 "attribute", id);
1192		free(id);
1193		return -1;
1194	}
1195	return add_aliases_to_type(t);
1196}
1197
1198int define_typeattribute(void)
1199{
1200	char *id;
1201	type_datum_t *t, *attr;
1202
1203	if (pass == 2) {
1204		while ((id = queue_remove(id_queue)))
1205			free(id);
1206		return 0;
1207	}
1208
1209	id = (char *)queue_remove(id_queue);
1210	if (!id) {
1211		yyerror("no type name for typeattribute definition?");
1212		return -1;
1213	}
1214
1215	if (!is_id_in_scope(SYM_TYPES, id)) {
1216		yyerror2("type %s is not within scope", id);
1217		free(id);
1218		return -1;
1219	}
1220	t = hashtab_search(policydbp->p_types.table, id);
1221	if (!t || t->flavor == TYPE_ATTRIB) {
1222		yyerror2("unknown type %s", id);
1223		free(id);
1224		return -1;
1225	}
1226
1227	while ((id = queue_remove(id_queue))) {
1228		if (!is_id_in_scope(SYM_TYPES, id)) {
1229			yyerror2("attribute %s is not within scope", id);
1230			free(id);
1231			return -1;
1232		}
1233		attr = hashtab_search(policydbp->p_types.table, id);
1234		if (!attr) {
1235			/* treat it as a fatal error */
1236			yyerror2("attribute %s is not declared", id);
1237			free(id);
1238			return -1;
1239		}
1240
1241		if (attr->flavor != TYPE_ATTRIB) {
1242			yyerror2("%s is a type, not an attribute", id);
1243			free(id);
1244			return -1;
1245		}
1246
1247		if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1248			yyerror("Out of memory!");
1249			return -1;
1250		}
1251
1252		if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
1253			yyerror("out of memory");
1254			return -1;
1255		}
1256	}
1257
1258	return 0;
1259}
1260
1261static int define_typebounds_helper(char *bounds_id, char *type_id)
1262{
1263	type_datum_t *bounds, *type;
1264
1265	if (!is_id_in_scope(SYM_TYPES, bounds_id)) {
1266		yyerror2("type %s is not within scope", bounds_id);
1267		return -1;
1268	}
1269
1270	bounds = hashtab_search(policydbp->p_types.table, bounds_id);
1271	if (!bounds || bounds->flavor == TYPE_ATTRIB) {
1272		yyerror2("hoge unknown type %s", bounds_id);
1273		return -1;
1274	}
1275
1276	if (!is_id_in_scope(SYM_TYPES, type_id)) {
1277		yyerror2("type %s is not within scope", type_id);
1278		return -1;
1279	}
1280
1281	type = hashtab_search(policydbp->p_types.table, type_id);
1282	if (!type || type->flavor == TYPE_ATTRIB) {
1283		yyerror2("type %s is not declared", type_id);
1284		return -1;
1285	}
1286
1287	if (type->flavor == TYPE_TYPE && !type->primary) {
1288		type = policydbp->type_val_to_struct[type->s.value - 1];
1289	} else if (type->flavor == TYPE_ALIAS) {
1290		type = policydbp->type_val_to_struct[type->primary - 1];
1291	}
1292
1293	if (!type->bounds)
1294		type->bounds = bounds->s.value;
1295	else if (type->bounds != bounds->s.value) {
1296		yyerror2("type %s has inconsistent master {%s,%s}",
1297			 type_id,
1298			 policydbp->p_type_val_to_name[type->bounds - 1],
1299			 policydbp->p_type_val_to_name[bounds->s.value - 1]);
1300		return -1;
1301	}
1302
1303	return 0;
1304}
1305
1306int define_typebounds(void)
1307{
1308	char *bounds, *id;
1309
1310	if (pass == 1) {
1311		while ((id = queue_remove(id_queue)))
1312			free(id);
1313		return 0;
1314	}
1315
1316	bounds = (char *) queue_remove(id_queue);
1317	if (!bounds) {
1318		yyerror("no type name for typebounds definition?");
1319		return -1;
1320	}
1321
1322	while ((id = queue_remove(id_queue))) {
1323		if (define_typebounds_helper(bounds, id))
1324			return -1;
1325		free(id);
1326	}
1327	free(bounds);
1328
1329	return 0;
1330}
1331
1332int define_type(int alias)
1333{
1334	char *id;
1335	type_datum_t *datum, *attr;
1336
1337	if (pass == 2) {
1338		/*
1339		 * If type name contains ".", we have to define boundary
1340		 * relationship implicitly to keep compatibility with
1341		 * old name based hierarchy.
1342		 */
1343		if ((id = queue_remove(id_queue))) {
1344			char *bounds, *delim;
1345
1346			if ((delim = strrchr(id, '.'))
1347			    && (bounds = strdup(id))) {
1348				bounds[(size_t)(delim - id)] = '\0';
1349
1350				if (define_typebounds_helper(bounds, id))
1351					return -1;
1352				free(bounds);
1353			}
1354			free(id);
1355		}
1356
1357		if (alias) {
1358			while ((id = queue_remove(id_queue)))
1359				free(id);
1360		}
1361
1362		while ((id = queue_remove(id_queue)))
1363			free(id);
1364		return 0;
1365	}
1366
1367	if ((datum = declare_type(TRUE, FALSE)) == NULL) {
1368		return -1;
1369	}
1370
1371	if (alias) {
1372		if (add_aliases_to_type(datum) == -1) {
1373			return -1;
1374		}
1375	}
1376
1377	while ((id = queue_remove(id_queue))) {
1378		if (!is_id_in_scope(SYM_TYPES, id)) {
1379			yyerror2("attribute %s is not within scope", id);
1380			free(id);
1381			return -1;
1382		}
1383		attr = hashtab_search(policydbp->p_types.table, id);
1384		if (!attr) {
1385			/* treat it as a fatal error */
1386			yyerror2("attribute %s is not declared", id);
1387			return -1;
1388		}
1389
1390		if (attr->flavor != TYPE_ATTRIB) {
1391			yyerror2("%s is a type, not an attribute", id);
1392			return -1;
1393		}
1394
1395		if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1396			yyerror("Out of memory!");
1397			return -1;
1398		}
1399
1400		if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
1401			yyerror("Out of memory");
1402			return -1;
1403		}
1404	}
1405
1406	return 0;
1407}
1408
1409struct val_to_name {
1410	unsigned int val;
1411	char *name;
1412};
1413
1414/* Adds a type, given by its textual name, to a typeset.  If *add is
1415   0, then add the type to the negative set; otherwise if *add is 1
1416   then add it to the positive side. */
1417static int set_types(type_set_t * set, char *id, int *add, char starallowed)
1418{
1419	type_datum_t *t;
1420
1421	if (strcmp(id, "*") == 0) {
1422		if (!starallowed) {
1423			yyerror("* not allowed in this type of rule");
1424			return -1;
1425		}
1426		/* set TYPE_STAR flag */
1427		set->flags = TYPE_STAR;
1428		free(id);
1429		*add = 1;
1430		return 0;
1431	}
1432
1433	if (strcmp(id, "~") == 0) {
1434		if (!starallowed) {
1435			yyerror("~ not allowed in this type of rule");
1436			return -1;
1437		}
1438		/* complement the set */
1439		set->flags = TYPE_COMP;
1440		free(id);
1441		*add = 1;
1442		return 0;
1443	}
1444
1445	if (strcmp(id, "-") == 0) {
1446		*add = 0;
1447		free(id);
1448		return 0;
1449	}
1450
1451	if (!is_id_in_scope(SYM_TYPES, id)) {
1452		yyerror2("type %s is not within scope", id);
1453		free(id);
1454		return -1;
1455	}
1456	t = hashtab_search(policydbp->p_types.table, id);
1457	if (!t) {
1458		yyerror2("unknown type %s", id);
1459		free(id);
1460		return -1;
1461	}
1462
1463	if (*add == 0) {
1464		if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
1465			goto oom;
1466	} else {
1467		if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
1468			goto oom;
1469	}
1470	free(id);
1471	*add = 1;
1472	return 0;
1473      oom:
1474	yyerror("Out of memory");
1475	free(id);
1476	return -1;
1477}
1478
1479int define_compute_type_helper(int which, avrule_t ** rule)
1480{
1481	char *id;
1482	type_datum_t *datum;
1483	ebitmap_t tclasses;
1484	ebitmap_node_t *node;
1485	avrule_t *avrule;
1486	class_perm_node_t *perm;
1487	int i, add = 1;
1488
1489	avrule = malloc(sizeof(avrule_t));
1490	if (!avrule) {
1491		yyerror("out of memory");
1492		return -1;
1493	}
1494	avrule_init(avrule);
1495	avrule->specified = which;
1496	avrule->line = policydb_lineno;
1497
1498	while ((id = queue_remove(id_queue))) {
1499		if (set_types(&avrule->stypes, id, &add, 0))
1500			return -1;
1501	}
1502	add = 1;
1503	while ((id = queue_remove(id_queue))) {
1504		if (set_types(&avrule->ttypes, id, &add, 0))
1505			return -1;
1506	}
1507
1508	ebitmap_init(&tclasses);
1509	if (read_classes(&tclasses))
1510		goto bad;
1511
1512	id = (char *)queue_remove(id_queue);
1513	if (!id) {
1514		yyerror("no newtype?");
1515		goto bad;
1516	}
1517	if (!is_id_in_scope(SYM_TYPES, id)) {
1518		yyerror2("type %s is not within scope", id);
1519		free(id);
1520		goto bad;
1521	}
1522	datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
1523						(hashtab_key_t) id);
1524	if (!datum || datum->flavor == TYPE_ATTRIB) {
1525		yyerror2("unknown type %s", id);
1526		goto bad;
1527	}
1528
1529	ebitmap_for_each_bit(&tclasses, node, i) {
1530		if (ebitmap_node_get_bit(node, i)) {
1531			perm = malloc(sizeof(class_perm_node_t));
1532			if (!perm) {
1533				yyerror("out of memory");
1534				return -1;
1535			}
1536			class_perm_node_init(perm);
1537			perm->class = i + 1;
1538			perm->data = datum->s.value;
1539			perm->next = avrule->perms;
1540			avrule->perms = perm;
1541		}
1542	}
1543	ebitmap_destroy(&tclasses);
1544
1545	*rule = avrule;
1546	return 0;
1547
1548      bad:
1549	avrule_destroy(avrule);
1550	free(avrule);
1551	return -1;
1552}
1553
1554int define_compute_type(int which)
1555{
1556	char *id;
1557	avrule_t *avrule;
1558
1559	if (pass == 1) {
1560		while ((id = queue_remove(id_queue)))
1561			free(id);
1562		while ((id = queue_remove(id_queue)))
1563			free(id);
1564		while ((id = queue_remove(id_queue)))
1565			free(id);
1566		id = queue_remove(id_queue);
1567		free(id);
1568		return 0;
1569	}
1570
1571	if (define_compute_type_helper(which, &avrule))
1572		return -1;
1573
1574	append_avrule(avrule);
1575	return 0;
1576}
1577
1578avrule_t *define_cond_compute_type(int which)
1579{
1580	char *id;
1581	avrule_t *avrule;
1582
1583	if (pass == 1) {
1584		while ((id = queue_remove(id_queue)))
1585			free(id);
1586		while ((id = queue_remove(id_queue)))
1587			free(id);
1588		while ((id = queue_remove(id_queue)))
1589			free(id);
1590		id = queue_remove(id_queue);
1591		free(id);
1592		return (avrule_t *) 1;
1593	}
1594
1595	if (define_compute_type_helper(which, &avrule))
1596		return COND_ERR;
1597
1598	return avrule;
1599}
1600
1601int define_bool_tunable(int is_tunable)
1602{
1603	char *id, *bool_value;
1604	cond_bool_datum_t *datum;
1605	int ret;
1606	uint32_t value;
1607
1608	if (pass == 2) {
1609		while ((id = queue_remove(id_queue)))
1610			free(id);
1611		return 0;
1612	}
1613
1614	id = (char *)queue_remove(id_queue);
1615	if (!id) {
1616		yyerror("no identifier for bool definition?");
1617		return -1;
1618	}
1619	if (id_has_dot(id)) {
1620		free(id);
1621		yyerror("boolean identifiers may not contain periods");
1622		return -1;
1623	}
1624	datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
1625	if (!datum) {
1626		yyerror("out of memory");
1627		free(id);
1628		return -1;
1629	}
1630	memset(datum, 0, sizeof(cond_bool_datum_t));
1631	if (is_tunable)
1632		datum->flags |= COND_BOOL_FLAGS_TUNABLE;
1633	ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
1634	switch (ret) {
1635	case -3:{
1636			yyerror("Out of memory!");
1637			goto cleanup;
1638		}
1639	case -2:{
1640			yyerror2("duplicate declaration of boolean %s", id);
1641			goto cleanup;
1642		}
1643	case -1:{
1644			yyerror("could not declare boolean here");
1645			goto cleanup;
1646		}
1647	case 0:
1648	case 1:{
1649			break;
1650		}
1651	default:{
1652			assert(0);	/* should never get here */
1653		}
1654	}
1655	datum->s.value = value;
1656
1657	bool_value = (char *)queue_remove(id_queue);
1658	if (!bool_value) {
1659		yyerror("no default value for bool definition?");
1660		free(id);
1661		return -1;
1662	}
1663
1664	datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
1665	return 0;
1666      cleanup:
1667	cond_destroy_bool(id, datum, NULL);
1668	return -1;
1669}
1670
1671avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
1672{
1673	if (pass == 1) {
1674		/* return something so we get through pass 1 */
1675		return (avrule_t *) 1;
1676	}
1677
1678	if (sl == NULL) {
1679		/* This is a require block, return previous list */
1680		return avlist;
1681	}
1682
1683	/* prepend the new avlist to the pre-existing one */
1684	sl->next = avlist;
1685	return sl;
1686}
1687
1688int define_te_avtab_helper(int which, avrule_t ** rule)
1689{
1690	char *id;
1691	class_datum_t *cladatum;
1692	perm_datum_t *perdatum = NULL;
1693	class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
1694	ebitmap_t tclasses;
1695	ebitmap_node_t *node;
1696	avrule_t *avrule;
1697	unsigned int i;
1698	int add = 1, ret = 0;
1699	int suppress = 0;
1700
1701	avrule = (avrule_t *) malloc(sizeof(avrule_t));
1702	if (!avrule) {
1703		yyerror("memory error");
1704		ret = -1;
1705		goto out;
1706	}
1707	avrule_init(avrule);
1708	avrule->specified = which;
1709	avrule->line = policydb_lineno;
1710
1711	while ((id = queue_remove(id_queue))) {
1712		if (set_types
1713		    (&avrule->stypes, id, &add,
1714		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
1715			ret = -1;
1716			goto out;
1717		}
1718	}
1719	add = 1;
1720	while ((id = queue_remove(id_queue))) {
1721		if (strcmp(id, "self") == 0) {
1722			free(id);
1723			avrule->flags |= RULE_SELF;
1724			continue;
1725		}
1726		if (set_types
1727		    (&avrule->ttypes, id, &add,
1728		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
1729			ret = -1;
1730			goto out;
1731		}
1732	}
1733
1734	ebitmap_init(&tclasses);
1735	ret = read_classes(&tclasses);
1736	if (ret)
1737		goto out;
1738
1739	perms = NULL;
1740	ebitmap_for_each_bit(&tclasses, node, i) {
1741		if (!ebitmap_node_get_bit(node, i))
1742			continue;
1743		cur_perms =
1744		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
1745		if (!cur_perms) {
1746			yyerror("out of memory");
1747			ret = -1;
1748			goto out;
1749		}
1750		class_perm_node_init(cur_perms);
1751		cur_perms->class = i + 1;
1752		if (!perms)
1753			perms = cur_perms;
1754		if (tail)
1755			tail->next = cur_perms;
1756		tail = cur_perms;
1757	}
1758
1759	while ((id = queue_remove(id_queue))) {
1760		cur_perms = perms;
1761		ebitmap_for_each_bit(&tclasses, node, i) {
1762			if (!ebitmap_node_get_bit(node, i))
1763				continue;
1764			cladatum = policydbp->class_val_to_struct[i];
1765
1766			if (strcmp(id, "*") == 0) {
1767				/* set all permissions in the class */
1768				cur_perms->data = ~0U;
1769				goto next;
1770			}
1771
1772			if (strcmp(id, "~") == 0) {
1773				/* complement the set */
1774				if (which == AVRULE_DONTAUDIT)
1775					yywarn("dontaudit rule with a ~?");
1776				cur_perms->data = ~cur_perms->data;
1777				goto next;
1778			}
1779
1780			perdatum =
1781			    hashtab_search(cladatum->permissions.table, id);
1782			if (!perdatum) {
1783				if (cladatum->comdatum) {
1784					perdatum =
1785					    hashtab_search(cladatum->comdatum->
1786							   permissions.table,
1787							   id);
1788				}
1789			}
1790			if (!perdatum) {
1791				if (!suppress)
1792					yyerror2("permission %s is not defined"
1793					     " for class %s", id,
1794					     policydbp->p_class_val_to_name[i]);
1795				continue;
1796			} else
1797			    if (!is_perm_in_scope
1798				(id, policydbp->p_class_val_to_name[i])) {
1799				if (!suppress) {
1800					yyerror2("permission %s of class %s is"
1801					     " not within scope", id,
1802					     policydbp->p_class_val_to_name[i]);
1803				}
1804				continue;
1805			} else {
1806				cur_perms->data |= 1U << (perdatum->s.value - 1);
1807			}
1808		      next:
1809			cur_perms = cur_perms->next;
1810		}
1811
1812		free(id);
1813	}
1814
1815	ebitmap_destroy(&tclasses);
1816
1817	avrule->perms = perms;
1818	*rule = avrule;
1819
1820      out:
1821	return ret;
1822
1823}
1824
1825avrule_t *define_cond_te_avtab(int which)
1826{
1827	char *id;
1828	avrule_t *avrule;
1829	int i;
1830
1831	if (pass == 1) {
1832		for (i = 0; i < 4; i++) {
1833			while ((id = queue_remove(id_queue)))
1834				free(id);
1835		}
1836		return (avrule_t *) 1;	/* any non-NULL value */
1837	}
1838
1839	if (define_te_avtab_helper(which, &avrule))
1840		return COND_ERR;
1841
1842	return avrule;
1843}
1844
1845int define_te_avtab(int which)
1846{
1847	char *id;
1848	avrule_t *avrule;
1849	int i;
1850
1851	if (pass == 1) {
1852		for (i = 0; i < 4; i++) {
1853			while ((id = queue_remove(id_queue)))
1854				free(id);
1855		}
1856		return 0;
1857	}
1858
1859	if (define_te_avtab_helper(which, &avrule))
1860		return -1;
1861
1862	/* append this avrule to the end of the current rules list */
1863	append_avrule(avrule);
1864	return 0;
1865}
1866
1867/* The role-types rule is no longer used to declare regular role or
1868 * role attribute, but solely aimed for declaring role-types associations.
1869 */
1870int define_role_types(void)
1871{
1872	role_datum_t *role;
1873	char *id;
1874	int add = 1;
1875
1876	if (pass == 1) {
1877		while ((id = queue_remove(id_queue)))
1878			free(id);
1879		return 0;
1880	}
1881
1882	id = (char *)queue_remove(id_queue);
1883	if (!id) {
1884		yyerror("no role name for role-types rule?");
1885		return -1;
1886	}
1887
1888	if (!is_id_in_scope(SYM_ROLES, id)) {
1889		yyerror2("role %s is not within scope", id);
1890		free(id);
1891		return -1;
1892	}
1893
1894	role = hashtab_search(policydbp->p_roles.table, id);
1895	if (!role) {
1896		yyerror2("unknown role %s", id);
1897		free(id);
1898		return -1;
1899	}
1900
1901	while ((id = queue_remove(id_queue))) {
1902		if (set_types(&role->types, id, &add, 0))
1903			return -1;
1904	}
1905
1906	return 0;
1907}
1908
1909int define_attrib_role(void)
1910{
1911	if (pass == 2) {
1912		free(queue_remove(id_queue));
1913		return 0;
1914	}
1915
1916	/* Declare a role attribute */
1917	if (declare_role(TRUE) == NULL)
1918		return -1;
1919
1920	return 0;
1921}
1922
1923int define_role_attr(void)
1924{
1925	char *id;
1926	role_datum_t *r, *attr;
1927
1928	if (pass == 2) {
1929		while ((id = queue_remove(id_queue)))
1930			free(id);
1931		return 0;
1932	}
1933
1934	/* Declare a regular role */
1935	if ((r = declare_role(FALSE)) == NULL)
1936		return -1;
1937
1938	while ((id = queue_remove(id_queue))) {
1939		if (!is_id_in_scope(SYM_ROLES, id)) {
1940			yyerror2("attribute %s is not within scope", id);
1941			free(id);
1942			return -1;
1943		}
1944		attr = hashtab_search(policydbp->p_roles.table, id);
1945		if (!attr) {
1946			/* treat it as a fatal error */
1947			yyerror2("role attribute %s is not declared", id);
1948			free(id);
1949			return -1;
1950		}
1951
1952		if (attr->flavor != ROLE_ATTRIB) {
1953			yyerror2("%s is a regular role, not an attribute", id);
1954			free(id);
1955			return -1;
1956		}
1957
1958		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
1959			yyerror("Out of memory!");
1960			return -1;
1961		}
1962
1963		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
1964			yyerror("out of memory");
1965			return -1;
1966		}
1967	}
1968
1969	return 0;
1970}
1971
1972int define_roleattribute(void)
1973{
1974	char *id;
1975	role_datum_t *r, *attr;
1976
1977	if (pass == 2) {
1978		while ((id = queue_remove(id_queue)))
1979			free(id);
1980		return 0;
1981	}
1982
1983	id = (char *)queue_remove(id_queue);
1984	if (!id) {
1985		yyerror("no role name for roleattribute definition?");
1986		return -1;
1987	}
1988
1989	if (!is_id_in_scope(SYM_ROLES, id)) {
1990		yyerror2("role %s is not within scope", id);
1991		free(id);
1992		return -1;
1993	}
1994	r = hashtab_search(policydbp->p_roles.table, id);
1995	/* We support adding one role attribute into another */
1996	if (!r) {
1997		yyerror2("unknown role %s", id);
1998		free(id);
1999		return -1;
2000	}
2001
2002	while ((id = queue_remove(id_queue))) {
2003		if (!is_id_in_scope(SYM_ROLES, id)) {
2004			yyerror2("attribute %s is not within scope", id);
2005			free(id);
2006			return -1;
2007		}
2008		attr = hashtab_search(policydbp->p_roles.table, id);
2009		if (!attr) {
2010			/* treat it as a fatal error */
2011			yyerror2("role attribute %s is not declared", id);
2012			free(id);
2013			return -1;
2014		}
2015
2016		if (attr->flavor != ROLE_ATTRIB) {
2017			yyerror2("%s is a regular role, not an attribute", id);
2018			free(id);
2019			return -1;
2020		}
2021
2022		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2023			yyerror("Out of memory!");
2024			return -1;
2025		}
2026
2027		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2028			yyerror("out of memory");
2029			return -1;
2030		}
2031	}
2032
2033	return 0;
2034}
2035
2036role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
2037{
2038	role_datum_t *new;
2039
2040	if (pass == 1) {
2041		return (role_datum_t *) 1;	/* any non-NULL value */
2042	}
2043
2044	new = malloc(sizeof(role_datum_t));
2045	if (!new) {
2046		yyerror("out of memory");
2047		return NULL;
2048	}
2049	memset(new, 0, sizeof(role_datum_t));
2050	new->s.value = 0;		/* temporary role */
2051	if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
2052		yyerror("out of memory");
2053		return NULL;
2054	}
2055	if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
2056		yyerror("out of memory");
2057		return NULL;
2058	}
2059	if (!r1->s.value) {
2060		/* free intermediate result */
2061		type_set_destroy(&r1->types);
2062		ebitmap_destroy(&r1->dominates);
2063		free(r1);
2064	}
2065	if (!r2->s.value) {
2066		/* free intermediate result */
2067		yyerror("right hand role is temporary?");
2068		type_set_destroy(&r2->types);
2069		ebitmap_destroy(&r2->dominates);
2070		free(r2);
2071	}
2072	return new;
2073}
2074
2075/* This function eliminates the ordering dependency of role dominance rule */
2076static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum,
2077				 void *arg)
2078{
2079	role_datum_t *rdp = (role_datum_t *) arg;
2080	role_datum_t *rdatum = (role_datum_t *) datum;
2081	ebitmap_node_t *node;
2082	int i;
2083
2084	/* Don't bother to process against self role */
2085	if (rdatum->s.value == rdp->s.value)
2086		return 0;
2087
2088	/* If a dominating role found */
2089	if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
2090		ebitmap_t types;
2091		ebitmap_init(&types);
2092		if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
2093			ebitmap_destroy(&types);
2094			return -1;
2095		}
2096		/* raise types and dominates from dominated role */
2097		ebitmap_for_each_bit(&rdp->dominates, node, i) {
2098			if (ebitmap_node_get_bit(node, i))
2099				if (ebitmap_set_bit
2100				    (&rdatum->dominates, i, TRUE))
2101					goto oom;
2102		}
2103		ebitmap_for_each_bit(&types, node, i) {
2104			if (ebitmap_node_get_bit(node, i))
2105				if (ebitmap_set_bit
2106				    (&rdatum->types.types, i, TRUE))
2107					goto oom;
2108		}
2109		ebitmap_destroy(&types);
2110	}
2111
2112	/* go through all the roles */
2113	return 0;
2114      oom:
2115	yyerror("Out of memory");
2116	return -1;
2117}
2118
2119role_datum_t *define_role_dom(role_datum_t * r)
2120{
2121	role_datum_t *role;
2122	char *role_id;
2123	ebitmap_node_t *node;
2124	unsigned int i;
2125	int ret;
2126
2127	if (pass == 1) {
2128		role_id = queue_remove(id_queue);
2129		free(role_id);
2130		return (role_datum_t *) 1;	/* any non-NULL value */
2131	}
2132
2133	yywarn("Role dominance has been deprecated");
2134
2135	role_id = queue_remove(id_queue);
2136	if (!is_id_in_scope(SYM_ROLES, role_id)) {
2137		yyerror2("role %s is not within scope", role_id);
2138		free(role_id);
2139		return NULL;
2140	}
2141	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2142					       role_id);
2143	if (!role) {
2144		role = (role_datum_t *) malloc(sizeof(role_datum_t));
2145		if (!role) {
2146			yyerror("out of memory");
2147			free(role_id);
2148			return NULL;
2149		}
2150		memset(role, 0, sizeof(role_datum_t));
2151		ret =
2152		    declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
2153				   (hashtab_datum_t) role, &role->s.value,
2154				   &role->s.value);
2155		switch (ret) {
2156		case -3:{
2157				yyerror("Out of memory!");
2158				goto cleanup;
2159			}
2160		case -2:{
2161				yyerror2("duplicate declaration of role %s",
2162					 role_id);
2163				goto cleanup;
2164			}
2165		case -1:{
2166				yyerror("could not declare role here");
2167				goto cleanup;
2168			}
2169		case 0:
2170		case 1:{
2171				break;
2172			}
2173		default:{
2174				assert(0);	/* should never get here */
2175			}
2176		}
2177		if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
2178			yyerror("Out of memory!");
2179			goto cleanup;
2180		}
2181	}
2182	if (r) {
2183		ebitmap_t types;
2184		ebitmap_init(&types);
2185		ebitmap_for_each_bit(&r->dominates, node, i) {
2186			if (ebitmap_node_get_bit(node, i))
2187				if (ebitmap_set_bit(&role->dominates, i, TRUE))
2188					goto oom;
2189		}
2190		if (type_set_expand(&r->types, &types, policydbp, 1)) {
2191			ebitmap_destroy(&types);
2192			return NULL;
2193		}
2194		ebitmap_for_each_bit(&types, node, i) {
2195			if (ebitmap_node_get_bit(node, i))
2196				if (ebitmap_set_bit
2197				    (&role->types.types, i, TRUE))
2198					goto oom;
2199		}
2200		ebitmap_destroy(&types);
2201		if (!r->s.value) {
2202			/* free intermediate result */
2203			type_set_destroy(&r->types);
2204			ebitmap_destroy(&r->dominates);
2205			free(r);
2206		}
2207		/*
2208		 * Now go through all the roles and escalate this role's
2209		 * dominates and types if a role dominates this role.
2210		 */
2211		hashtab_map(policydbp->p_roles.table,
2212			    dominate_role_recheck, role);
2213	}
2214	return role;
2215      cleanup:
2216	free(role_id);
2217	role_datum_destroy(role);
2218	free(role);
2219	return NULL;
2220      oom:
2221	yyerror("Out of memory");
2222	goto cleanup;
2223}
2224
2225static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
2226				   void *p)
2227{
2228	struct val_to_name *v = p;
2229	role_datum_t *roldatum;
2230
2231	roldatum = (role_datum_t *) datum;
2232
2233	if (v->val == roldatum->s.value) {
2234		v->name = key;
2235		return 1;
2236	}
2237
2238	return 0;
2239}
2240
2241static char *role_val_to_name(unsigned int val)
2242{
2243	struct val_to_name v;
2244	int rc;
2245
2246	v.val = val;
2247	rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
2248	if (rc)
2249		return v.name;
2250	return NULL;
2251}
2252
2253static int set_roles(role_set_t * set, char *id)
2254{
2255	role_datum_t *r;
2256
2257	if (strcmp(id, "*") == 0) {
2258		free(id);
2259		yyerror("* is not allowed for role sets");
2260		return -1;
2261	}
2262
2263	if (strcmp(id, "~") == 0) {
2264		free(id);
2265		yyerror("~ is not allowed for role sets");
2266		return -1;
2267	}
2268	if (!is_id_in_scope(SYM_ROLES, id)) {
2269		yyerror2("role %s is not within scope", id);
2270		free(id);
2271		return -1;
2272	}
2273	r = hashtab_search(policydbp->p_roles.table, id);
2274	if (!r) {
2275		yyerror2("unknown role %s", id);
2276		free(id);
2277		return -1;
2278	}
2279
2280	if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
2281		yyerror("out of memory");
2282		free(id);
2283		return -1;
2284	}
2285	free(id);
2286	return 0;
2287}
2288
2289int define_role_trans(int class_specified)
2290{
2291	char *id;
2292	role_datum_t *role;
2293	role_set_t roles;
2294	type_set_t types;
2295	class_datum_t *cladatum;
2296	ebitmap_t e_types, e_roles, e_classes;
2297	ebitmap_node_t *tnode, *rnode, *cnode;
2298	struct role_trans *tr = NULL;
2299	struct role_trans_rule *rule = NULL;
2300	unsigned int i, j, k;
2301	int add = 1;
2302
2303	if (pass == 1) {
2304		while ((id = queue_remove(id_queue)))
2305			free(id);
2306		while ((id = queue_remove(id_queue)))
2307			free(id);
2308		if (class_specified)
2309			while ((id = queue_remove(id_queue)))
2310				free(id);
2311		id = queue_remove(id_queue);
2312		free(id);
2313		return 0;
2314	}
2315
2316	role_set_init(&roles);
2317	ebitmap_init(&e_roles);
2318	type_set_init(&types);
2319	ebitmap_init(&e_types);
2320	ebitmap_init(&e_classes);
2321
2322	while ((id = queue_remove(id_queue))) {
2323		if (set_roles(&roles, id))
2324			return -1;
2325	}
2326	add = 1;
2327	while ((id = queue_remove(id_queue))) {
2328		if (set_types(&types, id, &add, 0))
2329			return -1;
2330	}
2331
2332	if (class_specified) {
2333		if (read_classes(&e_classes))
2334			return -1;
2335	} else {
2336		cladatum = hashtab_search(policydbp->p_classes.table,
2337					  "process");
2338		if (!cladatum) {
2339			yyerror2("could not find process class for "
2340				 "legacy role_transition statement");
2341			return -1;
2342		}
2343
2344		ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE);
2345	}
2346
2347	id = (char *)queue_remove(id_queue);
2348	if (!id) {
2349		yyerror("no new role in transition definition?");
2350		goto bad;
2351	}
2352	if (!is_id_in_scope(SYM_ROLES, id)) {
2353		yyerror2("role %s is not within scope", id);
2354		free(id);
2355		goto bad;
2356	}
2357	role = hashtab_search(policydbp->p_roles.table, id);
2358	if (!role) {
2359		yyerror2("unknown role %s used in transition definition", id);
2360		goto bad;
2361	}
2362
2363	if (role->flavor != ROLE_ROLE) {
2364		yyerror2("the new role %s must be a regular role", id);
2365		goto bad;
2366	}
2367
2368	/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
2369	if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
2370		goto bad;
2371
2372	if (type_set_expand(&types, &e_types, policydbp, 1))
2373		goto bad;
2374
2375	ebitmap_for_each_bit(&e_roles, rnode, i) {
2376		if (!ebitmap_node_get_bit(rnode, i))
2377			continue;
2378		ebitmap_for_each_bit(&e_types, tnode, j) {
2379			if (!ebitmap_node_get_bit(tnode, j))
2380				continue;
2381			ebitmap_for_each_bit(&e_classes, cnode, k) {
2382				if (!ebitmap_node_get_bit(cnode, k))
2383					continue;
2384				for (tr = policydbp->role_tr; tr;
2385				     tr = tr->next) {
2386					if (tr->role == (i + 1) &&
2387					    tr->type == (j + 1) &&
2388					    tr->tclass == (k + 1)) {
2389						yyerror2("duplicate role "
2390							 "transition for "
2391							 "(%s,%s,%s)",
2392							 role_val_to_name(i+1),
2393							 policydbp->p_type_val_to_name[j],
2394							 policydbp->p_class_val_to_name[k]);
2395						goto bad;
2396					}
2397				}
2398
2399				tr = malloc(sizeof(struct role_trans));
2400				if (!tr) {
2401					yyerror("out of memory");
2402					return -1;
2403				}
2404				memset(tr, 0, sizeof(struct role_trans));
2405				tr->role = i + 1;
2406				tr->type = j + 1;
2407				tr->tclass = k + 1;
2408				tr->new_role = role->s.value;
2409				tr->next = policydbp->role_tr;
2410				policydbp->role_tr = tr;
2411			}
2412		}
2413	}
2414	/* Now add the real rule */
2415	rule = malloc(sizeof(struct role_trans_rule));
2416	if (!rule) {
2417		yyerror("out of memory");
2418		return -1;
2419	}
2420	memset(rule, 0, sizeof(struct role_trans_rule));
2421	rule->roles = roles;
2422	rule->types = types;
2423	rule->classes = e_classes;
2424	rule->new_role = role->s.value;
2425
2426	append_role_trans(rule);
2427
2428	ebitmap_destroy(&e_roles);
2429	ebitmap_destroy(&e_types);
2430
2431	return 0;
2432
2433      bad:
2434	return -1;
2435}
2436
2437int define_role_allow(void)
2438{
2439	char *id;
2440	struct role_allow_rule *ra = 0;
2441
2442	if (pass == 1) {
2443		while ((id = queue_remove(id_queue)))
2444			free(id);
2445		while ((id = queue_remove(id_queue)))
2446			free(id);
2447		return 0;
2448	}
2449
2450	ra = malloc(sizeof(role_allow_rule_t));
2451	if (!ra) {
2452		yyerror("out of memory");
2453		return -1;
2454	}
2455	role_allow_rule_init(ra);
2456
2457	while ((id = queue_remove(id_queue))) {
2458		if (set_roles(&ra->roles, id))
2459			return -1;
2460	}
2461
2462	while ((id = queue_remove(id_queue))) {
2463		if (set_roles(&ra->new_roles, id))
2464			return -1;
2465	}
2466
2467	append_role_allow(ra);
2468	return 0;
2469}
2470
2471avrule_t *define_cond_filename_trans(void)
2472{
2473	yyerror("type transitions with a filename not allowed inside "
2474		"conditionals\n");
2475	return COND_ERR;
2476}
2477
2478int define_filename_trans(void)
2479{
2480	char *id, *name = NULL;
2481	type_set_t stypes, ttypes;
2482	ebitmap_t e_stypes, e_ttypes;
2483	ebitmap_t e_tclasses;
2484	ebitmap_node_t *snode, *tnode, *cnode;
2485	filename_trans_t *ft;
2486	filename_trans_rule_t *ftr;
2487	type_datum_t *typdatum;
2488	uint32_t otype;
2489	unsigned int c, s, t;
2490	int add;
2491
2492	if (pass == 1) {
2493		/* stype */
2494		while ((id = queue_remove(id_queue)))
2495			free(id);
2496		/* ttype */
2497		while ((id = queue_remove(id_queue)))
2498			free(id);
2499		/* tclass */
2500		while ((id = queue_remove(id_queue)))
2501			free(id);
2502		/* otype */
2503		id = queue_remove(id_queue);
2504		free(id);
2505		/* name */
2506		id = queue_remove(id_queue);
2507		free(id);
2508		return 0;
2509	}
2510
2511
2512	add = 1;
2513	type_set_init(&stypes);
2514	while ((id = queue_remove(id_queue))) {
2515		if (set_types(&stypes, id, &add, 0))
2516			goto bad;
2517	}
2518
2519	add =1;
2520	type_set_init(&ttypes);
2521	while ((id = queue_remove(id_queue))) {
2522		if (set_types(&ttypes, id, &add, 0))
2523			goto bad;
2524	}
2525
2526	ebitmap_init(&e_tclasses);
2527	if (read_classes(&e_tclasses))
2528		goto bad;
2529
2530	id = (char *)queue_remove(id_queue);
2531	if (!id) {
2532		yyerror("no otype in transition definition?");
2533		goto bad;
2534	}
2535	if (!is_id_in_scope(SYM_TYPES, id)) {
2536		yyerror2("type %s is not within scope", id);
2537		free(id);
2538		goto bad;
2539	}
2540	typdatum = hashtab_search(policydbp->p_types.table, id);
2541	if (!typdatum) {
2542		yyerror2("unknown type %s used in transition definition", id);
2543		goto bad;
2544	}
2545	free(id);
2546	otype = typdatum->s.value;
2547
2548	name = queue_remove(id_queue);
2549	if (!name) {
2550		yyerror("no pathname specified in filename_trans definition?");
2551		goto bad;
2552	}
2553
2554	/* We expand the class set into seperate rules.  We expand the types
2555	 * just to make sure there are not duplicates.  They will get turned
2556	 * into seperate rules later */
2557	ebitmap_init(&e_stypes);
2558	if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
2559		goto bad;
2560
2561	ebitmap_init(&e_ttypes);
2562	if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
2563		goto bad;
2564
2565	ebitmap_for_each_bit(&e_tclasses, cnode, c) {
2566		if (!ebitmap_node_get_bit(cnode, c))
2567			continue;
2568		ebitmap_for_each_bit(&e_stypes, snode, s) {
2569			if (!ebitmap_node_get_bit(snode, s))
2570				continue;
2571			ebitmap_for_each_bit(&e_ttypes, tnode, t) {
2572				if (!ebitmap_node_get_bit(tnode, t))
2573					continue;
2574
2575				for (ft = policydbp->filename_trans; ft; ft = ft->next) {
2576					if (ft->stype == (s + 1) &&
2577					    ft->ttype == (t + 1) &&
2578					    ft->tclass == (c + 1) &&
2579					    !strcmp(ft->name, name)) {
2580						yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
2581							 name,
2582							 policydbp->p_type_val_to_name[s],
2583							 policydbp->p_type_val_to_name[t],
2584							 policydbp->p_class_val_to_name[c]);
2585						goto bad;
2586					}
2587				}
2588
2589				ft = malloc(sizeof(*ft));
2590				if (!ft) {
2591					yyerror("out of memory");
2592					goto bad;
2593				}
2594				memset(ft, 0, sizeof(*ft));
2595
2596				ft->next = policydbp->filename_trans;
2597				policydbp->filename_trans = ft;
2598
2599				ft->name = strdup(name);
2600				if (!ft->name) {
2601					yyerror("out of memory");
2602					goto bad;
2603				}
2604				ft->stype = s + 1;
2605				ft->ttype = t + 1;
2606				ft->tclass = c + 1;
2607				ft->otype = otype;
2608			}
2609		}
2610
2611		/* Now add the real rule since we didn't find any duplicates */
2612		ftr = malloc(sizeof(*ftr));
2613		if (!ftr) {
2614			yyerror("out of memory");
2615			goto bad;
2616		}
2617		filename_trans_rule_init(ftr);
2618		append_filename_trans(ftr);
2619
2620		ftr->name = strdup(name);
2621		ftr->stypes = stypes;
2622		ftr->ttypes = ttypes;
2623		ftr->tclass = c + 1;
2624		ftr->otype = otype;
2625	}
2626
2627	free(name);
2628	ebitmap_destroy(&e_stypes);
2629	ebitmap_destroy(&e_ttypes);
2630	ebitmap_destroy(&e_tclasses);
2631
2632	return 0;
2633
2634bad:
2635	free(name);
2636	return -1;
2637}
2638
2639static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
2640{
2641	constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
2642	for (e = expr; e; e = e->next) {
2643		newe = malloc(sizeof(*newe));
2644		if (!newe)
2645			goto oom;
2646		if (constraint_expr_init(newe) == -1) {
2647			free(newe);
2648			goto oom;
2649		}
2650		if (l)
2651			l->next = newe;
2652		else
2653			h = newe;
2654		l = newe;
2655		newe->expr_type = e->expr_type;
2656		newe->attr = e->attr;
2657		newe->op = e->op;
2658		if (newe->expr_type == CEXPR_NAMES) {
2659			if (newe->attr & CEXPR_TYPE) {
2660				if (type_set_cpy
2661				    (newe->type_names, e->type_names))
2662					goto oom;
2663			} else {
2664				if (ebitmap_cpy(&newe->names, &e->names))
2665					goto oom;
2666			}
2667		}
2668	}
2669
2670	return h;
2671      oom:
2672	e = h;
2673	while (e) {
2674		l = e;
2675		e = e->next;
2676		constraint_expr_destroy(l);
2677	}
2678	return NULL;
2679}
2680
2681int define_constraint(constraint_expr_t * expr)
2682{
2683	struct constraint_node *node;
2684	char *id;
2685	class_datum_t *cladatum;
2686	perm_datum_t *perdatum;
2687	ebitmap_t classmap;
2688	ebitmap_node_t *enode;
2689	constraint_expr_t *e;
2690	unsigned int i;
2691	int depth;
2692	unsigned char useexpr = 1;
2693
2694	if (pass == 1) {
2695		while ((id = queue_remove(id_queue)))
2696			free(id);
2697		while ((id = queue_remove(id_queue)))
2698			free(id);
2699		return 0;
2700	}
2701
2702	depth = -1;
2703	for (e = expr; e; e = e->next) {
2704		switch (e->expr_type) {
2705		case CEXPR_NOT:
2706			if (depth < 0) {
2707				yyerror("illegal constraint expression");
2708				return -1;
2709			}
2710			break;
2711		case CEXPR_AND:
2712		case CEXPR_OR:
2713			if (depth < 1) {
2714				yyerror("illegal constraint expression");
2715				return -1;
2716			}
2717			depth--;
2718			break;
2719		case CEXPR_ATTR:
2720		case CEXPR_NAMES:
2721			if (e->attr & CEXPR_XTARGET) {
2722				yyerror("illegal constraint expression");
2723				return -1;	/* only for validatetrans rules */
2724			}
2725			if (depth == (CEXPR_MAXDEPTH - 1)) {
2726				yyerror("constraint expression is too deep");
2727				return -1;
2728			}
2729			depth++;
2730			break;
2731		default:
2732			yyerror("illegal constraint expression");
2733			return -1;
2734		}
2735	}
2736	if (depth != 0) {
2737		yyerror("illegal constraint expression");
2738		return -1;
2739	}
2740
2741	ebitmap_init(&classmap);
2742	while ((id = queue_remove(id_queue))) {
2743		if (!is_id_in_scope(SYM_CLASSES, id)) {
2744			yyerror2("class %s is not within scope", id);
2745			free(id);
2746			return -1;
2747		}
2748		cladatum =
2749		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2750						     (hashtab_key_t) id);
2751		if (!cladatum) {
2752			yyerror2("class %s is not defined", id);
2753			ebitmap_destroy(&classmap);
2754			free(id);
2755			return -1;
2756		}
2757		if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
2758			yyerror("out of memory");
2759			ebitmap_destroy(&classmap);
2760			free(id);
2761			return -1;
2762		}
2763		node = malloc(sizeof(struct constraint_node));
2764		if (!node) {
2765			yyerror("out of memory");
2766			return -1;
2767		}
2768		memset(node, 0, sizeof(constraint_node_t));
2769		if (useexpr) {
2770			node->expr = expr;
2771			useexpr = 0;
2772		} else {
2773			node->expr = constraint_expr_clone(expr);
2774		}
2775		if (!node->expr) {
2776			yyerror("out of memory");
2777			return -1;
2778		}
2779		node->permissions = 0;
2780
2781		node->next = cladatum->constraints;
2782		cladatum->constraints = node;
2783
2784		free(id);
2785	}
2786
2787	while ((id = queue_remove(id_queue))) {
2788		ebitmap_for_each_bit(&classmap, enode, i) {
2789			if (ebitmap_node_get_bit(enode, i)) {
2790				cladatum = policydbp->class_val_to_struct[i];
2791				node = cladatum->constraints;
2792
2793				perdatum =
2794				    (perm_datum_t *) hashtab_search(cladatum->
2795								    permissions.
2796								    table,
2797								    (hashtab_key_t)
2798								    id);
2799				if (!perdatum) {
2800					if (cladatum->comdatum) {
2801						perdatum =
2802						    (perm_datum_t *)
2803						    hashtab_search(cladatum->
2804								   comdatum->
2805								   permissions.
2806								   table,
2807								   (hashtab_key_t)
2808								   id);
2809					}
2810					if (!perdatum) {
2811						yyerror2("permission %s is not"
2812							 " defined", id);
2813						free(id);
2814						ebitmap_destroy(&classmap);
2815						return -1;
2816					}
2817				}
2818				node->permissions |=
2819				    (1 << (perdatum->s.value - 1));
2820			}
2821		}
2822		free(id);
2823	}
2824
2825	ebitmap_destroy(&classmap);
2826
2827	return 0;
2828}
2829
2830int define_validatetrans(constraint_expr_t * expr)
2831{
2832	struct constraint_node *node;
2833	char *id;
2834	class_datum_t *cladatum;
2835	ebitmap_t classmap;
2836	constraint_expr_t *e;
2837	int depth;
2838	unsigned char useexpr = 1;
2839
2840	if (pass == 1) {
2841		while ((id = queue_remove(id_queue)))
2842			free(id);
2843		return 0;
2844	}
2845
2846	depth = -1;
2847	for (e = expr; e; e = e->next) {
2848		switch (e->expr_type) {
2849		case CEXPR_NOT:
2850			if (depth < 0) {
2851				yyerror("illegal validatetrans expression");
2852				return -1;
2853			}
2854			break;
2855		case CEXPR_AND:
2856		case CEXPR_OR:
2857			if (depth < 1) {
2858				yyerror("illegal validatetrans expression");
2859				return -1;
2860			}
2861			depth--;
2862			break;
2863		case CEXPR_ATTR:
2864		case CEXPR_NAMES:
2865			if (depth == (CEXPR_MAXDEPTH - 1)) {
2866				yyerror("validatetrans expression is too deep");
2867				return -1;
2868			}
2869			depth++;
2870			break;
2871		default:
2872			yyerror("illegal validatetrans expression");
2873			return -1;
2874		}
2875	}
2876	if (depth != 0) {
2877		yyerror("illegal validatetrans expression");
2878		return -1;
2879	}
2880
2881	ebitmap_init(&classmap);
2882	while ((id = queue_remove(id_queue))) {
2883		if (!is_id_in_scope(SYM_CLASSES, id)) {
2884			yyerror2("class %s is not within scope", id);
2885			free(id);
2886			return -1;
2887		}
2888		cladatum =
2889		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2890						     (hashtab_key_t) id);
2891		if (!cladatum) {
2892			yyerror2("class %s is not defined", id);
2893			ebitmap_destroy(&classmap);
2894			free(id);
2895			return -1;
2896		}
2897		if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
2898			yyerror("out of memory");
2899			ebitmap_destroy(&classmap);
2900			free(id);
2901			return -1;
2902		}
2903
2904		node = malloc(sizeof(struct constraint_node));
2905		if (!node) {
2906			yyerror("out of memory");
2907			return -1;
2908		}
2909		memset(node, 0, sizeof(constraint_node_t));
2910		if (useexpr) {
2911			node->expr = expr;
2912			useexpr = 0;
2913		} else {
2914			node->expr = constraint_expr_clone(expr);
2915		}
2916		node->permissions = 0;
2917
2918		node->next = cladatum->validatetrans;
2919		cladatum->validatetrans = node;
2920
2921		free(id);
2922	}
2923
2924	ebitmap_destroy(&classmap);
2925
2926	return 0;
2927}
2928
2929uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
2930{
2931	struct constraint_expr *expr, *e1 = NULL, *e2;
2932	user_datum_t *user;
2933	role_datum_t *role;
2934	ebitmap_t negset;
2935	char *id;
2936	uint32_t val;
2937	int add = 1;
2938
2939	if (pass == 1) {
2940		if (expr_type == CEXPR_NAMES) {
2941			while ((id = queue_remove(id_queue)))
2942				free(id);
2943		}
2944		return 1;	/* any non-NULL value */
2945	}
2946
2947	if ((expr = malloc(sizeof(*expr))) == NULL ||
2948	    constraint_expr_init(expr) == -1) {
2949		yyerror("out of memory");
2950		free(expr);
2951		return 0;
2952	}
2953	expr->expr_type = expr_type;
2954
2955	switch (expr_type) {
2956	case CEXPR_NOT:
2957		e1 = NULL;
2958		e2 = (struct constraint_expr *)arg1;
2959		while (e2) {
2960			e1 = e2;
2961			e2 = e2->next;
2962		}
2963		if (!e1 || e1->next) {
2964			yyerror("illegal constraint expression");
2965			constraint_expr_destroy(expr);
2966			return 0;
2967		}
2968		e1->next = expr;
2969		return arg1;
2970	case CEXPR_AND:
2971	case CEXPR_OR:
2972		e1 = NULL;
2973		e2 = (struct constraint_expr *)arg1;
2974		while (e2) {
2975			e1 = e2;
2976			e2 = e2->next;
2977		}
2978		if (!e1 || e1->next) {
2979			yyerror("illegal constraint expression");
2980			constraint_expr_destroy(expr);
2981			return 0;
2982		}
2983		e1->next = (struct constraint_expr *)arg2;
2984
2985		e1 = NULL;
2986		e2 = (struct constraint_expr *)arg2;
2987		while (e2) {
2988			e1 = e2;
2989			e2 = e2->next;
2990		}
2991		if (!e1 || e1->next) {
2992			yyerror("illegal constraint expression");
2993			constraint_expr_destroy(expr);
2994			return 0;
2995		}
2996		e1->next = expr;
2997		return arg1;
2998	case CEXPR_ATTR:
2999		expr->attr = arg1;
3000		expr->op = arg2;
3001		return (uintptr_t) expr;
3002	case CEXPR_NAMES:
3003		add = 1;
3004		expr->attr = arg1;
3005		expr->op = arg2;
3006		ebitmap_init(&negset);
3007		while ((id = (char *)queue_remove(id_queue))) {
3008			if (expr->attr & CEXPR_USER) {
3009				if (!is_id_in_scope(SYM_USERS, id)) {
3010					yyerror2("user %s is not within scope",
3011						 id);
3012					constraint_expr_destroy(expr);
3013					return 0;
3014				}
3015				user =
3016				    (user_datum_t *) hashtab_search(policydbp->
3017								    p_users.
3018								    table,
3019								    (hashtab_key_t)
3020								    id);
3021				if (!user) {
3022					yyerror2("unknown user %s", id);
3023					constraint_expr_destroy(expr);
3024					return 0;
3025				}
3026				val = user->s.value;
3027			} else if (expr->attr & CEXPR_ROLE) {
3028				if (!is_id_in_scope(SYM_ROLES, id)) {
3029					yyerror2("role %s is not within scope",
3030						 id);
3031					constraint_expr_destroy(expr);
3032					return 0;
3033				}
3034				role =
3035				    (role_datum_t *) hashtab_search(policydbp->
3036								    p_roles.
3037								    table,
3038								    (hashtab_key_t)
3039								    id);
3040				if (!role) {
3041					yyerror2("unknown role %s", id);
3042					constraint_expr_destroy(expr);
3043					return 0;
3044				}
3045				val = role->s.value;
3046			} else if (expr->attr & CEXPR_TYPE) {
3047				if (set_types(expr->type_names, id, &add, 0)) {
3048					constraint_expr_destroy(expr);
3049					return 0;
3050				}
3051				continue;
3052			} else {
3053				yyerror("invalid constraint expression");
3054				constraint_expr_destroy(expr);
3055				return 0;
3056			}
3057			if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3058				yyerror("out of memory");
3059				ebitmap_destroy(&expr->names);
3060				constraint_expr_destroy(expr);
3061				return 0;
3062			}
3063			free(id);
3064		}
3065		ebitmap_destroy(&negset);
3066		return (uintptr_t) expr;
3067	default:
3068		yyerror("invalid constraint expression");
3069		constraint_expr_destroy(expr);
3070		return 0;
3071	}
3072
3073	yyerror("invalid constraint expression");
3074	free(expr);
3075	return 0;
3076}
3077
3078int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
3079{
3080	cond_expr_t *e;
3081	int depth;
3082	cond_node_t cn, *cn_old;
3083
3084	/* expression cannot be NULL */
3085	if (!expr) {
3086		yyerror("illegal conditional expression");
3087		return -1;
3088	}
3089	if (!t) {
3090		if (!f) {
3091			/* empty is fine, destroy expression and return */
3092			cond_expr_destroy(expr);
3093			return 0;
3094		}
3095		/* Invert */
3096		t = f;
3097		f = 0;
3098		expr = define_cond_expr(COND_NOT, expr, 0);
3099		if (!expr) {
3100			yyerror("unable to invert");
3101			return -1;
3102		}
3103	}
3104
3105	/* verify expression */
3106	depth = -1;
3107	for (e = expr; e; e = e->next) {
3108		switch (e->expr_type) {
3109		case COND_NOT:
3110			if (depth < 0) {
3111				yyerror
3112				    ("illegal conditional expression; Bad NOT");
3113				return -1;
3114			}
3115			break;
3116		case COND_AND:
3117		case COND_OR:
3118		case COND_XOR:
3119		case COND_EQ:
3120		case COND_NEQ:
3121			if (depth < 1) {
3122				yyerror
3123				    ("illegal conditional expression; Bad binary op");
3124				return -1;
3125			}
3126			depth--;
3127			break;
3128		case COND_BOOL:
3129			if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3130				yyerror
3131				    ("conditional expression is like totally too deep");
3132				return -1;
3133			}
3134			depth++;
3135			break;
3136		default:
3137			yyerror("illegal conditional expression");
3138			return -1;
3139		}
3140	}
3141	if (depth != 0) {
3142		yyerror("illegal conditional expression");
3143		return -1;
3144	}
3145
3146	/*  use tmp conditional node to partially build new node */
3147	memset(&cn, 0, sizeof(cn));
3148	cn.expr = expr;
3149	cn.avtrue_list = t;
3150	cn.avfalse_list = f;
3151
3152	/* normalize/precompute expression */
3153	if (cond_normalize_expr(policydbp, &cn) < 0) {
3154		yyerror("problem normalizing conditional expression");
3155		return -1;
3156	}
3157
3158	/* get the existing conditional node, or create a new one */
3159	cn_old = get_current_cond_list(&cn);
3160	if (!cn_old) {
3161		return -1;
3162	}
3163
3164	append_cond_list(&cn);
3165
3166	/* note that there is no check here for duplicate rules, nor
3167	 * check that rule already exists in base -- that will be
3168	 * handled during conditional expansion, in expand.c */
3169
3170	cn.avtrue_list = NULL;
3171	cn.avfalse_list = NULL;
3172	cond_node_destroy(&cn);
3173
3174	return 0;
3175}
3176
3177cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
3178{
3179	struct cond_expr *expr, *e1 = NULL, *e2;
3180	cond_bool_datum_t *bool_var;
3181	char *id;
3182
3183	/* expressions are handled in the second pass */
3184	if (pass == 1) {
3185		if (expr_type == COND_BOOL) {
3186			while ((id = queue_remove(id_queue))) {
3187				free(id);
3188			}
3189		}
3190		return (cond_expr_t *) 1;	/* any non-NULL value */
3191	}
3192
3193	/* create a new expression struct */
3194	expr = malloc(sizeof(struct cond_expr));
3195	if (!expr) {
3196		yyerror("out of memory");
3197		return NULL;
3198	}
3199	memset(expr, 0, sizeof(cond_expr_t));
3200	expr->expr_type = expr_type;
3201
3202	/* create the type asked for */
3203	switch (expr_type) {
3204	case COND_NOT:
3205		e1 = NULL;
3206		e2 = (struct cond_expr *)arg1;
3207		while (e2) {
3208			e1 = e2;
3209			e2 = e2->next;
3210		}
3211		if (!e1 || e1->next) {
3212			yyerror("illegal conditional NOT expression");
3213			free(expr);
3214			return NULL;
3215		}
3216		e1->next = expr;
3217		return (struct cond_expr *)arg1;
3218	case COND_AND:
3219	case COND_OR:
3220	case COND_XOR:
3221	case COND_EQ:
3222	case COND_NEQ:
3223		e1 = NULL;
3224		e2 = (struct cond_expr *)arg1;
3225		while (e2) {
3226			e1 = e2;
3227			e2 = e2->next;
3228		}
3229		if (!e1 || e1->next) {
3230			yyerror
3231			    ("illegal left side of conditional binary op expression");
3232			free(expr);
3233			return NULL;
3234		}
3235		e1->next = (struct cond_expr *)arg2;
3236
3237		e1 = NULL;
3238		e2 = (struct cond_expr *)arg2;
3239		while (e2) {
3240			e1 = e2;
3241			e2 = e2->next;
3242		}
3243		if (!e1 || e1->next) {
3244			yyerror
3245			    ("illegal right side of conditional binary op expression");
3246			free(expr);
3247			return NULL;
3248		}
3249		e1->next = expr;
3250		return (struct cond_expr *)arg1;
3251	case COND_BOOL:
3252		id = (char *)queue_remove(id_queue);
3253		if (!id) {
3254			yyerror("bad conditional; expected boolean id");
3255			free(id);
3256			free(expr);
3257			return NULL;
3258		}
3259		if (!is_id_in_scope(SYM_BOOLS, id)) {
3260			yyerror2("boolean %s is not within scope", id);
3261			free(id);
3262			free(expr);
3263			return NULL;
3264		}
3265		bool_var =
3266		    (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
3267							 table,
3268							 (hashtab_key_t) id);
3269		if (!bool_var) {
3270			yyerror2("unknown boolean %s in conditional expression",
3271				 id);
3272			free(expr);
3273			free(id);
3274			return NULL;
3275		}
3276		expr->bool = bool_var->s.value;
3277		free(id);
3278		return expr;
3279	default:
3280		yyerror("illegal conditional expression");
3281		return NULL;
3282	}
3283}
3284
3285static int set_user_roles(role_set_t * set, char *id)
3286{
3287	role_datum_t *r;
3288	unsigned int i;
3289	ebitmap_node_t *node;
3290
3291	if (strcmp(id, "*") == 0) {
3292		free(id);
3293		yyerror("* is not allowed in user declarations");
3294		return -1;
3295	}
3296
3297	if (strcmp(id, "~") == 0) {
3298		free(id);
3299		yyerror("~ is not allowed in user declarations");
3300		return -1;
3301	}
3302
3303	if (!is_id_in_scope(SYM_ROLES, id)) {
3304		yyerror2("role %s is not within scope", id);
3305		free(id);
3306		return -1;
3307	}
3308	r = hashtab_search(policydbp->p_roles.table, id);
3309	if (!r) {
3310		yyerror2("unknown role %s", id);
3311		free(id);
3312		return -1;
3313	}
3314
3315	/* set the role and every role it dominates */
3316	ebitmap_for_each_bit(&r->dominates, node, i) {
3317		if (ebitmap_node_get_bit(node, i))
3318			if (ebitmap_set_bit(&set->roles, i, TRUE))
3319				goto oom;
3320	}
3321	free(id);
3322	return 0;
3323      oom:
3324	yyerror("out of memory");
3325	return -1;
3326}
3327
3328static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
3329{
3330	cat_datum_t *cdatum;
3331	int range_start, range_end, i;
3332
3333	if (id_has_dot(id)) {
3334		char *id_start = id;
3335		char *id_end = strchr(id, '.');
3336
3337		*(id_end++) = '\0';
3338
3339		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3340							(hashtab_key_t)
3341							id_start);
3342		if (!cdatum) {
3343			yyerror2("unknown category %s", id_start);
3344			return -1;
3345		}
3346		range_start = cdatum->s.value - 1;
3347		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3348							(hashtab_key_t) id_end);
3349		if (!cdatum) {
3350			yyerror2("unknown category %s", id_end);
3351			return -1;
3352		}
3353		range_end = cdatum->s.value - 1;
3354
3355		if (range_end < range_start) {
3356			yyerror2("category range is invalid");
3357			return -1;
3358		}
3359	} else {
3360		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3361							(hashtab_key_t) id);
3362		if (!cdatum) {
3363			yyerror2("unknown category %s", id);
3364			return -1;
3365		}
3366		range_start = range_end = cdatum->s.value - 1;
3367	}
3368
3369	for (i = range_start; i <= range_end; i++) {
3370		if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
3371			uint32_t level_value = levdatum->level->sens - 1;
3372			policydb_index_others(NULL, policydbp, 0);
3373			yyerror2("category %s can not be associated "
3374				 "with level %s",
3375				 policydbp->p_cat_val_to_name[i],
3376				 policydbp->p_sens_val_to_name[level_value]);
3377			return -1;
3378		}
3379		if (ebitmap_set_bit(cats, i, TRUE)) {
3380			yyerror("out of memory");
3381			return -1;
3382		}
3383	}
3384
3385	return 0;
3386}
3387
3388static int parse_semantic_categories(char *id, level_datum_t * levdatum,
3389				     mls_semantic_cat_t ** cats)
3390{
3391	cat_datum_t *cdatum;
3392	mls_semantic_cat_t *newcat;
3393	unsigned int range_start, range_end;
3394
3395	if (id_has_dot(id)) {
3396		char *id_start = id;
3397		char *id_end = strchr(id, '.');
3398
3399		*(id_end++) = '\0';
3400
3401		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3402							(hashtab_key_t)
3403							id_start);
3404		if (!cdatum) {
3405			yyerror2("unknown category %s", id_start);
3406			return -1;
3407		}
3408		range_start = cdatum->s.value;
3409
3410		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3411							(hashtab_key_t) id_end);
3412		if (!cdatum) {
3413			yyerror2("unknown category %s", id_end);
3414			return -1;
3415		}
3416		range_end = cdatum->s.value;
3417	} else {
3418		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3419							(hashtab_key_t) id);
3420		if (!cdatum) {
3421			yyerror2("unknown category %s", id);
3422			return -1;
3423		}
3424		range_start = range_end = cdatum->s.value;
3425	}
3426
3427	newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
3428	if (!newcat) {
3429		yyerror("out of memory");
3430		return -1;
3431	}
3432
3433	mls_semantic_cat_init(newcat);
3434	newcat->next = *cats;
3435	newcat->low = range_start;
3436	newcat->high = range_end;
3437
3438	*cats = newcat;
3439
3440	return 0;
3441}
3442
3443int define_user(void)
3444{
3445	char *id;
3446	user_datum_t *usrdatum;
3447	level_datum_t *levdatum;
3448	int l;
3449
3450	if (pass == 1) {
3451		while ((id = queue_remove(id_queue)))
3452			free(id);
3453		if (mlspol) {
3454			while ((id = queue_remove(id_queue)))
3455				free(id);
3456			id = queue_remove(id_queue);
3457			free(id);
3458			for (l = 0; l < 2; l++) {
3459				while ((id = queue_remove(id_queue))) {
3460					free(id);
3461				}
3462				id = queue_remove(id_queue);
3463				if (!id)
3464					break;
3465				free(id);
3466			}
3467		}
3468		return 0;
3469	}
3470
3471	if ((usrdatum = declare_user()) == NULL) {
3472		return -1;
3473	}
3474
3475	while ((id = queue_remove(id_queue))) {
3476		if (set_user_roles(&usrdatum->roles, id))
3477			continue;
3478	}
3479
3480	if (mlspol) {
3481		id = queue_remove(id_queue);
3482		if (!id) {
3483			yyerror("no default level specified for user");
3484			return -1;
3485		}
3486
3487		levdatum = (level_datum_t *)
3488		    hashtab_search(policydbp->p_levels.table,
3489				   (hashtab_key_t) id);
3490		if (!levdatum) {
3491			yyerror2("unknown sensitivity %s used in user"
3492				 " level definition", id);
3493			free(id);
3494			return -1;
3495		}
3496		free(id);
3497
3498		usrdatum->dfltlevel.sens = levdatum->level->sens;
3499
3500		while ((id = queue_remove(id_queue))) {
3501			if (parse_semantic_categories(id, levdatum,
3502			                            &usrdatum->dfltlevel.cat)) {
3503				free(id);
3504				return -1;
3505			}
3506			free(id);
3507		}
3508
3509		id = queue_remove(id_queue);
3510
3511		for (l = 0; l < 2; l++) {
3512			levdatum = (level_datum_t *)
3513			    hashtab_search(policydbp->p_levels.table,
3514					   (hashtab_key_t) id);
3515			if (!levdatum) {
3516				yyerror2("unknown sensitivity %s used in user"
3517					 " range definition", id);
3518				free(id);
3519				return -1;
3520			}
3521			free(id);
3522
3523			usrdatum->range.level[l].sens = levdatum->level->sens;
3524
3525			while ((id = queue_remove(id_queue))) {
3526				if (parse_semantic_categories(id, levdatum,
3527				               &usrdatum->range.level[l].cat)) {
3528					free(id);
3529					return -1;
3530				}
3531				free(id);
3532			}
3533
3534			id = queue_remove(id_queue);
3535			if (!id)
3536				break;
3537		}
3538
3539		if (l == 0) {
3540			if (mls_semantic_level_cpy(&usrdatum->range.level[1],
3541			                           &usrdatum->range.level[0])) {
3542				yyerror("out of memory");
3543				return -1;
3544			}
3545		}
3546	}
3547	return 0;
3548}
3549
3550static int parse_security_context(context_struct_t * c)
3551{
3552	char *id;
3553	role_datum_t *role;
3554	type_datum_t *typdatum;
3555	user_datum_t *usrdatum;
3556	level_datum_t *levdatum;
3557	int l;
3558
3559	if (pass == 1) {
3560		id = queue_remove(id_queue);
3561		free(id);	/* user  */
3562		id = queue_remove(id_queue);
3563		free(id);	/* role  */
3564		id = queue_remove(id_queue);
3565		free(id);	/* type  */
3566		if (mlspol) {
3567			id = queue_remove(id_queue);
3568			free(id);
3569			for (l = 0; l < 2; l++) {
3570				while ((id = queue_remove(id_queue))) {
3571					free(id);
3572				}
3573				id = queue_remove(id_queue);
3574				if (!id)
3575					break;
3576				free(id);
3577			}
3578		}
3579		return 0;
3580	}
3581
3582	context_init(c);
3583
3584	/* extract the user */
3585	id = queue_remove(id_queue);
3586	if (!id) {
3587		yyerror("no effective user?");
3588		goto bad;
3589	}
3590	if (!is_id_in_scope(SYM_USERS, id)) {
3591		yyerror2("user %s is not within scope", id);
3592		free(id);
3593		goto bad;
3594	}
3595	usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3596						   (hashtab_key_t) id);
3597	if (!usrdatum) {
3598		yyerror2("user %s is not defined", id);
3599		free(id);
3600		goto bad;
3601	}
3602	c->user = usrdatum->s.value;
3603
3604	/* no need to keep the user name */
3605	free(id);
3606
3607	/* extract the role */
3608	id = (char *)queue_remove(id_queue);
3609	if (!id) {
3610		yyerror("no role name for sid context definition?");
3611		return -1;
3612	}
3613	if (!is_id_in_scope(SYM_ROLES, id)) {
3614		yyerror2("role %s is not within scope", id);
3615		free(id);
3616		return -1;
3617	}
3618	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
3619					       (hashtab_key_t) id);
3620	if (!role) {
3621		yyerror2("role %s is not defined", id);
3622		free(id);
3623		return -1;
3624	}
3625	c->role = role->s.value;
3626
3627	/* no need to keep the role name */
3628	free(id);
3629
3630	/* extract the type */
3631	id = (char *)queue_remove(id_queue);
3632	if (!id) {
3633		yyerror("no type name for sid context definition?");
3634		return -1;
3635	}
3636	if (!is_id_in_scope(SYM_TYPES, id)) {
3637		yyerror2("type %s is not within scope", id);
3638		free(id);
3639		return -1;
3640	}
3641	typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
3642						   (hashtab_key_t) id);
3643	if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
3644		yyerror2("type %s is not defined or is an attribute", id);
3645		free(id);
3646		return -1;
3647	}
3648	c->type = typdatum->s.value;
3649
3650	/* no need to keep the type name */
3651	free(id);
3652
3653	if (mlspol) {
3654		/* extract the low sensitivity */
3655		id = (char *)queue_head(id_queue);
3656		if (!id) {
3657			yyerror("no sensitivity name for sid context"
3658				" definition?");
3659			return -1;
3660		}
3661
3662		id = (char *)queue_remove(id_queue);
3663		for (l = 0; l < 2; l++) {
3664			levdatum = (level_datum_t *)
3665			    hashtab_search(policydbp->p_levels.table,
3666					   (hashtab_key_t) id);
3667			if (!levdatum) {
3668				yyerror2("Sensitivity %s is not defined", id);
3669				free(id);
3670				return -1;
3671			}
3672			free(id);
3673			c->range.level[l].sens = levdatum->level->sens;
3674
3675			/* extract low category set */
3676			while ((id = queue_remove(id_queue))) {
3677				if (parse_categories(id, levdatum,
3678						     &c->range.level[l].cat)) {
3679					free(id);
3680					return -1;
3681				}
3682				free(id);
3683			}
3684
3685			/* extract high sensitivity */
3686			id = (char *)queue_remove(id_queue);
3687			if (!id)
3688				break;
3689		}
3690
3691		if (l == 0) {
3692			c->range.level[1].sens = c->range.level[0].sens;
3693			if (ebitmap_cpy(&c->range.level[1].cat,
3694					&c->range.level[0].cat)) {
3695
3696				yyerror("out of memory");
3697				goto bad;
3698			}
3699		}
3700	}
3701
3702	if (!policydb_context_isvalid(policydbp, c)) {
3703		yyerror("invalid security context");
3704		goto bad;
3705	}
3706	return 0;
3707
3708      bad:
3709	context_destroy(c);
3710
3711	return -1;
3712}
3713
3714int define_initial_sid_context(void)
3715{
3716	char *id;
3717	ocontext_t *c, *head;
3718
3719	if (pass == 1) {
3720		id = (char *)queue_remove(id_queue);
3721		free(id);
3722		parse_security_context(NULL);
3723		return 0;
3724	}
3725
3726	id = (char *)queue_remove(id_queue);
3727	if (!id) {
3728		yyerror("no sid name for SID context definition?");
3729		return -1;
3730	}
3731	head = policydbp->ocontexts[OCON_ISID];
3732	for (c = head; c; c = c->next) {
3733		if (!strcmp(id, c->u.name))
3734			break;
3735	}
3736
3737	if (!c) {
3738		yyerror2("SID %s is not defined", id);
3739		free(id);
3740		return -1;
3741	}
3742	if (c->context[0].user) {
3743		yyerror2("The context for SID %s is multiply defined", id);
3744		free(id);
3745		return -1;
3746	}
3747	/* no need to keep the sid name */
3748	free(id);
3749
3750	if (parse_security_context(&c->context[0]))
3751		return -1;
3752
3753	return 0;
3754}
3755
3756int define_fs_context(unsigned int major, unsigned int minor)
3757{
3758	ocontext_t *newc, *c, *head;
3759
3760	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
3761		yyerror("fscon not supported for target");
3762		return -1;
3763	}
3764
3765	if (pass == 1) {
3766		parse_security_context(NULL);
3767		parse_security_context(NULL);
3768		return 0;
3769	}
3770
3771	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
3772	if (!newc) {
3773		yyerror("out of memory");
3774		return -1;
3775	}
3776	memset(newc, 0, sizeof(ocontext_t));
3777
3778	newc->u.name = (char *)malloc(6);
3779	if (!newc->u.name) {
3780		yyerror("out of memory");
3781		free(newc);
3782		return -1;
3783	}
3784	sprintf(newc->u.name, "%02x:%02x", major, minor);
3785
3786	if (parse_security_context(&newc->context[0])) {
3787		free(newc->u.name);
3788		free(newc);
3789		return -1;
3790	}
3791	if (parse_security_context(&newc->context[1])) {
3792		context_destroy(&newc->context[0]);
3793		free(newc->u.name);
3794		free(newc);
3795		return -1;
3796	}
3797	head = policydbp->ocontexts[OCON_FS];
3798
3799	for (c = head; c; c = c->next) {
3800		if (!strcmp(newc->u.name, c->u.name)) {
3801			yyerror2("duplicate entry for file system %s",
3802				 newc->u.name);
3803			context_destroy(&newc->context[0]);
3804			context_destroy(&newc->context[1]);
3805			free(newc->u.name);
3806			free(newc);
3807			return -1;
3808		}
3809	}
3810
3811	newc->next = head;
3812	policydbp->ocontexts[OCON_FS] = newc;
3813
3814	return 0;
3815}
3816
3817int define_pirq_context(unsigned int pirq)
3818{
3819	ocontext_t *newc, *c, *l, *head;
3820	char *id;
3821
3822	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3823		yyerror("pirqcon not supported for target");
3824		return -1;
3825	}
3826
3827	if (pass == 1) {
3828		id = (char *) queue_remove(id_queue);
3829		free(id);
3830		parse_security_context(NULL);
3831		return 0;
3832	}
3833
3834	newc = malloc(sizeof(ocontext_t));
3835	if (!newc) {
3836		yyerror("out of memory");
3837		return -1;
3838	}
3839	memset(newc, 0, sizeof(ocontext_t));
3840
3841	newc->u.pirq = pirq;
3842
3843	if (parse_security_context(&newc->context[0])) {
3844		free(newc);
3845		return -1;
3846	}
3847
3848	head = policydbp->ocontexts[OCON_XEN_PIRQ];
3849	for (l = NULL, c = head; c; l = c, c = c->next) {
3850		unsigned int pirq2;
3851
3852		pirq2 = c->u.pirq;
3853		if (pirq == pirq2) {
3854			yyerror2("duplicate pirqcon entry for %d ", pirq);
3855			goto bad;
3856		}
3857	}
3858
3859	if (l)
3860		l->next = newc;
3861	else
3862		policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
3863
3864	return 0;
3865
3866bad:
3867	free(newc);
3868	return -1;
3869}
3870
3871int define_iomem_context(unsigned long low, unsigned long high)
3872{
3873	ocontext_t *newc, *c, *l, *head;
3874	char *id;
3875
3876	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3877		yyerror("iomemcon not supported for target");
3878		return -1;
3879	}
3880
3881	if (pass == 1) {
3882		id = (char *)queue_remove(id_queue);
3883		free(id);
3884		parse_security_context(NULL);
3885		return 0;
3886	}
3887
3888	newc = malloc(sizeof(ocontext_t));
3889	if (!newc) {
3890		yyerror("out of memory");
3891		return -1;
3892	}
3893	memset(newc, 0, sizeof(ocontext_t));
3894
3895	newc->u.iomem.low_iomem  = low;
3896	newc->u.iomem.high_iomem = high;
3897
3898	if (low > high) {
3899		yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high);
3900		free(newc);
3901		return -1;
3902	}
3903
3904	if (parse_security_context(&newc->context[0])) {
3905		free(newc);
3906		return -1;
3907	}
3908
3909	head = policydbp->ocontexts[OCON_XEN_IOMEM];
3910	for (l = NULL, c = head; c; l = c, c = c->next) {
3911		unsigned int low2, high2;
3912
3913		low2 = c->u.iomem.low_iomem;
3914		high2 = c->u.iomem.high_iomem;
3915		if (low <= high2 && low2 <= high) {
3916			yyerror2("iomemcon entry for 0x%x-0x%x overlaps with "
3917				"earlier entry 0x%x-0x%x", low, high,
3918				low2, high2);
3919			goto bad;
3920		}
3921	}
3922
3923	if (l)
3924		l->next = newc;
3925	else
3926		policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
3927
3928	return 0;
3929
3930bad:
3931	free(newc);
3932	return -1;
3933}
3934
3935int define_ioport_context(unsigned long low, unsigned long high)
3936{
3937	ocontext_t *newc, *c, *l, *head;
3938	char *id;
3939
3940	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3941		yyerror("ioportcon not supported for target");
3942		return -1;
3943	}
3944
3945	if (pass == 1) {
3946		id = (char *)queue_remove(id_queue);
3947		free(id);
3948		parse_security_context(NULL);
3949		return 0;
3950	}
3951
3952	newc = malloc(sizeof(ocontext_t));
3953	if (!newc) {
3954		yyerror("out of memory");
3955		return -1;
3956	}
3957	memset(newc, 0, sizeof(ocontext_t));
3958
3959	newc->u.ioport.low_ioport  = low;
3960	newc->u.ioport.high_ioport = high;
3961
3962	if (low > high) {
3963		yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high);
3964		free(newc);
3965		return -1;
3966	}
3967
3968	if (parse_security_context(&newc->context[0])) {
3969		free(newc);
3970		return -1;
3971	}
3972
3973	head = policydbp->ocontexts[OCON_XEN_IOPORT];
3974	for (l = NULL, c = head; c; l = c, c = c->next) {
3975		unsigned int low2, high2;
3976
3977		low2 = c->u.ioport.low_ioport;
3978		high2 = c->u.ioport.high_ioport;
3979		if (low <= high2 && low2 <= high) {
3980			yyerror2("ioportcon entry for 0x%x-0x%x overlaps with"
3981				"earlier entry 0x%x-0x%x", low, high,
3982				low2, high2);
3983			goto bad;
3984		}
3985	}
3986
3987	if (l)
3988		l->next = newc;
3989	else
3990		policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
3991
3992	return 0;
3993
3994bad:
3995	free(newc);
3996	return -1;
3997}
3998
3999int define_pcidevice_context(unsigned long device)
4000{
4001	ocontext_t *newc, *c, *l, *head;
4002	char *id;
4003
4004	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4005		yyerror("pcidevicecon not supported for target");
4006		return -1;
4007	}
4008
4009	if (pass == 1) {
4010		id = (char *) queue_remove(id_queue);
4011		free(id);
4012		parse_security_context(NULL);
4013		return 0;
4014	}
4015
4016	newc = malloc(sizeof(ocontext_t));
4017	if (!newc) {
4018		yyerror("out of memory");
4019		return -1;
4020	}
4021	memset(newc, 0, sizeof(ocontext_t));
4022
4023	newc->u.device = device;
4024
4025	if (parse_security_context(&newc->context[0])) {
4026		free(newc);
4027		return -1;
4028	}
4029
4030	head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
4031	for (l = NULL, c = head; c; l = c, c = c->next) {
4032		unsigned int device2;
4033
4034		device2 = c->u.device;
4035		if (device == device2) {
4036			yyerror2("duplicate pcidevicecon entry for 0x%x ",
4037				 device);
4038			goto bad;
4039		}
4040	}
4041
4042	if (l)
4043		l->next = newc;
4044	else
4045		policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
4046
4047	return 0;
4048
4049bad:
4050	free(newc);
4051	return -1;
4052}
4053
4054int define_port_context(unsigned int low, unsigned int high)
4055{
4056	ocontext_t *newc, *c, *l, *head;
4057	unsigned int protocol;
4058	char *id;
4059
4060	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4061		yyerror("portcon not supported for target");
4062		return -1;
4063	}
4064
4065	if (pass == 1) {
4066		id = (char *)queue_remove(id_queue);
4067		free(id);
4068		parse_security_context(NULL);
4069		return 0;
4070	}
4071
4072	newc = malloc(sizeof(ocontext_t));
4073	if (!newc) {
4074		yyerror("out of memory");
4075		return -1;
4076	}
4077	memset(newc, 0, sizeof(ocontext_t));
4078
4079	id = (char *)queue_remove(id_queue);
4080	if (!id) {
4081		free(newc);
4082		return -1;
4083	}
4084	if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4085		protocol = IPPROTO_TCP;
4086	} else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4087		protocol = IPPROTO_UDP;
4088	} else {
4089		yyerror2("unrecognized protocol %s", id);
4090		free(newc);
4091		return -1;
4092	}
4093
4094	newc->u.port.protocol = protocol;
4095	newc->u.port.low_port = low;
4096	newc->u.port.high_port = high;
4097
4098	if (low > high) {
4099		yyerror2("low port %d exceeds high port %d", low, high);
4100		free(newc);
4101		return -1;
4102	}
4103
4104	if (parse_security_context(&newc->context[0])) {
4105		free(newc);
4106		return -1;
4107	}
4108
4109	/* Preserve the matching order specified in the configuration. */
4110	head = policydbp->ocontexts[OCON_PORT];
4111	for (l = NULL, c = head; c; l = c, c = c->next) {
4112		unsigned int prot2, low2, high2;
4113
4114		prot2 = c->u.port.protocol;
4115		low2 = c->u.port.low_port;
4116		high2 = c->u.port.high_port;
4117		if (protocol != prot2)
4118			continue;
4119		if (low == low2 && high == high2) {
4120			yyerror2("duplicate portcon entry for %s %d-%d ", id,
4121				 low, high);
4122			goto bad;
4123		}
4124		if (low2 <= low && high2 >= high) {
4125			yyerror2("portcon entry for %s %d-%d hidden by earlier "
4126				 "entry for %d-%d", id, low, high, low2, high2);
4127			goto bad;
4128		}
4129	}
4130
4131	if (l)
4132		l->next = newc;
4133	else
4134		policydbp->ocontexts[OCON_PORT] = newc;
4135
4136	return 0;
4137
4138      bad:
4139	free(newc);
4140	return -1;
4141}
4142
4143int define_netif_context(void)
4144{
4145	ocontext_t *newc, *c, *head;
4146
4147	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4148		yyerror("netifcon not supported for target");
4149		return -1;
4150	}
4151
4152	if (pass == 1) {
4153		free(queue_remove(id_queue));
4154		parse_security_context(NULL);
4155		parse_security_context(NULL);
4156		return 0;
4157	}
4158
4159	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4160	if (!newc) {
4161		yyerror("out of memory");
4162		return -1;
4163	}
4164	memset(newc, 0, sizeof(ocontext_t));
4165
4166	newc->u.name = (char *)queue_remove(id_queue);
4167	if (!newc->u.name) {
4168		free(newc);
4169		return -1;
4170	}
4171	if (parse_security_context(&newc->context[0])) {
4172		free(newc->u.name);
4173		free(newc);
4174		return -1;
4175	}
4176	if (parse_security_context(&newc->context[1])) {
4177		context_destroy(&newc->context[0]);
4178		free(newc->u.name);
4179		free(newc);
4180		return -1;
4181	}
4182	head = policydbp->ocontexts[OCON_NETIF];
4183
4184	for (c = head; c; c = c->next) {
4185		if (!strcmp(newc->u.name, c->u.name)) {
4186			yyerror2("duplicate entry for network interface %s",
4187				 newc->u.name);
4188			context_destroy(&newc->context[0]);
4189			context_destroy(&newc->context[1]);
4190			free(newc->u.name);
4191			free(newc);
4192			return -1;
4193		}
4194	}
4195
4196	newc->next = head;
4197	policydbp->ocontexts[OCON_NETIF] = newc;
4198	return 0;
4199}
4200
4201int define_ipv4_node_context()
4202{
4203	char *id;
4204	int rc = 0;
4205	struct in_addr addr, mask;
4206	ocontext_t *newc, *c, *l, *head;
4207
4208	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4209		yyerror("nodecon not supported for target");
4210		return -1;
4211	}
4212
4213	if (pass == 1) {
4214		free(queue_remove(id_queue));
4215		free(queue_remove(id_queue));
4216		parse_security_context(NULL);
4217		goto out;
4218	}
4219
4220	id = queue_remove(id_queue);
4221	if (!id) {
4222		yyerror("failed to read ipv4 address");
4223		rc = -1;
4224		goto out;
4225	}
4226
4227	rc = inet_pton(AF_INET, id, &addr);
4228	free(id);
4229	if (rc < 1) {
4230		yyerror("failed to parse ipv4 address");
4231		if (rc == 0)
4232			rc = -1;
4233		goto out;
4234	}
4235
4236	id = queue_remove(id_queue);
4237	if (!id) {
4238		yyerror("failed to read ipv4 address");
4239		rc = -1;
4240		goto out;
4241	}
4242
4243	rc = inet_pton(AF_INET, id, &mask);
4244	free(id);
4245	if (rc < 1) {
4246		yyerror("failed to parse ipv4 mask");
4247		if (rc == 0)
4248			rc = -1;
4249		goto out;
4250	}
4251
4252	newc = malloc(sizeof(ocontext_t));
4253	if (!newc) {
4254		yyerror("out of memory");
4255		rc = -1;
4256		goto out;
4257	}
4258
4259	memset(newc, 0, sizeof(ocontext_t));
4260	newc->u.node.addr = addr.s_addr;
4261	newc->u.node.mask = mask.s_addr;
4262
4263	if (parse_security_context(&newc->context[0])) {
4264		free(newc);
4265		return -1;
4266	}
4267
4268	/* Create order of most specific to least retaining
4269	   the order specified in the configuration. */
4270	head = policydbp->ocontexts[OCON_NODE];
4271	for (l = NULL, c = head; c; l = c, c = c->next) {
4272		if (newc->u.node.mask > c->u.node.mask)
4273			break;
4274	}
4275
4276	newc->next = c;
4277
4278	if (l)
4279		l->next = newc;
4280	else
4281		policydbp->ocontexts[OCON_NODE] = newc;
4282	rc = 0;
4283out:
4284	return rc;
4285}
4286
4287int define_ipv6_node_context(void)
4288{
4289	char *id;
4290	int rc = 0;
4291	struct in6_addr addr, mask;
4292	ocontext_t *newc, *c, *l, *head;
4293
4294	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4295		yyerror("nodecon not supported for target");
4296		return -1;
4297	}
4298
4299	if (pass == 1) {
4300		free(queue_remove(id_queue));
4301		free(queue_remove(id_queue));
4302		parse_security_context(NULL);
4303		goto out;
4304	}
4305
4306	id = queue_remove(id_queue);
4307	if (!id) {
4308		yyerror("failed to read ipv6 address");
4309		rc = -1;
4310		goto out;
4311	}
4312
4313	rc = inet_pton(AF_INET6, id, &addr);
4314	free(id);
4315	if (rc < 1) {
4316		yyerror("failed to parse ipv6 address");
4317		if (rc == 0)
4318			rc = -1;
4319		goto out;
4320	}
4321
4322	id = queue_remove(id_queue);
4323	if (!id) {
4324		yyerror("failed to read ipv6 address");
4325		rc = -1;
4326		goto out;
4327	}
4328
4329	rc = inet_pton(AF_INET6, id, &mask);
4330	free(id);
4331	if (rc < 1) {
4332		yyerror("failed to parse ipv6 mask");
4333		if (rc == 0)
4334			rc = -1;
4335		goto out;
4336	}
4337
4338	newc = malloc(sizeof(ocontext_t));
4339	if (!newc) {
4340		yyerror("out of memory");
4341		rc = -1;
4342		goto out;
4343	}
4344
4345	memset(newc, 0, sizeof(ocontext_t));
4346	memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
4347	memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
4348
4349	if (parse_security_context(&newc->context[0])) {
4350		free(newc);
4351		rc = -1;
4352		goto out;
4353	}
4354
4355	/* Create order of most specific to least retaining
4356	   the order specified in the configuration. */
4357	head = policydbp->ocontexts[OCON_NODE6];
4358	for (l = NULL, c = head; c; l = c, c = c->next) {
4359		if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
4360			break;
4361	}
4362
4363	newc->next = c;
4364
4365	if (l)
4366		l->next = newc;
4367	else
4368		policydbp->ocontexts[OCON_NODE6] = newc;
4369
4370	rc = 0;
4371      out:
4372	return rc;
4373}
4374
4375int define_fs_use(int behavior)
4376{
4377	ocontext_t *newc, *c, *head;
4378
4379	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4380		yyerror("fsuse not supported for target");
4381		return -1;
4382	}
4383
4384	if (pass == 1) {
4385		free(queue_remove(id_queue));
4386		parse_security_context(NULL);
4387		return 0;
4388	}
4389
4390	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4391	if (!newc) {
4392		yyerror("out of memory");
4393		return -1;
4394	}
4395	memset(newc, 0, sizeof(ocontext_t));
4396
4397	newc->u.name = (char *)queue_remove(id_queue);
4398	if (!newc->u.name) {
4399		free(newc);
4400		return -1;
4401	}
4402	newc->v.behavior = behavior;
4403	if (parse_security_context(&newc->context[0])) {
4404		free(newc->u.name);
4405		free(newc);
4406		return -1;
4407	}
4408
4409	head = policydbp->ocontexts[OCON_FSUSE];
4410
4411	for (c = head; c; c = c->next) {
4412		if (!strcmp(newc->u.name, c->u.name)) {
4413			yyerror2("duplicate fs_use entry for filesystem type %s",
4414				 newc->u.name);
4415			context_destroy(&newc->context[0]);
4416			free(newc->u.name);
4417			free(newc);
4418			return -1;
4419		}
4420	}
4421
4422	newc->next = head;
4423	policydbp->ocontexts[OCON_FSUSE] = newc;
4424	return 0;
4425}
4426
4427int define_genfs_context_helper(char *fstype, int has_type)
4428{
4429	struct genfs *genfs_p, *genfs, *newgenfs;
4430	ocontext_t *newc, *c, *head, *p;
4431	char *type = NULL;
4432	int len, len2;
4433
4434	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4435		yyerror("genfs not supported for target");
4436		return -1;
4437	}
4438
4439	if (pass == 1) {
4440		free(fstype);
4441		free(queue_remove(id_queue));
4442		if (has_type)
4443			free(queue_remove(id_queue));
4444		parse_security_context(NULL);
4445		return 0;
4446	}
4447
4448	for (genfs_p = NULL, genfs = policydbp->genfs;
4449	     genfs; genfs_p = genfs, genfs = genfs->next) {
4450		if (strcmp(fstype, genfs->fstype) <= 0)
4451			break;
4452	}
4453
4454	if (!genfs || strcmp(fstype, genfs->fstype)) {
4455		newgenfs = malloc(sizeof(struct genfs));
4456		if (!newgenfs) {
4457			yyerror("out of memory");
4458			return -1;
4459		}
4460		memset(newgenfs, 0, sizeof(struct genfs));
4461		newgenfs->fstype = fstype;
4462		newgenfs->next = genfs;
4463		if (genfs_p)
4464			genfs_p->next = newgenfs;
4465		else
4466			policydbp->genfs = newgenfs;
4467		genfs = newgenfs;
4468	}
4469
4470	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4471	if (!newc) {
4472		yyerror("out of memory");
4473		return -1;
4474	}
4475	memset(newc, 0, sizeof(ocontext_t));
4476
4477	newc->u.name = (char *)queue_remove(id_queue);
4478	if (!newc->u.name)
4479		goto fail;
4480	if (has_type) {
4481		type = (char *)queue_remove(id_queue);
4482		if (!type)
4483			goto fail;
4484		if (type[1] != 0) {
4485			yyerror2("invalid type %s", type);
4486			goto fail;
4487		}
4488		switch (type[0]) {
4489		case 'b':
4490			newc->v.sclass = SECCLASS_BLK_FILE;
4491			break;
4492		case 'c':
4493			newc->v.sclass = SECCLASS_CHR_FILE;
4494			break;
4495		case 'd':
4496			newc->v.sclass = SECCLASS_DIR;
4497			break;
4498		case 'p':
4499			newc->v.sclass = SECCLASS_FIFO_FILE;
4500			break;
4501		case 'l':
4502			newc->v.sclass = SECCLASS_LNK_FILE;
4503			break;
4504		case 's':
4505			newc->v.sclass = SECCLASS_SOCK_FILE;
4506			break;
4507		case '-':
4508			newc->v.sclass = SECCLASS_FILE;
4509			break;
4510		default:
4511			yyerror2("invalid type %s", type);
4512			goto fail;
4513		}
4514	}
4515	if (parse_security_context(&newc->context[0]))
4516		goto fail;
4517
4518	head = genfs->head;
4519
4520	for (p = NULL, c = head; c; p = c, c = c->next) {
4521		if (!strcmp(newc->u.name, c->u.name) &&
4522		    (!newc->v.sclass || !c->v.sclass
4523		     || newc->v.sclass == c->v.sclass)) {
4524			yyerror2("duplicate entry for genfs entry (%s, %s)",
4525				 fstype, newc->u.name);
4526			goto fail;
4527		}
4528		len = strlen(newc->u.name);
4529		len2 = strlen(c->u.name);
4530		if (len > len2)
4531			break;
4532	}
4533
4534	newc->next = c;
4535	if (p)
4536		p->next = newc;
4537	else
4538		genfs->head = newc;
4539	return 0;
4540      fail:
4541	if (type)
4542		free(type);
4543	context_destroy(&newc->context[0]);
4544	if (fstype)
4545		free(fstype);
4546	if (newc->u.name)
4547		free(newc->u.name);
4548	free(newc);
4549	return -1;
4550}
4551
4552int define_genfs_context(int has_type)
4553{
4554	return define_genfs_context_helper(queue_remove(id_queue), has_type);
4555}
4556
4557int define_range_trans(int class_specified)
4558{
4559	char *id;
4560	level_datum_t *levdatum = 0;
4561	class_datum_t *cladatum;
4562	range_trans_rule_t *rule;
4563	int l, add = 1;
4564
4565	if (!mlspol) {
4566		yyerror("range_transition rule in non-MLS configuration");
4567		return -1;
4568	}
4569
4570	if (pass == 1) {
4571		while ((id = queue_remove(id_queue)))
4572			free(id);
4573		while ((id = queue_remove(id_queue)))
4574			free(id);
4575		if (class_specified)
4576			while ((id = queue_remove(id_queue)))
4577				free(id);
4578		id = queue_remove(id_queue);
4579		free(id);
4580		for (l = 0; l < 2; l++) {
4581			while ((id = queue_remove(id_queue))) {
4582				free(id);
4583			}
4584			id = queue_remove(id_queue);
4585			if (!id)
4586				break;
4587			free(id);
4588		}
4589		return 0;
4590	}
4591
4592	rule = malloc(sizeof(struct range_trans_rule));
4593	if (!rule) {
4594		yyerror("out of memory");
4595		return -1;
4596	}
4597	range_trans_rule_init(rule);
4598
4599	while ((id = queue_remove(id_queue))) {
4600		if (set_types(&rule->stypes, id, &add, 0))
4601			goto out;
4602	}
4603	add = 1;
4604	while ((id = queue_remove(id_queue))) {
4605		if (set_types(&rule->ttypes, id, &add, 0))
4606			goto out;
4607	}
4608
4609	if (class_specified) {
4610		if (read_classes(&rule->tclasses))
4611			goto out;
4612	} else {
4613		cladatum = hashtab_search(policydbp->p_classes.table,
4614		                          "process");
4615		if (!cladatum) {
4616			yyerror2("could not find process class for "
4617			         "legacy range_transition statement");
4618			goto out;
4619		}
4620
4621		ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
4622	}
4623
4624	id = (char *)queue_remove(id_queue);
4625	if (!id) {
4626		yyerror("no range in range_transition definition?");
4627		goto out;
4628	}
4629	for (l = 0; l < 2; l++) {
4630		levdatum = hashtab_search(policydbp->p_levels.table, id);
4631		if (!levdatum) {
4632			yyerror2("unknown level %s used in range_transition "
4633			         "definition", id);
4634			free(id);
4635			goto out;
4636		}
4637		free(id);
4638
4639		rule->trange.level[l].sens = levdatum->level->sens;
4640
4641		while ((id = queue_remove(id_queue))) {
4642			if (parse_semantic_categories(id, levdatum,
4643			                          &rule->trange.level[l].cat)) {
4644				free(id);
4645				goto out;
4646			}
4647			free(id);
4648		}
4649
4650		id = (char *)queue_remove(id_queue);
4651		if (!id)
4652			break;
4653	}
4654	if (l == 0) {
4655		if (mls_semantic_level_cpy(&rule->trange.level[1],
4656		                           &rule->trange.level[0])) {
4657			yyerror("out of memory");
4658			goto out;
4659		}
4660	}
4661
4662	append_range_trans(rule);
4663	return 0;
4664
4665out:
4666	range_trans_rule_destroy(rule);
4667	return -1;
4668}
4669
4670/* FLASK */
4671