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