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