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