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