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