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