policy_define.c revision f7917ea9cf6af752de98a1e742152d813028c669
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:	 	break;
1019		case 1:{
1020				/* ret == 1 means the alias was required and therefore already
1021				 * has a value. Set it up as an alias with a different primary. */
1022				type_datum_destroy(aliasdatum);
1023				free(aliasdatum);
1024
1025				aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id);
1026				assert(aliasdatum);
1027
1028				aliasdatum->primary = type->s.value;
1029				aliasdatum->flavor = TYPE_ALIAS;
1030
1031				break;
1032			}
1033		default:{
1034				assert(0);	/* should never get here */
1035			}
1036		}
1037	}
1038	return 0;
1039      cleanup:
1040	free(id);
1041	type_datum_destroy(aliasdatum);
1042	free(aliasdatum);
1043	return -1;
1044}
1045
1046int define_typealias(void)
1047{
1048	char *id;
1049	type_datum_t *t;
1050
1051	if (pass == 2) {
1052		while ((id = queue_remove(id_queue)))
1053			free(id);
1054		return 0;
1055	}
1056
1057	id = (char *)queue_remove(id_queue);
1058	if (!id) {
1059		yyerror("no type name for typealias definition?");
1060		return -1;
1061	}
1062
1063	if (!is_id_in_scope(SYM_TYPES, id)) {
1064		yyerror2("type %s is not within scope", id);
1065		free(id);
1066		return -1;
1067	}
1068	t = hashtab_search(policydbp->p_types.table, id);
1069	if (!t || t->flavor == TYPE_ATTRIB) {
1070		yyerror2("unknown type %s, or it was already declared as an "
1071			 "attribute", id);
1072		free(id);
1073		return -1;
1074	}
1075	return add_aliases_to_type(t);
1076}
1077
1078int define_typeattribute(void)
1079{
1080	char *id;
1081	type_datum_t *t, *attr;
1082
1083	if (pass == 2) {
1084		while ((id = queue_remove(id_queue)))
1085			free(id);
1086		return 0;
1087	}
1088
1089	id = (char *)queue_remove(id_queue);
1090	if (!id) {
1091		yyerror("no type name for typeattribute definition?");
1092		return -1;
1093	}
1094
1095	if (!is_id_in_scope(SYM_TYPES, id)) {
1096		yyerror2("type %s is not within scope", id);
1097		free(id);
1098		return -1;
1099	}
1100	t = hashtab_search(policydbp->p_types.table, id);
1101	if (!t || t->flavor == TYPE_ATTRIB) {
1102		yyerror2("unknown type %s", id);
1103		free(id);
1104		return -1;
1105	}
1106
1107	while ((id = queue_remove(id_queue))) {
1108		if (!is_id_in_scope(SYM_TYPES, id)) {
1109			yyerror2("attribute %s is not within scope", id);
1110			free(id);
1111			return -1;
1112		}
1113		attr = hashtab_search(policydbp->p_types.table, id);
1114		if (!attr) {
1115			/* treat it as a fatal error */
1116			yyerror2("attribute %s is not declared", id);
1117			free(id);
1118			return -1;
1119		}
1120
1121		if (attr->flavor != TYPE_ATTRIB) {
1122			yyerror2("%s is a type, not an attribute", id);
1123			free(id);
1124			return -1;
1125		}
1126
1127		if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1128			yyerror("Out of memory!");
1129			return -1;
1130		}
1131
1132		if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
1133			yyerror("out of memory");
1134			return -1;
1135		}
1136	}
1137
1138	return 0;
1139}
1140
1141static int define_typebounds_helper(char *bounds_id, char *type_id)
1142{
1143	type_datum_t *bounds, *type;
1144
1145	if (!is_id_in_scope(SYM_TYPES, bounds_id)) {
1146		yyerror2("type %s is not within scope", bounds_id);
1147		return -1;
1148	}
1149
1150	bounds = hashtab_search(policydbp->p_types.table, bounds_id);
1151	if (!bounds || bounds->flavor == TYPE_ATTRIB) {
1152		yyerror2("hoge unknown type %s", bounds_id);
1153		return -1;
1154	}
1155
1156	if (!is_id_in_scope(SYM_TYPES, type_id)) {
1157		yyerror2("type %s is not within scope", type_id);
1158		return -1;
1159	}
1160
1161	type = hashtab_search(policydbp->p_types.table, type_id);
1162	if (!type || type->flavor == TYPE_ATTRIB) {
1163		yyerror2("type %s is not declared", type_id);
1164		return -1;
1165	}
1166
1167	if (type->flavor == TYPE_TYPE && !type->primary) {
1168		type = policydbp->type_val_to_struct[type->s.value - 1];
1169	} else if (type->flavor == TYPE_ALIAS) {
1170		type = policydbp->type_val_to_struct[type->primary - 1];
1171	}
1172
1173	if (!type->bounds)
1174		type->bounds = bounds->s.value;
1175	else if (type->bounds != bounds->s.value) {
1176		yyerror2("type %s has inconsistent master {%s,%s}",
1177			 type_id,
1178			 policydbp->p_type_val_to_name[type->bounds - 1],
1179			 policydbp->p_type_val_to_name[bounds->s.value - 1]);
1180		return -1;
1181	}
1182
1183	return 0;
1184}
1185
1186int define_typebounds(void)
1187{
1188	char *bounds, *id;
1189
1190	if (pass == 1) {
1191		while ((id = queue_remove(id_queue)))
1192			free(id);
1193		return 0;
1194	}
1195
1196	bounds = (char *) queue_remove(id_queue);
1197	if (!bounds) {
1198		yyerror("no type name for typebounds definition?");
1199		return -1;
1200	}
1201
1202	while ((id = queue_remove(id_queue))) {
1203		if (define_typebounds_helper(bounds, id))
1204			return -1;
1205		free(id);
1206	}
1207	free(bounds);
1208
1209	return 0;
1210}
1211
1212int define_type(int alias)
1213{
1214	char *id;
1215	type_datum_t *datum, *attr;
1216	int newattr = 0;
1217
1218	if (pass == 2) {
1219		/*
1220		 * If type name contains ".", we have to define boundary
1221		 * relationship implicitly to keep compatibility with
1222		 * old name based hierarchy.
1223		 */
1224		if ((id = queue_remove(id_queue))) {
1225			char *bounds, *delim;
1226
1227			if ((delim = strrchr(id, '.'))
1228			    && (bounds = strdup(id))) {
1229				bounds[(size_t)(delim - id)] = '\0';
1230
1231				if (define_typebounds_helper(bounds, id))
1232					return -1;
1233				free(bounds);
1234			}
1235			free(id);
1236		}
1237
1238		if (alias) {
1239			while ((id = queue_remove(id_queue)))
1240				free(id);
1241		}
1242
1243		while ((id = queue_remove(id_queue)))
1244			free(id);
1245		return 0;
1246	}
1247
1248	if ((datum = declare_type(TRUE, FALSE)) == NULL) {
1249		return -1;
1250	}
1251
1252	if (alias) {
1253		if (add_aliases_to_type(datum) == -1) {
1254			return -1;
1255		}
1256	}
1257
1258	while ((id = queue_remove(id_queue))) {
1259		if (!is_id_in_scope(SYM_TYPES, id)) {
1260			yyerror2("attribute %s is not within scope", id);
1261			free(id);
1262			return -1;
1263		}
1264		attr = hashtab_search(policydbp->p_types.table, id);
1265		if (!attr) {
1266			/* treat it as a fatal error */
1267			yyerror2("attribute %s is not declared", id);
1268			return -1;
1269		} else {
1270			newattr = 0;
1271		}
1272
1273		if (attr->flavor != TYPE_ATTRIB) {
1274			yyerror2("%s is a type, not an attribute", id);
1275			return -1;
1276		}
1277
1278		if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1279			yyerror("Out of memory!");
1280			return -1;
1281		}
1282
1283		if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
1284			yyerror("Out of memory");
1285			return -1;
1286		}
1287	}
1288
1289	return 0;
1290}
1291
1292struct val_to_name {
1293	unsigned int val;
1294	char *name;
1295};
1296
1297/* Adds a type, given by its textual name, to a typeset.  If *add is
1298   0, then add the type to the negative set; otherwise if *add is 1
1299   then add it to the positive side. */
1300static int set_types(type_set_t * set, char *id, int *add, char starallowed)
1301{
1302	type_datum_t *t;
1303
1304	if (strcmp(id, "*") == 0) {
1305		if (!starallowed) {
1306			yyerror("* not allowed in this type of rule");
1307			return -1;
1308		}
1309		/* set TYPE_STAR flag */
1310		set->flags = TYPE_STAR;
1311		free(id);
1312		*add = 1;
1313		return 0;
1314	}
1315
1316	if (strcmp(id, "~") == 0) {
1317		if (!starallowed) {
1318			yyerror("~ not allowed in this type of rule");
1319			return -1;
1320		}
1321		/* complement the set */
1322		set->flags = TYPE_COMP;
1323		free(id);
1324		*add = 1;
1325		return 0;
1326	}
1327
1328	if (strcmp(id, "-") == 0) {
1329		*add = 0;
1330		free(id);
1331		return 0;
1332	}
1333
1334	if (!is_id_in_scope(SYM_TYPES, id)) {
1335		yyerror2("type %s is not within scope", id);
1336		free(id);
1337		return -1;
1338	}
1339	t = hashtab_search(policydbp->p_types.table, id);
1340	if (!t) {
1341		yyerror2("unknown type %s", id);
1342		free(id);
1343		return -1;
1344	}
1345
1346	if (*add == 0) {
1347		if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
1348			goto oom;
1349	} else {
1350		if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
1351			goto oom;
1352	}
1353	free(id);
1354	*add = 1;
1355	return 0;
1356      oom:
1357	yyerror("Out of memory");
1358	free(id);
1359	return -1;
1360}
1361
1362int define_compute_type_helper(int which, avrule_t ** rule)
1363{
1364	char *id;
1365	type_datum_t *datum;
1366	class_datum_t *cladatum;
1367	ebitmap_t tclasses;
1368	ebitmap_node_t *node;
1369	avrule_t *avrule;
1370	class_perm_node_t *perm;
1371	int i, add = 1;
1372
1373	avrule = malloc(sizeof(avrule_t));
1374	if (!avrule) {
1375		yyerror("out of memory");
1376		return -1;
1377	}
1378	avrule_init(avrule);
1379	avrule->specified = which;
1380	avrule->line = policydb_lineno;
1381
1382	while ((id = queue_remove(id_queue))) {
1383		if (set_types(&avrule->stypes, id, &add, 0))
1384			return -1;
1385	}
1386	add = 1;
1387	while ((id = queue_remove(id_queue))) {
1388		if (set_types(&avrule->ttypes, id, &add, 0))
1389			return -1;
1390	}
1391
1392	ebitmap_init(&tclasses);
1393	while ((id = queue_remove(id_queue))) {
1394		if (!is_id_in_scope(SYM_CLASSES, id)) {
1395			yyerror2("class %s is not within scope", id);
1396			free(id);
1397			goto bad;
1398		}
1399		cladatum = hashtab_search(policydbp->p_classes.table, id);
1400		if (!cladatum) {
1401			yyerror2("unknown class %s", id);
1402			goto bad;
1403		}
1404		if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
1405			yyerror("Out of memory");
1406			goto bad;
1407		}
1408		free(id);
1409	}
1410
1411	id = (char *)queue_remove(id_queue);
1412	if (!id) {
1413		yyerror("no newtype?");
1414		goto bad;
1415	}
1416	if (!is_id_in_scope(SYM_TYPES, id)) {
1417		yyerror2("type %s is not within scope", id);
1418		free(id);
1419		goto bad;
1420	}
1421	datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
1422						(hashtab_key_t) id);
1423	if (!datum || datum->flavor == TYPE_ATTRIB) {
1424		yyerror2("unknown type %s", id);
1425		goto bad;
1426	}
1427
1428	ebitmap_for_each_bit(&tclasses, node, i) {
1429		if (ebitmap_node_get_bit(node, i)) {
1430			perm = malloc(sizeof(class_perm_node_t));
1431			if (!perm) {
1432				yyerror("out of memory");
1433				return -1;
1434			}
1435			class_perm_node_init(perm);
1436			perm->class = i + 1;
1437			perm->data = datum->s.value;
1438			perm->next = avrule->perms;
1439			avrule->perms = perm;
1440		}
1441	}
1442	ebitmap_destroy(&tclasses);
1443
1444	*rule = avrule;
1445	return 0;
1446
1447      bad:
1448	avrule_destroy(avrule);
1449	free(avrule);
1450	return -1;
1451}
1452
1453int define_compute_type(int which)
1454{
1455	char *id;
1456	avrule_t *avrule;
1457
1458	if (pass == 1) {
1459		while ((id = queue_remove(id_queue)))
1460			free(id);
1461		while ((id = queue_remove(id_queue)))
1462			free(id);
1463		while ((id = queue_remove(id_queue)))
1464			free(id);
1465		id = queue_remove(id_queue);
1466		free(id);
1467		return 0;
1468	}
1469
1470	if (define_compute_type_helper(which, &avrule))
1471		return -1;
1472
1473	append_avrule(avrule);
1474	return 0;
1475}
1476
1477avrule_t *define_cond_compute_type(int which)
1478{
1479	char *id;
1480	avrule_t *avrule;
1481
1482	if (pass == 1) {
1483		while ((id = queue_remove(id_queue)))
1484			free(id);
1485		while ((id = queue_remove(id_queue)))
1486			free(id);
1487		while ((id = queue_remove(id_queue)))
1488			free(id);
1489		id = queue_remove(id_queue);
1490		free(id);
1491		return (avrule_t *) 1;
1492	}
1493
1494	if (define_compute_type_helper(which, &avrule))
1495		return COND_ERR;
1496
1497	return avrule;
1498}
1499
1500int define_bool(void)
1501{
1502	char *id, *bool_value;
1503	cond_bool_datum_t *datum;
1504	int ret;
1505	uint32_t value;
1506
1507	if (pass == 2) {
1508		while ((id = queue_remove(id_queue)))
1509			free(id);
1510		return 0;
1511	}
1512
1513	id = (char *)queue_remove(id_queue);
1514	if (!id) {
1515		yyerror("no identifier for bool definition?");
1516		return -1;
1517	}
1518	if (id_has_dot(id)) {
1519		free(id);
1520		yyerror("boolean identifiers may not contain periods");
1521		return -1;
1522	}
1523	datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
1524	if (!datum) {
1525		yyerror("out of memory");
1526		free(id);
1527		return -1;
1528	}
1529	memset(datum, 0, sizeof(cond_bool_datum_t));
1530	ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
1531	switch (ret) {
1532	case -3:{
1533			yyerror("Out of memory!");
1534			goto cleanup;
1535		}
1536	case -2:{
1537			yyerror2("duplicate declaration of boolean %s", id);
1538			goto cleanup;
1539		}
1540	case -1:{
1541			yyerror("could not declare boolean here");
1542			goto cleanup;
1543		}
1544	case 0:
1545	case 1:{
1546			break;
1547		}
1548	default:{
1549			assert(0);	/* should never get here */
1550		}
1551	}
1552	datum->s.value = value;
1553
1554	bool_value = (char *)queue_remove(id_queue);
1555	if (!bool_value) {
1556		yyerror("no default value for bool definition?");
1557		free(id);
1558		return -1;
1559	}
1560
1561	datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
1562	return 0;
1563      cleanup:
1564	cond_destroy_bool(id, datum, NULL);
1565	return -1;
1566}
1567
1568avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
1569{
1570	if (pass == 1) {
1571		/* return something so we get through pass 1 */
1572		return (avrule_t *) 1;
1573	}
1574
1575	if (sl == NULL) {
1576		/* This is a require block, return previous list */
1577		return avlist;
1578	}
1579
1580	/* prepend the new avlist to the pre-existing one */
1581	sl->next = avlist;
1582	return sl;
1583}
1584
1585int define_te_avtab_helper(int which, avrule_t ** rule)
1586{
1587	char *id;
1588	class_datum_t *cladatum;
1589	perm_datum_t *perdatum = NULL;
1590	class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
1591	ebitmap_t tclasses;
1592	ebitmap_node_t *node;
1593	avrule_t *avrule;
1594	unsigned int i;
1595	int add = 1, ret = 0;
1596	int suppress = 0;
1597
1598	avrule = (avrule_t *) malloc(sizeof(avrule_t));
1599	if (!avrule) {
1600		yyerror("memory error");
1601		ret = -1;
1602		goto out;
1603	}
1604	avrule_init(avrule);
1605	avrule->specified = which;
1606	avrule->line = policydb_lineno;
1607
1608	while ((id = queue_remove(id_queue))) {
1609		if (set_types
1610		    (&avrule->stypes, id, &add,
1611		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
1612			ret = -1;
1613			goto out;
1614		}
1615	}
1616	add = 1;
1617	while ((id = queue_remove(id_queue))) {
1618		if (strcmp(id, "self") == 0) {
1619			free(id);
1620			avrule->flags |= RULE_SELF;
1621			continue;
1622		}
1623		if (set_types
1624		    (&avrule->ttypes, id, &add,
1625		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
1626			ret = -1;
1627			goto out;
1628		}
1629	}
1630
1631	ebitmap_init(&tclasses);
1632	while ((id = queue_remove(id_queue))) {
1633		if (!is_id_in_scope(SYM_CLASSES, id)) {
1634			yyerror2("class %s is not within scope", id);
1635			ret = -1;
1636			goto out;
1637		}
1638		cladatum = hashtab_search(policydbp->p_classes.table, id);
1639		if (!cladatum) {
1640			yyerror2("unknown class %s used in rule", id);
1641			ret = -1;
1642			goto out;
1643		}
1644		if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
1645			yyerror("Out of memory");
1646			ret = -1;
1647			goto out;
1648		}
1649		free(id);
1650	}
1651
1652	perms = NULL;
1653	ebitmap_for_each_bit(&tclasses, node, i) {
1654		if (!ebitmap_node_get_bit(node, i))
1655			continue;
1656		cur_perms =
1657		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
1658		if (!cur_perms) {
1659			yyerror("out of memory");
1660			ret = -1;
1661			goto out;
1662		}
1663		class_perm_node_init(cur_perms);
1664		cur_perms->class = i + 1;
1665		if (!perms)
1666			perms = cur_perms;
1667		if (tail)
1668			tail->next = cur_perms;
1669		tail = cur_perms;
1670	}
1671
1672	while ((id = queue_remove(id_queue))) {
1673		cur_perms = perms;
1674		ebitmap_for_each_bit(&tclasses, node, i) {
1675			if (!ebitmap_node_get_bit(node, i))
1676				continue;
1677			cladatum = policydbp->class_val_to_struct[i];
1678
1679			if (strcmp(id, "*") == 0) {
1680				/* set all permissions in the class */
1681				cur_perms->data = ~0U;
1682				goto next;
1683			}
1684
1685			if (strcmp(id, "~") == 0) {
1686				/* complement the set */
1687				if (which == AVRULE_DONTAUDIT)
1688					yywarn("dontaudit rule with a ~?");
1689				cur_perms->data = ~cur_perms->data;
1690				goto next;
1691			}
1692
1693			perdatum =
1694			    hashtab_search(cladatum->permissions.table, id);
1695			if (!perdatum) {
1696				if (cladatum->comdatum) {
1697					perdatum =
1698					    hashtab_search(cladatum->comdatum->
1699							   permissions.table,
1700							   id);
1701				}
1702			}
1703			if (!perdatum) {
1704				if (!suppress)
1705					yyerror2("permission %s is not defined"
1706					     " for class %s", id,
1707					     policydbp->p_class_val_to_name[i]);
1708				continue;
1709			} else
1710			    if (!is_perm_in_scope
1711				(id, policydbp->p_class_val_to_name[i])) {
1712				if (!suppress) {
1713					yyerror2("permission %s of class %s is"
1714					     " not within scope", id,
1715					     policydbp->p_class_val_to_name[i]);
1716				}
1717				continue;
1718			} else {
1719				cur_perms->data |= 1U << (perdatum->s.value - 1);
1720			}
1721		      next:
1722			cur_perms = cur_perms->next;
1723		}
1724
1725		free(id);
1726	}
1727
1728	ebitmap_destroy(&tclasses);
1729
1730	avrule->perms = perms;
1731	*rule = avrule;
1732
1733      out:
1734	return ret;
1735
1736}
1737
1738avrule_t *define_cond_te_avtab(int which)
1739{
1740	char *id;
1741	avrule_t *avrule;
1742	int i;
1743
1744	if (pass == 1) {
1745		for (i = 0; i < 4; i++) {
1746			while ((id = queue_remove(id_queue)))
1747				free(id);
1748		}
1749		return (avrule_t *) 1;	/* any non-NULL value */
1750	}
1751
1752	if (define_te_avtab_helper(which, &avrule))
1753		return COND_ERR;
1754
1755	return avrule;
1756}
1757
1758int define_te_avtab(int which)
1759{
1760	char *id;
1761	avrule_t *avrule;
1762	int i;
1763
1764	if (pass == 1) {
1765		for (i = 0; i < 4; i++) {
1766			while ((id = queue_remove(id_queue)))
1767				free(id);
1768		}
1769		return 0;
1770	}
1771
1772	if (define_te_avtab_helper(which, &avrule))
1773		return -1;
1774
1775	/* append this avrule to the end of the current rules list */
1776	append_avrule(avrule);
1777	return 0;
1778}
1779
1780int define_role_types(void)
1781{
1782	role_datum_t *role;
1783	char *id;
1784	int add = 1;
1785
1786	if (pass == 1) {
1787		while ((id = queue_remove(id_queue)))
1788			free(id);
1789		return 0;
1790	}
1791
1792	if ((role = declare_role()) == NULL) {
1793		return -1;
1794	}
1795	while ((id = queue_remove(id_queue))) {
1796		if (set_types(&role->types, id, &add, 0))
1797			return -1;
1798	}
1799
1800	return 0;
1801}
1802
1803role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
1804{
1805	role_datum_t *new;
1806
1807	if (pass == 1) {
1808		return (role_datum_t *) 1;	/* any non-NULL value */
1809	}
1810
1811	new = malloc(sizeof(role_datum_t));
1812	if (!new) {
1813		yyerror("out of memory");
1814		return NULL;
1815	}
1816	memset(new, 0, sizeof(role_datum_t));
1817	new->s.value = 0;		/* temporary role */
1818	if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
1819		yyerror("out of memory");
1820		return NULL;
1821	}
1822	if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
1823		yyerror("out of memory");
1824		return NULL;
1825	}
1826	if (!r1->s.value) {
1827		/* free intermediate result */
1828		type_set_destroy(&r1->types);
1829		ebitmap_destroy(&r1->dominates);
1830		free(r1);
1831	}
1832	if (!r2->s.value) {
1833		/* free intermediate result */
1834		yyerror("right hand role is temporary?");
1835		type_set_destroy(&r2->types);
1836		ebitmap_destroy(&r2->dominates);
1837		free(r2);
1838	}
1839	return new;
1840}
1841
1842/* This function eliminates the ordering dependency of role dominance rule */
1843static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum,
1844				 void *arg)
1845{
1846	role_datum_t *rdp = (role_datum_t *) arg;
1847	role_datum_t *rdatum = (role_datum_t *) datum;
1848	ebitmap_node_t *node;
1849	int i;
1850
1851	/* Don't bother to process against self role */
1852	if (rdatum->s.value == rdp->s.value)
1853		return 0;
1854
1855	/* If a dominating role found */
1856	if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
1857		ebitmap_t types;
1858		ebitmap_init(&types);
1859		if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
1860			ebitmap_destroy(&types);
1861			return -1;
1862		}
1863		/* raise types and dominates from dominated role */
1864		ebitmap_for_each_bit(&rdp->dominates, node, i) {
1865			if (ebitmap_node_get_bit(node, i))
1866				if (ebitmap_set_bit
1867				    (&rdatum->dominates, i, TRUE))
1868					goto oom;
1869		}
1870		ebitmap_for_each_bit(&types, node, i) {
1871			if (ebitmap_node_get_bit(node, i))
1872				if (ebitmap_set_bit
1873				    (&rdatum->types.types, i, TRUE))
1874					goto oom;
1875		}
1876		ebitmap_destroy(&types);
1877	}
1878
1879	/* go through all the roles */
1880	return 0;
1881      oom:
1882	yyerror("Out of memory");
1883	return -1;
1884}
1885
1886role_datum_t *define_role_dom(role_datum_t * r)
1887{
1888	role_datum_t *role;
1889	char *role_id;
1890	ebitmap_node_t *node;
1891	unsigned int i;
1892	int ret;
1893
1894	if (pass == 1) {
1895		role_id = queue_remove(id_queue);
1896		free(role_id);
1897		return (role_datum_t *) 1;	/* any non-NULL value */
1898	}
1899
1900	yywarn("Role dominance has been deprecated");
1901
1902	role_id = queue_remove(id_queue);
1903	if (!is_id_in_scope(SYM_ROLES, role_id)) {
1904		yyerror2("role %s is not within scope", role_id);
1905		free(role_id);
1906		return NULL;
1907	}
1908	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
1909					       role_id);
1910	if (!role) {
1911		role = (role_datum_t *) malloc(sizeof(role_datum_t));
1912		if (!role) {
1913			yyerror("out of memory");
1914			free(role_id);
1915			return NULL;
1916		}
1917		memset(role, 0, sizeof(role_datum_t));
1918		ret =
1919		    declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
1920				   (hashtab_datum_t) role, &role->s.value,
1921				   &role->s.value);
1922		switch (ret) {
1923		case -3:{
1924				yyerror("Out of memory!");
1925				goto cleanup;
1926			}
1927		case -2:{
1928				yyerror2("duplicate declaration of role %s",
1929					 role_id);
1930				goto cleanup;
1931			}
1932		case -1:{
1933				yyerror("could not declare role here");
1934				goto cleanup;
1935			}
1936		case 0:
1937		case 1:{
1938				break;
1939			}
1940		default:{
1941				assert(0);	/* should never get here */
1942			}
1943		}
1944		if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
1945			yyerror("Out of memory!");
1946			goto cleanup;
1947		}
1948	}
1949	if (r) {
1950		ebitmap_t types;
1951		ebitmap_init(&types);
1952		ebitmap_for_each_bit(&r->dominates, node, i) {
1953			if (ebitmap_node_get_bit(node, i))
1954				if (ebitmap_set_bit(&role->dominates, i, TRUE))
1955					goto oom;
1956		}
1957		if (type_set_expand(&r->types, &types, policydbp, 1)) {
1958			ebitmap_destroy(&types);
1959			return NULL;
1960		}
1961		ebitmap_for_each_bit(&types, node, i) {
1962			if (ebitmap_node_get_bit(node, i))
1963				if (ebitmap_set_bit
1964				    (&role->types.types, i, TRUE))
1965					goto oom;
1966		}
1967		ebitmap_destroy(&types);
1968		if (!r->s.value) {
1969			/* free intermediate result */
1970			type_set_destroy(&r->types);
1971			ebitmap_destroy(&r->dominates);
1972			free(r);
1973		}
1974		/*
1975		 * Now go through all the roles and escalate this role's
1976		 * dominates and types if a role dominates this role.
1977		 */
1978		hashtab_map(policydbp->p_roles.table,
1979			    dominate_role_recheck, role);
1980	}
1981	return role;
1982      cleanup:
1983	free(role_id);
1984	role_datum_destroy(role);
1985	free(role);
1986	return NULL;
1987      oom:
1988	yyerror("Out of memory");
1989	goto cleanup;
1990}
1991
1992static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
1993				   void *p)
1994{
1995	struct val_to_name *v = p;
1996	role_datum_t *roldatum;
1997
1998	roldatum = (role_datum_t *) datum;
1999
2000	if (v->val == roldatum->s.value) {
2001		v->name = key;
2002		return 1;
2003	}
2004
2005	return 0;
2006}
2007
2008static char *role_val_to_name(unsigned int val)
2009{
2010	struct val_to_name v;
2011	int rc;
2012
2013	v.val = val;
2014	rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
2015	if (rc)
2016		return v.name;
2017	return NULL;
2018}
2019
2020static int set_roles(role_set_t * set, char *id)
2021{
2022	role_datum_t *r;
2023
2024	if (strcmp(id, "*") == 0) {
2025		free(id);
2026		yyerror("* is not allowed for role sets");
2027		return -1;
2028	}
2029
2030	if (strcmp(id, "~") == 0) {
2031		free(id);
2032		yyerror("~ is not allowed for role sets");
2033		return -1;
2034	}
2035	if (!is_id_in_scope(SYM_ROLES, id)) {
2036		yyerror2("role %s is not within scope", id);
2037		free(id);
2038		return -1;
2039	}
2040	r = hashtab_search(policydbp->p_roles.table, id);
2041	if (!r) {
2042		yyerror2("unknown role %s", id);
2043		free(id);
2044		return -1;
2045	}
2046
2047	if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
2048		yyerror("out of memory");
2049		free(id);
2050		return -1;
2051	}
2052	free(id);
2053	return 0;
2054}
2055
2056int define_role_trans(void)
2057{
2058	char *id;
2059	role_datum_t *role;
2060	role_set_t roles;
2061	type_set_t types;
2062	ebitmap_t e_types, e_roles;
2063	ebitmap_node_t *tnode, *rnode;
2064	struct role_trans *tr = NULL;
2065	struct role_trans_rule *rule = NULL;
2066	unsigned int i, j;
2067	int add = 1;
2068
2069	if (pass == 1) {
2070		while ((id = queue_remove(id_queue)))
2071			free(id);
2072		while ((id = queue_remove(id_queue)))
2073			free(id);
2074		id = queue_remove(id_queue);
2075		free(id);
2076		return 0;
2077	}
2078
2079	role_set_init(&roles);
2080	ebitmap_init(&e_roles);
2081	type_set_init(&types);
2082	ebitmap_init(&e_types);
2083
2084	while ((id = queue_remove(id_queue))) {
2085		if (set_roles(&roles, id))
2086			return -1;
2087	}
2088	add = 1;
2089	while ((id = queue_remove(id_queue))) {
2090		if (set_types(&types, id, &add, 0))
2091			return -1;
2092	}
2093
2094	id = (char *)queue_remove(id_queue);
2095	if (!id) {
2096		yyerror("no new role in transition definition?");
2097		goto bad;
2098	}
2099	if (!is_id_in_scope(SYM_ROLES, id)) {
2100		yyerror2("role %s is not within scope", id);
2101		free(id);
2102		goto bad;
2103	}
2104	role = hashtab_search(policydbp->p_roles.table, id);
2105	if (!role) {
2106		yyerror2("unknown role %s used in transition definition", id);
2107		goto bad;
2108	}
2109
2110	/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
2111	if (role_set_expand(&roles, &e_roles, policydbp, NULL))
2112		goto bad;
2113
2114	if (type_set_expand(&types, &e_types, policydbp, 1))
2115		goto bad;
2116
2117	ebitmap_for_each_bit(&e_roles, rnode, i) {
2118		if (!ebitmap_node_get_bit(rnode, i))
2119			continue;
2120		ebitmap_for_each_bit(&e_types, tnode, j) {
2121			if (!ebitmap_node_get_bit(tnode, j))
2122				continue;
2123
2124			for (tr = policydbp->role_tr; tr; tr = tr->next) {
2125				if (tr->role == (i + 1) && tr->type == (j + 1)) {
2126					yyerror2("duplicate role transition for (%s,%s)",
2127					      role_val_to_name(i + 1),
2128					      policydbp->p_type_val_to_name[j]);
2129					goto bad;
2130				}
2131			}
2132
2133			tr = malloc(sizeof(struct role_trans));
2134			if (!tr) {
2135				yyerror("out of memory");
2136				return -1;
2137			}
2138			memset(tr, 0, sizeof(struct role_trans));
2139			tr->role = i + 1;
2140			tr->type = j + 1;
2141			tr->new_role = role->s.value;
2142			tr->next = policydbp->role_tr;
2143			policydbp->role_tr = tr;
2144		}
2145	}
2146	/* Now add the real rule */
2147	rule = malloc(sizeof(struct role_trans_rule));
2148	if (!rule) {
2149		yyerror("out of memory");
2150		return -1;
2151	}
2152	memset(rule, 0, sizeof(struct role_trans_rule));
2153	rule->roles = roles;
2154	rule->types = types;
2155	rule->new_role = role->s.value;
2156
2157	append_role_trans(rule);
2158
2159	ebitmap_destroy(&e_roles);
2160	ebitmap_destroy(&e_types);
2161
2162	return 0;
2163
2164      bad:
2165	return -1;
2166}
2167
2168int define_role_allow(void)
2169{
2170	char *id;
2171	struct role_allow_rule *ra = 0;
2172
2173	if (pass == 1) {
2174		while ((id = queue_remove(id_queue)))
2175			free(id);
2176		while ((id = queue_remove(id_queue)))
2177			free(id);
2178		return 0;
2179	}
2180
2181	ra = malloc(sizeof(role_allow_rule_t));
2182	if (!ra) {
2183		yyerror("out of memory");
2184		return -1;
2185	}
2186	role_allow_rule_init(ra);
2187
2188	while ((id = queue_remove(id_queue))) {
2189		if (set_roles(&ra->roles, id))
2190			return -1;
2191	}
2192
2193	while ((id = queue_remove(id_queue))) {
2194		if (set_roles(&ra->new_roles, id))
2195			return -1;
2196	}
2197
2198	append_role_allow(ra);
2199	return 0;
2200}
2201
2202static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
2203{
2204	constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
2205	for (e = expr; e; e = e->next) {
2206		newe = malloc(sizeof(*newe));
2207		if (!newe)
2208			goto oom;
2209		if (constraint_expr_init(newe) == -1) {
2210			free(newe);
2211			goto oom;
2212		}
2213		if (l)
2214			l->next = newe;
2215		else
2216			h = newe;
2217		l = newe;
2218		newe->expr_type = e->expr_type;
2219		newe->attr = e->attr;
2220		newe->op = e->op;
2221		if (newe->expr_type == CEXPR_NAMES) {
2222			if (newe->attr & CEXPR_TYPE) {
2223				if (type_set_cpy
2224				    (newe->type_names, e->type_names))
2225					goto oom;
2226			} else {
2227				if (ebitmap_cpy(&newe->names, &e->names))
2228					goto oom;
2229			}
2230		}
2231	}
2232
2233	return h;
2234      oom:
2235	e = h;
2236	while (e) {
2237		l = e;
2238		e = e->next;
2239		constraint_expr_destroy(l);
2240	}
2241	return NULL;
2242}
2243
2244int define_constraint(constraint_expr_t * expr)
2245{
2246	struct constraint_node *node;
2247	char *id;
2248	class_datum_t *cladatum;
2249	perm_datum_t *perdatum;
2250	ebitmap_t classmap;
2251	ebitmap_node_t *enode;
2252	constraint_expr_t *e;
2253	unsigned int i;
2254	int depth;
2255	unsigned char useexpr = 1;
2256
2257	if (pass == 1) {
2258		while ((id = queue_remove(id_queue)))
2259			free(id);
2260		while ((id = queue_remove(id_queue)))
2261			free(id);
2262		return 0;
2263	}
2264
2265	depth = -1;
2266	for (e = expr; e; e = e->next) {
2267		switch (e->expr_type) {
2268		case CEXPR_NOT:
2269			if (depth < 0) {
2270				yyerror("illegal constraint expression");
2271				return -1;
2272			}
2273			break;
2274		case CEXPR_AND:
2275		case CEXPR_OR:
2276			if (depth < 1) {
2277				yyerror("illegal constraint expression");
2278				return -1;
2279			}
2280			depth--;
2281			break;
2282		case CEXPR_ATTR:
2283		case CEXPR_NAMES:
2284			if (e->attr & CEXPR_XTARGET) {
2285				yyerror("illegal constraint expression");
2286				return -1;	/* only for validatetrans rules */
2287			}
2288			if (depth == (CEXPR_MAXDEPTH - 1)) {
2289				yyerror("constraint expression is too deep");
2290				return -1;
2291			}
2292			depth++;
2293			break;
2294		default:
2295			yyerror("illegal constraint expression");
2296			return -1;
2297		}
2298	}
2299	if (depth != 0) {
2300		yyerror("illegal constraint expression");
2301		return -1;
2302	}
2303
2304	ebitmap_init(&classmap);
2305	while ((id = queue_remove(id_queue))) {
2306		if (!is_id_in_scope(SYM_CLASSES, id)) {
2307			yyerror2("class %s is not within scope", id);
2308			free(id);
2309			return -1;
2310		}
2311		cladatum =
2312		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2313						     (hashtab_key_t) id);
2314		if (!cladatum) {
2315			yyerror2("class %s is not defined", id);
2316			ebitmap_destroy(&classmap);
2317			free(id);
2318			return -1;
2319		}
2320		if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
2321			yyerror("out of memory");
2322			ebitmap_destroy(&classmap);
2323			free(id);
2324			return -1;
2325		}
2326		node = malloc(sizeof(struct constraint_node));
2327		if (!node) {
2328			yyerror("out of memory");
2329			return -1;
2330		}
2331		memset(node, 0, sizeof(constraint_node_t));
2332		if (useexpr) {
2333			node->expr = expr;
2334			useexpr = 0;
2335		} else {
2336			node->expr = constraint_expr_clone(expr);
2337		}
2338		if (!node->expr) {
2339			yyerror("out of memory");
2340			return -1;
2341		}
2342		node->permissions = 0;
2343
2344		node->next = cladatum->constraints;
2345		cladatum->constraints = node;
2346
2347		free(id);
2348	}
2349
2350	while ((id = queue_remove(id_queue))) {
2351		ebitmap_for_each_bit(&classmap, enode, i) {
2352			if (ebitmap_node_get_bit(enode, i)) {
2353				cladatum = policydbp->class_val_to_struct[i];
2354				node = cladatum->constraints;
2355
2356				perdatum =
2357				    (perm_datum_t *) hashtab_search(cladatum->
2358								    permissions.
2359								    table,
2360								    (hashtab_key_t)
2361								    id);
2362				if (!perdatum) {
2363					if (cladatum->comdatum) {
2364						perdatum =
2365						    (perm_datum_t *)
2366						    hashtab_search(cladatum->
2367								   comdatum->
2368								   permissions.
2369								   table,
2370								   (hashtab_key_t)
2371								   id);
2372					}
2373					if (!perdatum) {
2374						yyerror2("permission %s is not"
2375							 " defined", id);
2376						free(id);
2377						ebitmap_destroy(&classmap);
2378						return -1;
2379					}
2380				}
2381				node->permissions |=
2382				    (1 << (perdatum->s.value - 1));
2383			}
2384		}
2385		free(id);
2386	}
2387
2388	ebitmap_destroy(&classmap);
2389
2390	return 0;
2391}
2392
2393int define_validatetrans(constraint_expr_t * expr)
2394{
2395	struct constraint_node *node;
2396	char *id;
2397	class_datum_t *cladatum;
2398	ebitmap_t classmap;
2399	constraint_expr_t *e;
2400	int depth;
2401	unsigned char useexpr = 1;
2402
2403	if (pass == 1) {
2404		while ((id = queue_remove(id_queue)))
2405			free(id);
2406		return 0;
2407	}
2408
2409	depth = -1;
2410	for (e = expr; e; e = e->next) {
2411		switch (e->expr_type) {
2412		case CEXPR_NOT:
2413			if (depth < 0) {
2414				yyerror("illegal validatetrans expression");
2415				return -1;
2416			}
2417			break;
2418		case CEXPR_AND:
2419		case CEXPR_OR:
2420			if (depth < 1) {
2421				yyerror("illegal validatetrans expression");
2422				return -1;
2423			}
2424			depth--;
2425			break;
2426		case CEXPR_ATTR:
2427		case CEXPR_NAMES:
2428			if (depth == (CEXPR_MAXDEPTH - 1)) {
2429				yyerror("validatetrans expression is too deep");
2430				return -1;
2431			}
2432			depth++;
2433			break;
2434		default:
2435			yyerror("illegal validatetrans expression");
2436			return -1;
2437		}
2438	}
2439	if (depth != 0) {
2440		yyerror("illegal validatetrans expression");
2441		return -1;
2442	}
2443
2444	ebitmap_init(&classmap);
2445	while ((id = queue_remove(id_queue))) {
2446		if (!is_id_in_scope(SYM_CLASSES, id)) {
2447			yyerror2("class %s is not within scope", id);
2448			free(id);
2449			return -1;
2450		}
2451		cladatum =
2452		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2453						     (hashtab_key_t) id);
2454		if (!cladatum) {
2455			yyerror2("class %s is not defined", id);
2456			ebitmap_destroy(&classmap);
2457			free(id);
2458			return -1;
2459		}
2460		if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
2461			yyerror("out of memory");
2462			ebitmap_destroy(&classmap);
2463			free(id);
2464			return -1;
2465		}
2466
2467		node = malloc(sizeof(struct constraint_node));
2468		if (!node) {
2469			yyerror("out of memory");
2470			return -1;
2471		}
2472		memset(node, 0, sizeof(constraint_node_t));
2473		if (useexpr) {
2474			node->expr = expr;
2475			useexpr = 0;
2476		} else {
2477			node->expr = constraint_expr_clone(expr);
2478		}
2479		node->permissions = 0;
2480
2481		node->next = cladatum->validatetrans;
2482		cladatum->validatetrans = node;
2483
2484		free(id);
2485	}
2486
2487	ebitmap_destroy(&classmap);
2488
2489	return 0;
2490}
2491
2492uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
2493{
2494	struct constraint_expr *expr, *e1 = NULL, *e2;
2495	user_datum_t *user;
2496	role_datum_t *role;
2497	ebitmap_t negset;
2498	char *id;
2499	uint32_t val;
2500	int add = 1;
2501
2502	if (pass == 1) {
2503		if (expr_type == CEXPR_NAMES) {
2504			while ((id = queue_remove(id_queue)))
2505				free(id);
2506		}
2507		return 1;	/* any non-NULL value */
2508	}
2509
2510	if ((expr = malloc(sizeof(*expr))) == NULL ||
2511	    constraint_expr_init(expr) == -1) {
2512		yyerror("out of memory");
2513		free(expr);
2514		return 0;
2515	}
2516	expr->expr_type = expr_type;
2517
2518	switch (expr_type) {
2519	case CEXPR_NOT:
2520		e1 = NULL;
2521		e2 = (struct constraint_expr *)arg1;
2522		while (e2) {
2523			e1 = e2;
2524			e2 = e2->next;
2525		}
2526		if (!e1 || e1->next) {
2527			yyerror("illegal constraint expression");
2528			constraint_expr_destroy(expr);
2529			return 0;
2530		}
2531		e1->next = expr;
2532		return arg1;
2533	case CEXPR_AND:
2534	case CEXPR_OR:
2535		e1 = NULL;
2536		e2 = (struct constraint_expr *)arg1;
2537		while (e2) {
2538			e1 = e2;
2539			e2 = e2->next;
2540		}
2541		if (!e1 || e1->next) {
2542			yyerror("illegal constraint expression");
2543			constraint_expr_destroy(expr);
2544			return 0;
2545		}
2546		e1->next = (struct constraint_expr *)arg2;
2547
2548		e1 = NULL;
2549		e2 = (struct constraint_expr *)arg2;
2550		while (e2) {
2551			e1 = e2;
2552			e2 = e2->next;
2553		}
2554		if (!e1 || e1->next) {
2555			yyerror("illegal constraint expression");
2556			constraint_expr_destroy(expr);
2557			return 0;
2558		}
2559		e1->next = expr;
2560		return arg1;
2561	case CEXPR_ATTR:
2562		expr->attr = arg1;
2563		expr->op = arg2;
2564		return (uintptr_t) expr;
2565	case CEXPR_NAMES:
2566		add = 1;
2567		expr->attr = arg1;
2568		expr->op = arg2;
2569		ebitmap_init(&negset);
2570		while ((id = (char *)queue_remove(id_queue))) {
2571			if (expr->attr & CEXPR_USER) {
2572				if (!is_id_in_scope(SYM_USERS, id)) {
2573					yyerror2("user %s is not within scope",
2574						 id);
2575					constraint_expr_destroy(expr);
2576					return 0;
2577				}
2578				user =
2579				    (user_datum_t *) hashtab_search(policydbp->
2580								    p_users.
2581								    table,
2582								    (hashtab_key_t)
2583								    id);
2584				if (!user) {
2585					yyerror2("unknown user %s", id);
2586					constraint_expr_destroy(expr);
2587					return 0;
2588				}
2589				val = user->s.value;
2590			} else if (expr->attr & CEXPR_ROLE) {
2591				if (!is_id_in_scope(SYM_ROLES, id)) {
2592					yyerror2("role %s is not within scope",
2593						 id);
2594					constraint_expr_destroy(expr);
2595					return 0;
2596				}
2597				role =
2598				    (role_datum_t *) hashtab_search(policydbp->
2599								    p_roles.
2600								    table,
2601								    (hashtab_key_t)
2602								    id);
2603				if (!role) {
2604					yyerror2("unknown role %s", id);
2605					constraint_expr_destroy(expr);
2606					return 0;
2607				}
2608				val = role->s.value;
2609			} else if (expr->attr & CEXPR_TYPE) {
2610				if (set_types(expr->type_names, id, &add, 0)) {
2611					constraint_expr_destroy(expr);
2612					return 0;
2613				}
2614				continue;
2615			} else {
2616				yyerror("invalid constraint expression");
2617				constraint_expr_destroy(expr);
2618				return 0;
2619			}
2620			if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
2621				yyerror("out of memory");
2622				ebitmap_destroy(&expr->names);
2623				constraint_expr_destroy(expr);
2624				return 0;
2625			}
2626			free(id);
2627		}
2628		ebitmap_destroy(&negset);
2629		return (uintptr_t) expr;
2630	default:
2631		yyerror("invalid constraint expression");
2632		constraint_expr_destroy(expr);
2633		return 0;
2634	}
2635
2636	yyerror("invalid constraint expression");
2637	free(expr);
2638	return 0;
2639}
2640
2641int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
2642{
2643	cond_expr_t *e;
2644	int depth;
2645	cond_node_t cn, *cn_old;
2646
2647	/* expression cannot be NULL */
2648	if (!expr) {
2649		yyerror("illegal conditional expression");
2650		return -1;
2651	}
2652	if (!t) {
2653		if (!f) {
2654			/* empty is fine, destroy expression and return */
2655			cond_expr_destroy(expr);
2656			return 0;
2657		}
2658		/* Invert */
2659		t = f;
2660		f = 0;
2661		expr = define_cond_expr(COND_NOT, expr, 0);
2662		if (!expr) {
2663			yyerror("unable to invert");
2664			return -1;
2665		}
2666	}
2667
2668	/* verify expression */
2669	depth = -1;
2670	for (e = expr; e; e = e->next) {
2671		switch (e->expr_type) {
2672		case COND_NOT:
2673			if (depth < 0) {
2674				yyerror
2675				    ("illegal conditional expression; Bad NOT");
2676				return -1;
2677			}
2678			break;
2679		case COND_AND:
2680		case COND_OR:
2681		case COND_XOR:
2682		case COND_EQ:
2683		case COND_NEQ:
2684			if (depth < 1) {
2685				yyerror
2686				    ("illegal conditional expression; Bad binary op");
2687				return -1;
2688			}
2689			depth--;
2690			break;
2691		case COND_BOOL:
2692			if (depth == (COND_EXPR_MAXDEPTH - 1)) {
2693				yyerror
2694				    ("conditional expression is like totally too deep");
2695				return -1;
2696			}
2697			depth++;
2698			break;
2699		default:
2700			yyerror("illegal conditional expression");
2701			return -1;
2702		}
2703	}
2704	if (depth != 0) {
2705		yyerror("illegal conditional expression");
2706		return -1;
2707	}
2708
2709	/*  use tmp conditional node to partially build new node */
2710	memset(&cn, 0, sizeof(cn));
2711	cn.expr = expr;
2712	cn.avtrue_list = t;
2713	cn.avfalse_list = f;
2714
2715	/* normalize/precompute expression */
2716	if (cond_normalize_expr(policydbp, &cn) < 0) {
2717		yyerror("problem normalizing conditional expression");
2718		return -1;
2719	}
2720
2721	/* get the existing conditional node, or create a new one */
2722	cn_old = get_current_cond_list(&cn);
2723	if (!cn_old) {
2724		return -1;
2725	}
2726
2727	append_cond_list(&cn);
2728
2729	/* note that there is no check here for duplicate rules, nor
2730	 * check that rule already exists in base -- that will be
2731	 * handled during conditional expansion, in expand.c */
2732
2733	cn.avtrue_list = NULL;
2734	cn.avfalse_list = NULL;
2735	cond_node_destroy(&cn);
2736
2737	return 0;
2738}
2739
2740cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
2741{
2742	struct cond_expr *expr, *e1 = NULL, *e2;
2743	cond_bool_datum_t *bool_var;
2744	char *id;
2745
2746	/* expressions are handled in the second pass */
2747	if (pass == 1) {
2748		if (expr_type == COND_BOOL) {
2749			while ((id = queue_remove(id_queue))) {
2750				free(id);
2751			}
2752		}
2753		return (cond_expr_t *) 1;	/* any non-NULL value */
2754	}
2755
2756	/* create a new expression struct */
2757	expr = malloc(sizeof(struct cond_expr));
2758	if (!expr) {
2759		yyerror("out of memory");
2760		return NULL;
2761	}
2762	memset(expr, 0, sizeof(cond_expr_t));
2763	expr->expr_type = expr_type;
2764
2765	/* create the type asked for */
2766	switch (expr_type) {
2767	case COND_NOT:
2768		e1 = NULL;
2769		e2 = (struct cond_expr *)arg1;
2770		while (e2) {
2771			e1 = e2;
2772			e2 = e2->next;
2773		}
2774		if (!e1 || e1->next) {
2775			yyerror("illegal conditional NOT expression");
2776			free(expr);
2777			return NULL;
2778		}
2779		e1->next = expr;
2780		return (struct cond_expr *)arg1;
2781	case COND_AND:
2782	case COND_OR:
2783	case COND_XOR:
2784	case COND_EQ:
2785	case COND_NEQ:
2786		e1 = NULL;
2787		e2 = (struct cond_expr *)arg1;
2788		while (e2) {
2789			e1 = e2;
2790			e2 = e2->next;
2791		}
2792		if (!e1 || e1->next) {
2793			yyerror
2794			    ("illegal left side of conditional binary op expression");
2795			free(expr);
2796			return NULL;
2797		}
2798		e1->next = (struct cond_expr *)arg2;
2799
2800		e1 = NULL;
2801		e2 = (struct cond_expr *)arg2;
2802		while (e2) {
2803			e1 = e2;
2804			e2 = e2->next;
2805		}
2806		if (!e1 || e1->next) {
2807			yyerror
2808			    ("illegal right side of conditional binary op expression");
2809			free(expr);
2810			return NULL;
2811		}
2812		e1->next = expr;
2813		return (struct cond_expr *)arg1;
2814	case COND_BOOL:
2815		id = (char *)queue_remove(id_queue);
2816		if (!id) {
2817			yyerror("bad conditional; expected boolean id");
2818			free(id);
2819			free(expr);
2820			return NULL;
2821		}
2822		if (!is_id_in_scope(SYM_BOOLS, id)) {
2823			yyerror2("boolean %s is not within scope", id);
2824			free(id);
2825			free(expr);
2826			return NULL;
2827		}
2828		bool_var =
2829		    (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
2830							 table,
2831							 (hashtab_key_t) id);
2832		if (!bool_var) {
2833			yyerror2("unknown boolean %s in conditional expression",
2834				 id);
2835			free(expr);
2836			free(id);
2837			return NULL;
2838		}
2839		expr->bool = bool_var->s.value;
2840		free(id);
2841		return expr;
2842	default:
2843		yyerror("illegal conditional expression");
2844		return NULL;
2845	}
2846}
2847
2848static int set_user_roles(role_set_t * set, char *id)
2849{
2850	role_datum_t *r;
2851	unsigned int i;
2852	ebitmap_node_t *node;
2853
2854	if (strcmp(id, "*") == 0) {
2855		free(id);
2856		yyerror("* is not allowed in user declarations");
2857		return -1;
2858	}
2859
2860	if (strcmp(id, "~") == 0) {
2861		free(id);
2862		yyerror("~ is not allowed in user declarations");
2863		return -1;
2864	}
2865
2866	if (!is_id_in_scope(SYM_ROLES, id)) {
2867		yyerror2("role %s is not within scope", id);
2868		free(id);
2869		return -1;
2870	}
2871	r = hashtab_search(policydbp->p_roles.table, id);
2872	if (!r) {
2873		yyerror2("unknown role %s", id);
2874		free(id);
2875		return -1;
2876	}
2877
2878	/* set the role and every role it dominates */
2879	ebitmap_for_each_bit(&r->dominates, node, i) {
2880		if (ebitmap_node_get_bit(node, i))
2881			if (ebitmap_set_bit(&set->roles, i, TRUE))
2882				goto oom;
2883	}
2884	free(id);
2885	return 0;
2886      oom:
2887	yyerror("out of memory");
2888	return -1;
2889}
2890
2891static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
2892{
2893	cat_datum_t *cdatum;
2894	int range_start, range_end, i;
2895
2896	if (id_has_dot(id)) {
2897		char *id_start = id;
2898		char *id_end = strchr(id, '.');
2899
2900		*(id_end++) = '\0';
2901
2902		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
2903							(hashtab_key_t)
2904							id_start);
2905		if (!cdatum) {
2906			yyerror2("unknown category %s", id_start);
2907			return -1;
2908		}
2909		range_start = cdatum->s.value - 1;
2910		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
2911							(hashtab_key_t) id_end);
2912		if (!cdatum) {
2913			yyerror2("unknown category %s", id_end);
2914			return -1;
2915		}
2916		range_end = cdatum->s.value - 1;
2917
2918		if (range_end < range_start) {
2919			yyerror2("category range is invalid");
2920			return -1;
2921		}
2922	} else {
2923		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
2924							(hashtab_key_t) id);
2925		if (!cdatum) {
2926			yyerror2("unknown category %s", id);
2927			return -1;
2928		}
2929		range_start = range_end = cdatum->s.value - 1;
2930	}
2931
2932	for (i = range_start; i <= range_end; i++) {
2933		if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
2934			uint32_t level_value = levdatum->level->sens - 1;
2935			policydb_index_others(NULL, policydbp, 0);
2936			yyerror2("category %s can not be associated "
2937				 "with level %s",
2938				 policydbp->p_cat_val_to_name[i],
2939				 policydbp->p_sens_val_to_name[level_value]);
2940			return -1;
2941		}
2942		if (ebitmap_set_bit(cats, i, TRUE)) {
2943			yyerror("out of memory");
2944			return -1;
2945		}
2946	}
2947
2948	return 0;
2949}
2950
2951static int parse_semantic_categories(char *id, level_datum_t * levdatum,
2952				     mls_semantic_cat_t ** cats)
2953{
2954	cat_datum_t *cdatum;
2955	mls_semantic_cat_t *newcat;
2956	unsigned int range_start, range_end;
2957
2958	if (id_has_dot(id)) {
2959		char *id_start = id;
2960		char *id_end = strchr(id, '.');
2961
2962		*(id_end++) = '\0';
2963
2964		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
2965							(hashtab_key_t)
2966							id_start);
2967		if (!cdatum) {
2968			yyerror2("unknown category %s", id_start);
2969			return -1;
2970		}
2971		range_start = cdatum->s.value;
2972
2973		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
2974							(hashtab_key_t) id_end);
2975		if (!cdatum) {
2976			yyerror2("unknown category %s", id_end);
2977			return -1;
2978		}
2979		range_end = cdatum->s.value;
2980	} else {
2981		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
2982							(hashtab_key_t) id);
2983		if (!cdatum) {
2984			yyerror2("unknown category %s", id);
2985			return -1;
2986		}
2987		range_start = range_end = cdatum->s.value;
2988	}
2989
2990	newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
2991	if (!newcat) {
2992		yyerror("out of memory");
2993		return -1;
2994	}
2995
2996	mls_semantic_cat_init(newcat);
2997	newcat->next = *cats;
2998	newcat->low = range_start;
2999	newcat->high = range_end;
3000
3001	*cats = newcat;
3002
3003	return 0;
3004}
3005
3006int define_user(void)
3007{
3008	char *id;
3009	user_datum_t *usrdatum;
3010	level_datum_t *levdatum;
3011	int l;
3012
3013	if (pass == 1) {
3014		while ((id = queue_remove(id_queue)))
3015			free(id);
3016		if (mlspol) {
3017			while ((id = queue_remove(id_queue)))
3018				free(id);
3019			id = queue_remove(id_queue);
3020			free(id);
3021			for (l = 0; l < 2; l++) {
3022				while ((id = queue_remove(id_queue))) {
3023					free(id);
3024				}
3025				id = queue_remove(id_queue);
3026				if (!id)
3027					break;
3028				free(id);
3029			}
3030		}
3031		return 0;
3032	}
3033
3034	if ((usrdatum = declare_user()) == NULL) {
3035		return -1;
3036	}
3037
3038	while ((id = queue_remove(id_queue))) {
3039		if (set_user_roles(&usrdatum->roles, id))
3040			continue;
3041	}
3042
3043	if (mlspol) {
3044		id = queue_remove(id_queue);
3045		if (!id) {
3046			yyerror("no default level specified for user");
3047			return -1;
3048		}
3049
3050		levdatum = (level_datum_t *)
3051		    hashtab_search(policydbp->p_levels.table,
3052				   (hashtab_key_t) id);
3053		if (!levdatum) {
3054			yyerror2("unknown sensitivity %s used in user"
3055				 " level definition", id);
3056			free(id);
3057			return -1;
3058		}
3059		free(id);
3060
3061		usrdatum->dfltlevel.sens = levdatum->level->sens;
3062
3063		while ((id = queue_remove(id_queue))) {
3064			if (parse_semantic_categories(id, levdatum,
3065			                            &usrdatum->dfltlevel.cat)) {
3066				free(id);
3067				return -1;
3068			}
3069			free(id);
3070		}
3071
3072		id = queue_remove(id_queue);
3073
3074		for (l = 0; l < 2; l++) {
3075			levdatum = (level_datum_t *)
3076			    hashtab_search(policydbp->p_levels.table,
3077					   (hashtab_key_t) id);
3078			if (!levdatum) {
3079				yyerror2("unknown sensitivity %s used in user"
3080					 " range definition", id);
3081				free(id);
3082				return -1;
3083			}
3084			free(id);
3085
3086			usrdatum->range.level[l].sens = levdatum->level->sens;
3087
3088			while ((id = queue_remove(id_queue))) {
3089				if (parse_semantic_categories(id, levdatum,
3090				               &usrdatum->range.level[l].cat)) {
3091					free(id);
3092					return -1;
3093				}
3094				free(id);
3095			}
3096
3097			id = queue_remove(id_queue);
3098			if (!id)
3099				break;
3100		}
3101
3102		if (l == 0) {
3103			if (mls_semantic_level_cpy(&usrdatum->range.level[1],
3104			                           &usrdatum->range.level[0])) {
3105				yyerror("out of memory");
3106				return -1;
3107			}
3108		}
3109	}
3110	return 0;
3111}
3112
3113static int parse_security_context(context_struct_t * c)
3114{
3115	char *id;
3116	role_datum_t *role;
3117	type_datum_t *typdatum;
3118	user_datum_t *usrdatum;
3119	level_datum_t *levdatum;
3120	int l;
3121
3122	if (pass == 1) {
3123		id = queue_remove(id_queue);
3124		free(id);	/* user  */
3125		id = queue_remove(id_queue);
3126		free(id);	/* role  */
3127		id = queue_remove(id_queue);
3128		free(id);	/* type  */
3129		if (mlspol) {
3130			id = queue_remove(id_queue);
3131			free(id);
3132			for (l = 0; l < 2; l++) {
3133				while ((id = queue_remove(id_queue))) {
3134					free(id);
3135				}
3136				id = queue_remove(id_queue);
3137				if (!id)
3138					break;
3139				free(id);
3140			}
3141		}
3142		return 0;
3143	}
3144
3145	context_init(c);
3146
3147	/* extract the user */
3148	id = queue_remove(id_queue);
3149	if (!id) {
3150		yyerror("no effective user?");
3151		goto bad;
3152	}
3153	if (!is_id_in_scope(SYM_USERS, id)) {
3154		yyerror2("user %s is not within scope", id);
3155		free(id);
3156		goto bad;
3157	}
3158	usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3159						   (hashtab_key_t) id);
3160	if (!usrdatum) {
3161		yyerror2("user %s is not defined", id);
3162		free(id);
3163		goto bad;
3164	}
3165	c->user = usrdatum->s.value;
3166
3167	/* no need to keep the user name */
3168	free(id);
3169
3170	/* extract the role */
3171	id = (char *)queue_remove(id_queue);
3172	if (!id) {
3173		yyerror("no role name for sid context definition?");
3174		return -1;
3175	}
3176	if (!is_id_in_scope(SYM_ROLES, id)) {
3177		yyerror2("role %s is not within scope", id);
3178		free(id);
3179		return -1;
3180	}
3181	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
3182					       (hashtab_key_t) id);
3183	if (!role) {
3184		yyerror2("role %s is not defined", id);
3185		free(id);
3186		return -1;
3187	}
3188	c->role = role->s.value;
3189
3190	/* no need to keep the role name */
3191	free(id);
3192
3193	/* extract the type */
3194	id = (char *)queue_remove(id_queue);
3195	if (!id) {
3196		yyerror("no type name for sid context definition?");
3197		return -1;
3198	}
3199	if (!is_id_in_scope(SYM_TYPES, id)) {
3200		yyerror2("type %s is not within scope", id);
3201		free(id);
3202		return -1;
3203	}
3204	typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
3205						   (hashtab_key_t) id);
3206	if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
3207		yyerror2("type %s is not defined or is an attribute", id);
3208		free(id);
3209		return -1;
3210	}
3211	c->type = typdatum->s.value;
3212
3213	/* no need to keep the type name */
3214	free(id);
3215
3216	if (mlspol) {
3217		/* extract the low sensitivity */
3218		id = (char *)queue_head(id_queue);
3219		if (!id) {
3220			yyerror("no sensitivity name for sid context"
3221				" definition?");
3222			return -1;
3223		}
3224
3225		id = (char *)queue_remove(id_queue);
3226		for (l = 0; l < 2; l++) {
3227			levdatum = (level_datum_t *)
3228			    hashtab_search(policydbp->p_levels.table,
3229					   (hashtab_key_t) id);
3230			if (!levdatum) {
3231				yyerror2("Sensitivity %s is not defined", id);
3232				free(id);
3233				return -1;
3234			}
3235			free(id);
3236			c->range.level[l].sens = levdatum->level->sens;
3237
3238			/* extract low category set */
3239			while ((id = queue_remove(id_queue))) {
3240				if (parse_categories(id, levdatum,
3241						     &c->range.level[l].cat)) {
3242					free(id);
3243					return -1;
3244				}
3245				free(id);
3246			}
3247
3248			/* extract high sensitivity */
3249			id = (char *)queue_remove(id_queue);
3250			if (!id)
3251				break;
3252		}
3253
3254		if (l == 0) {
3255			c->range.level[1].sens = c->range.level[0].sens;
3256			if (ebitmap_cpy(&c->range.level[1].cat,
3257					&c->range.level[0].cat)) {
3258
3259				yyerror("out of memory");
3260				goto bad;
3261			}
3262		}
3263	}
3264
3265	if (!policydb_context_isvalid(policydbp, c)) {
3266		yyerror("invalid security context");
3267		goto bad;
3268	}
3269	return 0;
3270
3271      bad:
3272	context_destroy(c);
3273
3274	return -1;
3275}
3276
3277int define_initial_sid_context(void)
3278{
3279	char *id;
3280	ocontext_t *c, *head;
3281
3282	if (pass == 1) {
3283		id = (char *)queue_remove(id_queue);
3284		free(id);
3285		parse_security_context(NULL);
3286		return 0;
3287	}
3288
3289	id = (char *)queue_remove(id_queue);
3290	if (!id) {
3291		yyerror("no sid name for SID context definition?");
3292		return -1;
3293	}
3294	head = policydbp->ocontexts[OCON_ISID];
3295	for (c = head; c; c = c->next) {
3296		if (!strcmp(id, c->u.name))
3297			break;
3298	}
3299
3300	if (!c) {
3301		yyerror2("SID %s is not defined", id);
3302		free(id);
3303		return -1;
3304	}
3305	if (c->context[0].user) {
3306		yyerror2("The context for SID %s is multiply defined", id);
3307		free(id);
3308		return -1;
3309	}
3310	/* no need to keep the sid name */
3311	free(id);
3312
3313	if (parse_security_context(&c->context[0]))
3314		return -1;
3315
3316	return 0;
3317}
3318
3319int define_fs_context(unsigned int major, unsigned int minor)
3320{
3321	ocontext_t *newc, *c, *head;
3322
3323	if (pass == 1) {
3324		parse_security_context(NULL);
3325		parse_security_context(NULL);
3326		return 0;
3327	}
3328
3329	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
3330	if (!newc) {
3331		yyerror("out of memory");
3332		return -1;
3333	}
3334	memset(newc, 0, sizeof(ocontext_t));
3335
3336	newc->u.name = (char *)malloc(6);
3337	if (!newc->u.name) {
3338		yyerror("out of memory");
3339		free(newc);
3340		return -1;
3341	}
3342	sprintf(newc->u.name, "%02x:%02x", major, minor);
3343
3344	if (parse_security_context(&newc->context[0])) {
3345		free(newc->u.name);
3346		free(newc);
3347		return -1;
3348	}
3349	if (parse_security_context(&newc->context[1])) {
3350		context_destroy(&newc->context[0]);
3351		free(newc->u.name);
3352		free(newc);
3353		return -1;
3354	}
3355	head = policydbp->ocontexts[OCON_FS];
3356
3357	for (c = head; c; c = c->next) {
3358		if (!strcmp(newc->u.name, c->u.name)) {
3359			yyerror2("duplicate entry for file system %s",
3360				 newc->u.name);
3361			context_destroy(&newc->context[0]);
3362			context_destroy(&newc->context[1]);
3363			free(newc->u.name);
3364			free(newc);
3365			return -1;
3366		}
3367	}
3368
3369	newc->next = head;
3370	policydbp->ocontexts[OCON_FS] = newc;
3371
3372	return 0;
3373}
3374
3375int define_port_context(unsigned int low, unsigned int high)
3376{
3377	ocontext_t *newc, *c, *l, *head;
3378	unsigned int protocol;
3379	char *id;
3380
3381	if (pass == 1) {
3382		id = (char *)queue_remove(id_queue);
3383		free(id);
3384		parse_security_context(NULL);
3385		return 0;
3386	}
3387
3388	newc = malloc(sizeof(ocontext_t));
3389	if (!newc) {
3390		yyerror("out of memory");
3391		return -1;
3392	}
3393	memset(newc, 0, sizeof(ocontext_t));
3394
3395	id = (char *)queue_remove(id_queue);
3396	if (!id) {
3397		free(newc);
3398		return -1;
3399	}
3400	if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
3401		protocol = IPPROTO_TCP;
3402	} else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
3403		protocol = IPPROTO_UDP;
3404	} else {
3405		yyerror2("unrecognized protocol %s", id);
3406		free(newc);
3407		return -1;
3408	}
3409
3410	newc->u.port.protocol = protocol;
3411	newc->u.port.low_port = low;
3412	newc->u.port.high_port = high;
3413
3414	if (low > high) {
3415		yyerror2("low port %d exceeds high port %d", low, high);
3416		free(newc);
3417		return -1;
3418	}
3419
3420	if (parse_security_context(&newc->context[0])) {
3421		free(newc);
3422		return -1;
3423	}
3424
3425	/* Preserve the matching order specified in the configuration. */
3426	head = policydbp->ocontexts[OCON_PORT];
3427	for (l = NULL, c = head; c; l = c, c = c->next) {
3428		unsigned int prot2, low2, high2;
3429
3430		prot2 = c->u.port.protocol;
3431		low2 = c->u.port.low_port;
3432		high2 = c->u.port.high_port;
3433		if (protocol != prot2)
3434			continue;
3435		if (low == low2 && high == high2) {
3436			yyerror2("duplicate portcon entry for %s %d-%d ", id,
3437				 low, high);
3438			goto bad;
3439		}
3440		if (low2 <= low && high2 >= high) {
3441			yyerror2("portcon entry for %s %d-%d hidden by earlier "
3442				 "entry for %d-%d", id, low, high, low2, high2);
3443			goto bad;
3444		}
3445	}
3446
3447	if (l)
3448		l->next = newc;
3449	else
3450		policydbp->ocontexts[OCON_PORT] = newc;
3451
3452	return 0;
3453
3454      bad:
3455	free(newc);
3456	return -1;
3457}
3458
3459int define_netif_context(void)
3460{
3461	ocontext_t *newc, *c, *head;
3462
3463	if (pass == 1) {
3464		free(queue_remove(id_queue));
3465		parse_security_context(NULL);
3466		parse_security_context(NULL);
3467		return 0;
3468	}
3469
3470	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
3471	if (!newc) {
3472		yyerror("out of memory");
3473		return -1;
3474	}
3475	memset(newc, 0, sizeof(ocontext_t));
3476
3477	newc->u.name = (char *)queue_remove(id_queue);
3478	if (!newc->u.name) {
3479		free(newc);
3480		return -1;
3481	}
3482	if (parse_security_context(&newc->context[0])) {
3483		free(newc->u.name);
3484		free(newc);
3485		return -1;
3486	}
3487	if (parse_security_context(&newc->context[1])) {
3488		context_destroy(&newc->context[0]);
3489		free(newc->u.name);
3490		free(newc);
3491		return -1;
3492	}
3493	head = policydbp->ocontexts[OCON_NETIF];
3494
3495	for (c = head; c; c = c->next) {
3496		if (!strcmp(newc->u.name, c->u.name)) {
3497			yyerror2("duplicate entry for network interface %s",
3498				 newc->u.name);
3499			context_destroy(&newc->context[0]);
3500			context_destroy(&newc->context[1]);
3501			free(newc->u.name);
3502			free(newc);
3503			return -1;
3504		}
3505	}
3506
3507	newc->next = head;
3508	policydbp->ocontexts[OCON_NETIF] = newc;
3509	return 0;
3510}
3511
3512int define_ipv4_node_context()
3513{
3514	char *id;
3515	int rc = 0;
3516	struct in_addr addr, mask;
3517	ocontext_t *newc, *c, *l, *head;
3518
3519	if (pass == 1) {
3520		free(queue_remove(id_queue));
3521		free(queue_remove(id_queue));
3522		parse_security_context(NULL);
3523		goto out;
3524	}
3525
3526	id = queue_remove(id_queue);
3527	if (!id) {
3528		yyerror("failed to read ipv4 address");
3529		rc = -1;
3530		goto out;
3531	}
3532
3533	rc = inet_pton(AF_INET, id, &addr);
3534	free(id);
3535	if (rc < 1) {
3536		yyerror("failed to parse ipv4 address");
3537		if (rc == 0)
3538			rc = -1;
3539		goto out;
3540	}
3541
3542	id = queue_remove(id_queue);
3543	if (!id) {
3544		yyerror("failed to read ipv4 address");
3545		rc = -1;
3546		goto out;
3547	}
3548
3549	rc = inet_pton(AF_INET, id, &mask);
3550	free(id);
3551	if (rc < 1) {
3552		yyerror("failed to parse ipv4 mask");
3553		if (rc == 0)
3554			rc = -1;
3555		goto out;
3556	}
3557
3558	newc = malloc(sizeof(ocontext_t));
3559	if (!newc) {
3560		yyerror("out of memory");
3561		rc = -1;
3562		goto out;
3563	}
3564
3565	memset(newc, 0, sizeof(ocontext_t));
3566	newc->u.node.addr = addr.s_addr;
3567	newc->u.node.mask = mask.s_addr;
3568
3569	if (parse_security_context(&newc->context[0])) {
3570		free(newc);
3571		return -1;
3572	}
3573
3574	/* Create order of most specific to least retaining
3575	   the order specified in the configuration. */
3576	head = policydbp->ocontexts[OCON_NODE];
3577	for (l = NULL, c = head; c; l = c, c = c->next) {
3578		if (newc->u.node.mask > c->u.node.mask)
3579			break;
3580	}
3581
3582	newc->next = c;
3583
3584	if (l)
3585		l->next = newc;
3586	else
3587		policydbp->ocontexts[OCON_NODE] = newc;
3588	rc = 0;
3589out:
3590	return rc;
3591}
3592
3593int define_ipv6_node_context(void)
3594{
3595	char *id;
3596	int rc = 0;
3597	struct in6_addr addr, mask;
3598	ocontext_t *newc, *c, *l, *head;
3599
3600	if (pass == 1) {
3601		free(queue_remove(id_queue));
3602		free(queue_remove(id_queue));
3603		parse_security_context(NULL);
3604		goto out;
3605	}
3606
3607	id = queue_remove(id_queue);
3608	if (!id) {
3609		yyerror("failed to read ipv6 address");
3610		rc = -1;
3611		goto out;
3612	}
3613
3614	rc = inet_pton(AF_INET6, id, &addr);
3615	free(id);
3616	if (rc < 1) {
3617		yyerror("failed to parse ipv6 address");
3618		if (rc == 0)
3619			rc = -1;
3620		goto out;
3621	}
3622
3623	id = queue_remove(id_queue);
3624	if (!id) {
3625		yyerror("failed to read ipv6 address");
3626		rc = -1;
3627		goto out;
3628	}
3629
3630	rc = inet_pton(AF_INET6, id, &mask);
3631	free(id);
3632	if (rc < 1) {
3633		yyerror("failed to parse ipv6 mask");
3634		if (rc == 0)
3635			rc = -1;
3636		goto out;
3637	}
3638
3639	newc = malloc(sizeof(ocontext_t));
3640	if (!newc) {
3641		yyerror("out of memory");
3642		rc = -1;
3643		goto out;
3644	}
3645
3646	memset(newc, 0, sizeof(ocontext_t));
3647	memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
3648	memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
3649
3650	if (parse_security_context(&newc->context[0])) {
3651		free(newc);
3652		rc = -1;
3653		goto out;
3654	}
3655
3656	/* Create order of most specific to least retaining
3657	   the order specified in the configuration. */
3658	head = policydbp->ocontexts[OCON_NODE6];
3659	for (l = NULL, c = head; c; l = c, c = c->next) {
3660		if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
3661			break;
3662	}
3663
3664	newc->next = c;
3665
3666	if (l)
3667		l->next = newc;
3668	else
3669		policydbp->ocontexts[OCON_NODE6] = newc;
3670
3671	rc = 0;
3672      out:
3673	return rc;
3674}
3675
3676int define_fs_use(int behavior)
3677{
3678	ocontext_t *newc, *c, *head;
3679
3680	if (pass == 1) {
3681		free(queue_remove(id_queue));
3682		parse_security_context(NULL);
3683		return 0;
3684	}
3685
3686	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
3687	if (!newc) {
3688		yyerror("out of memory");
3689		return -1;
3690	}
3691	memset(newc, 0, sizeof(ocontext_t));
3692
3693	newc->u.name = (char *)queue_remove(id_queue);
3694	if (!newc->u.name) {
3695		free(newc);
3696		return -1;
3697	}
3698	newc->v.behavior = behavior;
3699	if (parse_security_context(&newc->context[0])) {
3700		free(newc->u.name);
3701		free(newc);
3702		return -1;
3703	}
3704
3705	head = policydbp->ocontexts[OCON_FSUSE];
3706
3707	for (c = head; c; c = c->next) {
3708		if (!strcmp(newc->u.name, c->u.name)) {
3709			yyerror2("duplicate fs_use entry for filesystem type %s",
3710				 newc->u.name);
3711			context_destroy(&newc->context[0]);
3712			free(newc->u.name);
3713			free(newc);
3714			return -1;
3715		}
3716	}
3717
3718	newc->next = head;
3719	policydbp->ocontexts[OCON_FSUSE] = newc;
3720	return 0;
3721}
3722
3723int define_genfs_context_helper(char *fstype, int has_type)
3724{
3725	struct genfs *genfs_p, *genfs, *newgenfs;
3726	ocontext_t *newc, *c, *head, *p;
3727	char *type = NULL;
3728	int len, len2;
3729
3730	if (pass == 1) {
3731		free(fstype);
3732		free(queue_remove(id_queue));
3733		if (has_type)
3734			free(queue_remove(id_queue));
3735		parse_security_context(NULL);
3736		return 0;
3737	}
3738
3739	for (genfs_p = NULL, genfs = policydbp->genfs;
3740	     genfs; genfs_p = genfs, genfs = genfs->next) {
3741		if (strcmp(fstype, genfs->fstype) <= 0)
3742			break;
3743	}
3744
3745	if (!genfs || strcmp(fstype, genfs->fstype)) {
3746		newgenfs = malloc(sizeof(struct genfs));
3747		if (!newgenfs) {
3748			yyerror("out of memory");
3749			return -1;
3750		}
3751		memset(newgenfs, 0, sizeof(struct genfs));
3752		newgenfs->fstype = fstype;
3753		newgenfs->next = genfs;
3754		if (genfs_p)
3755			genfs_p->next = newgenfs;
3756		else
3757			policydbp->genfs = newgenfs;
3758		genfs = newgenfs;
3759	}
3760
3761	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
3762	if (!newc) {
3763		yyerror("out of memory");
3764		return -1;
3765	}
3766	memset(newc, 0, sizeof(ocontext_t));
3767
3768	newc->u.name = (char *)queue_remove(id_queue);
3769	if (!newc->u.name)
3770		goto fail;
3771	if (has_type) {
3772		type = (char *)queue_remove(id_queue);
3773		if (!type)
3774			goto fail;
3775		if (type[1] != 0) {
3776			yyerror2("invalid type %s", type);
3777			goto fail;
3778		}
3779		switch (type[0]) {
3780		case 'b':
3781			newc->v.sclass = SECCLASS_BLK_FILE;
3782			break;
3783		case 'c':
3784			newc->v.sclass = SECCLASS_CHR_FILE;
3785			break;
3786		case 'd':
3787			newc->v.sclass = SECCLASS_DIR;
3788			break;
3789		case 'p':
3790			newc->v.sclass = SECCLASS_FIFO_FILE;
3791			break;
3792		case 'l':
3793			newc->v.sclass = SECCLASS_LNK_FILE;
3794			break;
3795		case 's':
3796			newc->v.sclass = SECCLASS_SOCK_FILE;
3797			break;
3798		case '-':
3799			newc->v.sclass = SECCLASS_FILE;
3800			break;
3801		default:
3802			yyerror2("invalid type %s", type);
3803			goto fail;
3804		}
3805	}
3806	if (parse_security_context(&newc->context[0]))
3807		goto fail;
3808
3809	head = genfs->head;
3810
3811	for (p = NULL, c = head; c; p = c, c = c->next) {
3812		if (!strcmp(newc->u.name, c->u.name) &&
3813		    (!newc->v.sclass || !c->v.sclass
3814		     || newc->v.sclass == c->v.sclass)) {
3815			yyerror2("duplicate entry for genfs entry (%s, %s)",
3816				 fstype, newc->u.name);
3817			goto fail;
3818		}
3819		len = strlen(newc->u.name);
3820		len2 = strlen(c->u.name);
3821		if (len > len2)
3822			break;
3823	}
3824
3825	newc->next = c;
3826	if (p)
3827		p->next = newc;
3828	else
3829		genfs->head = newc;
3830	return 0;
3831      fail:
3832	if (type)
3833		free(type);
3834	context_destroy(&newc->context[0]);
3835	if (fstype)
3836		free(fstype);
3837	if (newc->u.name)
3838		free(newc->u.name);
3839	free(newc);
3840	return -1;
3841}
3842
3843int define_genfs_context(int has_type)
3844{
3845	return define_genfs_context_helper(queue_remove(id_queue), has_type);
3846}
3847
3848int define_range_trans(int class_specified)
3849{
3850	char *id;
3851	level_datum_t *levdatum = 0;
3852	class_datum_t *cladatum;
3853	range_trans_rule_t *rule;
3854	int l, add = 1;
3855
3856	if (!mlspol) {
3857		yyerror("range_transition rule in non-MLS configuration");
3858		return -1;
3859	}
3860
3861	if (pass == 1) {
3862		while ((id = queue_remove(id_queue)))
3863			free(id);
3864		while ((id = queue_remove(id_queue)))
3865			free(id);
3866		if (class_specified)
3867			while ((id = queue_remove(id_queue)))
3868				free(id);
3869		id = queue_remove(id_queue);
3870		free(id);
3871		for (l = 0; l < 2; l++) {
3872			while ((id = queue_remove(id_queue))) {
3873				free(id);
3874			}
3875			id = queue_remove(id_queue);
3876			if (!id)
3877				break;
3878			free(id);
3879		}
3880		return 0;
3881	}
3882
3883	rule = malloc(sizeof(struct range_trans_rule));
3884	if (!rule) {
3885		yyerror("out of memory");
3886		return -1;
3887	}
3888	range_trans_rule_init(rule);
3889
3890	while ((id = queue_remove(id_queue))) {
3891		if (set_types(&rule->stypes, id, &add, 0))
3892			goto out;
3893	}
3894	add = 1;
3895	while ((id = queue_remove(id_queue))) {
3896		if (set_types(&rule->ttypes, id, &add, 0))
3897			goto out;
3898	}
3899
3900	if (class_specified) {
3901		while ((id = queue_remove(id_queue))) {
3902			if (!is_id_in_scope(SYM_CLASSES, id)) {
3903				yyerror2("class %s is not within scope", id);
3904				free(id);
3905				goto out;
3906			}
3907			cladatum = hashtab_search(policydbp->p_classes.table,
3908			                          id);
3909			if (!cladatum) {
3910				yyerror2("unknown class %s", id);
3911				goto out;
3912			}
3913
3914			ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1,
3915			                TRUE);
3916			free(id);
3917		}
3918	} else {
3919		cladatum = hashtab_search(policydbp->p_classes.table,
3920		                          "process");
3921		if (!cladatum) {
3922			yyerror2("could not find process class for "
3923			         "legacy range_transition statement");
3924			goto out;
3925		}
3926
3927		ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
3928	}
3929
3930	id = (char *)queue_remove(id_queue);
3931	if (!id) {
3932		yyerror("no range in range_transition definition?");
3933		goto out;
3934	}
3935	for (l = 0; l < 2; l++) {
3936		levdatum = hashtab_search(policydbp->p_levels.table, id);
3937		if (!levdatum) {
3938			yyerror2("unknown level %s used in range_transition "
3939			         "definition", id);
3940			free(id);
3941			goto out;
3942		}
3943		free(id);
3944
3945		rule->trange.level[l].sens = levdatum->level->sens;
3946
3947		while ((id = queue_remove(id_queue))) {
3948			if (parse_semantic_categories(id, levdatum,
3949			                          &rule->trange.level[l].cat)) {
3950				free(id);
3951				goto out;
3952			}
3953			free(id);
3954		}
3955
3956		id = (char *)queue_remove(id_queue);
3957		if (!id)
3958			break;
3959	}
3960	if (l == 0) {
3961		if (mls_semantic_level_cpy(&rule->trange.level[1],
3962		                           &rule->trange.level[0])) {
3963			yyerror("out of memory");
3964			goto out;
3965		}
3966	}
3967
3968	append_range_trans(rule);
3969	return 0;
3970
3971out:
3972	range_trans_rule_destroy(rule);
3973	return -1;
3974}
3975
3976/* FLASK */
3977