policy_define.c

Go to the documentation of this file.
00001 /**
00002  * @file policy_define.c
00003  *
00004  * This file is based upon checkpolicy/policy_define.c from NSA's SVN
00005  * repository.  It has been modified to support older policy formats.
00006  */
00007 
00008 /*
00009  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
00010  */
00011 
00012 /*
00013  * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
00014  *
00015  *      Support for enhanced MLS infrastructure.
00016  *
00017  * Updated: David Caplan, <dac@tresys.com>
00018  *
00019  *      Added conditional policy language extensions
00020  *
00021  * Updated: Joshua Brindle <jbrindle@tresys.com>
00022  *          Karl MacMillan <kmacmillan@mentalrootkit.com>
00023  *          Jason Tang     <jtang@tresys.com>
00024  *
00025  *      Added support for binary policy modules
00026  *
00027  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
00028  * Copyright (C) 2003 - 2008 Tresys Technology, LLC
00029  * Copyright (C) 2007 Red Hat Inc.
00030  *      This program is free software; you can redistribute it and/or modify
00031  *      it under the terms of the GNU General Public License as published by
00032  *      the Free Software Foundation, version 2.
00033  */
00034 
00035 /* FLASK */
00036 
00037 #include <config.h>
00038 
00039 #include <sys/types.h>
00040 #include <assert.h>
00041 #include <stdarg.h>
00042 #include <stdint.h>
00043 #include <stdio.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <sys/socket.h>
00047 #include <netinet/in.h>
00048 #include <arpa/inet.h>
00049 #include <stdlib.h>
00050 
00051 #include <sepol/policydb/expand.h>
00052 #include <sepol/policydb/policydb.h>
00053 #include <sepol/policydb/services.h>
00054 #include <sepol/policydb/conditional.h>
00055 #include <sepol/policydb/flask.h>
00056 #include <sepol/policydb/hierarchy.h>
00057 #ifdef HAVE_SEPOL_POLICYCAPS
00058 #include <sepol/policydb/polcaps.h>
00059 #endif
00060 
00061 #include "queue.h"
00062 #include <qpol/policy.h>
00063 #include "module_compiler.h"
00064 #include "policy_define.h"
00065 
00066 policydb_t *policydbp;
00067 queue_t id_queue = 0;
00068 unsigned int pass;
00069 static int load_rules;
00070 static unsigned int num_rules = 0;
00071 char *curfile = 0;
00072 int mlspol = 0;
00073 
00074 extern unsigned long policydb_lineno;
00075 extern unsigned long source_lineno;
00076 extern unsigned int policydb_errors;
00077 
00078 extern int yywarn(char *msg);
00079 extern int yyerror(char *msg);
00080 
00081 #define ERRORMSG_LEN 255
00082 static char errormsg[ERRORMSG_LEN + 1] = { 0 };
00083 
00084 static int id_has_dot(char *id);
00085 static int parse_security_context(context_struct_t * c);
00086 
00087 /* initialize all of the state variables for the scanner/parser */
00088 void init_parser(int pass_number, int do_rules)
00089 {
00090         policydb_lineno = 1;
00091         source_lineno = 1;
00092         policydb_errors = 0;
00093         pass = pass_number;
00094         load_rules = do_rules;
00095         num_rules = 0;
00096 }
00097 
00098 void yyerror2(char *fmt, ...)
00099 {
00100         va_list ap;
00101         va_start(ap, fmt);
00102         vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
00103         yyerror(errormsg);
00104         va_end(ap);
00105 }
00106 
00107 int define_mls(void)
00108 {
00109         mlspol = 1;
00110         policydbp->mls = 1;
00111 
00112         return 0;
00113 }
00114 
00115 /* Add a rule onto an avtab hash table only if it does not already
00116  * exist.  (Note that the avtab is discarded afterwards; it will be
00117  * regenerated during expansion.)  Return 1 if rule was added (or
00118  * otherwise handled successfully), 0 if it conflicted with something,
00119  * 2 if the rule is not to be added, or -1 on error.
00120  */
00121 static int insert_check_type_rule(avrule_t * rule, avtab_t * avtab, cond_av_list_t ** list, cond_av_list_t ** other)
00122 {
00123         int ret;
00124 
00125         if (num_rules && !load_rules)
00126                 return 2;
00127 
00128 #ifdef SEPOL_DYNAMIC_AVTAB
00129         if (!avtab->htable)
00130                 if (avtab_alloc(avtab, MAX_AVTAB_SIZE))
00131                         return -1;
00132 #endif
00133 
00134         ret = expand_rule(NULL, policydbp, rule, avtab, list, other, 0);
00135         if (ret < 0) {
00136                 yyerror("Failed on expanding rule");
00137         }
00138         return ret;
00139 }
00140 int insert_separator(int push)
00141 {
00142         int error;
00143 
00144         if (push)
00145                 error = queue_push(id_queue, 0);
00146         else
00147                 error = queue_insert(id_queue, 0);
00148 
00149         if (error) {
00150                 yyerror("queue overflow");
00151                 return -1;
00152         }
00153         return 0;
00154 }
00155 
00156 int insert_id(char *id, int push)
00157 {
00158         char *newid = 0;
00159         int error;
00160 
00161         newid = (char *)malloc(strlen(id) + 1);
00162         if (!newid) {
00163                 yyerror("out of memory");
00164                 return -1;
00165         }
00166         strcpy(newid, id);
00167         if (push)
00168                 error = queue_push(id_queue, (queue_element_t) newid);
00169         else
00170                 error = queue_insert(id_queue, (queue_element_t) newid);
00171 
00172         if (error) {
00173                 yyerror("queue overflow");
00174                 free(newid);
00175                 return -1;
00176         }
00177         return 0;
00178 }
00179 
00180 /* If the identifier has a dot within it and that its first character
00181    is not a dot then return 1, else return 0. */
00182 static int id_has_dot(char *id)
00183 {
00184         if (strchr(id, '.') >= id + 1) {
00185                 return 1;
00186         }
00187         return 0;
00188 }
00189 
00190 int define_class(void)
00191 {
00192         char *id = 0;
00193         class_datum_t *datum = 0;
00194         int ret;
00195         uint32_t value;
00196 
00197         if (pass == 2) {
00198                 id = queue_remove(id_queue);
00199                 free(id);
00200                 return 0;
00201         }
00202 
00203         id = (char *)queue_remove(id_queue);
00204         if (!id) {
00205                 yyerror("no class name for class definition?");
00206                 return -1;
00207         }
00208         datum = (class_datum_t *) malloc(sizeof(class_datum_t));
00209         if (!datum) {
00210                 yyerror("out of memory");
00211                 goto bad;
00212         }
00213         memset(datum, 0, sizeof(class_datum_t));
00214         ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
00215         switch (ret) {
00216         case -3:{
00217                 yyerror("Out of memory!");
00218                 goto bad;
00219         }
00220         case -2:{
00221                 yyerror2("duplicate declaration of class %s", id);
00222                 goto bad;
00223         }
00224         case -1:{
00225                 yyerror("could not declare class here");
00226                 goto bad;
00227         }
00228         case 0:
00229         case 1:{
00230                 break;
00231         }
00232         default:{
00233                 assert(0);             /* should never get here */
00234         }
00235         }
00236         datum->s.value = value;
00237         return 0;
00238 
00239       bad:
00240         if (id)
00241                 free(id);
00242         if (datum)
00243                 free(datum);
00244         return -1;
00245 }
00246 
00247 int define_polcap(void)
00248 {
00249         char *id = 0;
00250         int capnum;
00251 
00252         if (pass == 2) {
00253                 id = queue_remove(id_queue);
00254                 free(id);
00255                 return 0;
00256         }
00257 
00258         id = (char *)queue_remove(id_queue);
00259         if (!id) {
00260                 yyerror("no capability name for policycap definition?");
00261                 goto bad;
00262         }
00263 #ifdef HAVE_SEPOL_POLICYCAPS
00264         /* Check for valid cap name -> number mapping */
00265         capnum = sepol_polcap_getnum(id);
00266         if (capnum < 0) {
00267                 yyerror2("invalid policy capability name %s", id);
00268                 goto bad;
00269         }
00270 
00271         /* Store it */
00272         if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
00273                 yyerror("out of memory");
00274                 goto bad;
00275         }
00276 #else
00277         yyerror("This version of SETools does not have policycap enabled.");
00278 #endif
00279 
00280         free(id);
00281         return 0;
00282 
00283       bad:
00284         free(id);
00285         return -1;
00286 }
00287 
00288 int define_initial_sid(void)
00289 {
00290         char *id = 0;
00291         ocontext_t *newc = 0, *c, *head;
00292 
00293         if (pass == 2) {
00294                 id = queue_remove(id_queue);
00295                 free(id);
00296                 return 0;
00297         }
00298 
00299         id = (char *)queue_remove(id_queue);
00300         if (!id) {
00301                 yyerror("no sid name for SID definition?");
00302                 return -1;
00303         }
00304         newc = (ocontext_t *) malloc(sizeof(ocontext_t));
00305         if (!newc) {
00306                 yyerror("out of memory");
00307                 goto bad;
00308         }
00309         memset(newc, 0, sizeof(ocontext_t));
00310         newc->u.name = id;
00311         context_init(&newc->context[0]);
00312         head = policydbp->ocontexts[OCON_ISID];
00313 
00314         for (c = head; c; c = c->next) {
00315                 if (!strcmp(newc->u.name, c->u.name)) {
00316                         yyerror2("duplicate initial SID %s", id);
00317                         goto bad;
00318                 }
00319         }
00320 
00321         if (head) {
00322                 newc->sid[0] = head->sid[0] + 1;
00323         } else {
00324                 newc->sid[0] = 1;
00325         }
00326         newc->next = head;
00327         policydbp->ocontexts[OCON_ISID] = newc;
00328 
00329         return 0;
00330 
00331       bad:
00332         if (id)
00333                 free(id);
00334         if (newc)
00335                 free(newc);
00336         return -1;
00337 }
00338 
00339 int define_common_perms(void)
00340 {
00341         char *id = 0, *perm = 0;
00342         common_datum_t *comdatum = 0;
00343         perm_datum_t *perdatum = 0;
00344         int ret;
00345 
00346         if (pass == 2) {
00347                 while ((id = queue_remove(id_queue)))
00348                         free(id);
00349                 return 0;
00350         }
00351 
00352         id = (char *)queue_remove(id_queue);
00353         if (!id) {
00354                 yyerror("no common name for common perm definition?");
00355                 return -1;
00356         }
00357         comdatum = hashtab_search(policydbp->p_commons.table, id);
00358         if (comdatum) {
00359                 yyerror2("duplicate declaration for common %s\n", id);
00360                 return -1;
00361         }
00362         comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
00363         if (!comdatum) {
00364                 yyerror("out of memory");
00365                 goto bad;
00366         }
00367         memset(comdatum, 0, sizeof(common_datum_t));
00368         ret = hashtab_insert(policydbp->p_commons.table, (hashtab_key_t) id, (hashtab_datum_t) comdatum);
00369 
00370         if (ret == SEPOL_EEXIST) {
00371                 yyerror("duplicate common definition");
00372                 goto bad;
00373         }
00374         if (ret == SEPOL_ENOMEM) {
00375                 yyerror("hash table overflow");
00376                 goto bad;
00377         }
00378         comdatum->s.value = policydbp->p_commons.nprim + 1;
00379         if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
00380                 yyerror("out of memory");
00381                 goto bad;
00382         }
00383         policydbp->p_commons.nprim++;
00384         while ((perm = queue_remove(id_queue))) {
00385                 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
00386                 if (!perdatum) {
00387                         yyerror("out of memory");
00388                         goto bad_perm;
00389                 }
00390                 memset(perdatum, 0, sizeof(perm_datum_t));
00391                 perdatum->s.value = comdatum->permissions.nprim + 1;
00392 
00393                 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
00394                         yyerror("too many permissions to fit in an access vector");
00395                         goto bad_perm;
00396                 }
00397                 ret = hashtab_insert(comdatum->permissions.table, (hashtab_key_t) perm, (hashtab_datum_t) perdatum);
00398 
00399                 if (ret == SEPOL_EEXIST) {
00400                         yyerror2("duplicate permission %s in common %s", perm, id);
00401                         goto bad_perm;
00402                 }
00403                 if (ret == SEPOL_ENOMEM) {
00404                         yyerror("hash table overflow");
00405                         goto bad_perm;
00406                 }
00407                 comdatum->permissions.nprim++;
00408         }
00409 
00410         return 0;
00411 
00412       bad:
00413         if (id)
00414                 free(id);
00415         if (comdatum)
00416                 free(comdatum);
00417         return -1;
00418 
00419       bad_perm:
00420         if (perm)
00421                 free(perm);
00422         if (perdatum)
00423                 free(perdatum);
00424         return -1;
00425 }
00426 
00427 int define_av_perms(int inherits)
00428 {
00429         char *id;
00430         class_datum_t *cladatum;
00431         common_datum_t *comdatum;
00432         perm_datum_t *perdatum = 0, *perdatum2 = 0;
00433         int ret;
00434 
00435         if (pass == 2) {
00436                 while ((id = queue_remove(id_queue)))
00437                         free(id);
00438                 return 0;
00439         }
00440 
00441         id = (char *)queue_remove(id_queue);
00442         if (!id) {
00443                 yyerror("no tclass name for av perm definition?");
00444                 return -1;
00445         }
00446         cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, (hashtab_key_t) id);
00447         if (!cladatum) {
00448                 yyerror2("class %s is not defined", id);
00449                 goto bad;
00450         }
00451         free(id);
00452 
00453         if (cladatum->comdatum || cladatum->permissions.nprim) {
00454                 yyerror("duplicate access vector definition");
00455                 return -1;
00456         }
00457         if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
00458                 yyerror("out of memory");
00459                 return -1;
00460         }
00461         if (inherits) {
00462                 id = (char *)queue_remove(id_queue);
00463                 if (!id) {
00464                         yyerror("no inherits name for access vector definition?");
00465                         return -1;
00466                 }
00467                 comdatum = (common_datum_t *) hashtab_search(policydbp->p_commons.table, (hashtab_key_t) id);
00468 
00469                 if (!comdatum) {
00470                         yyerror2("common %s is not defined", id);
00471                         goto bad;
00472                 }
00473                 cladatum->comkey = id;
00474                 cladatum->comdatum = comdatum;
00475 
00476                 /*
00477                  * Class-specific permissions start with values
00478                  * after the last common permission.
00479                  */
00480                 cladatum->permissions.nprim += comdatum->permissions.nprim;
00481         }
00482         while ((id = queue_remove(id_queue))) {
00483                 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
00484                 if (!perdatum) {
00485                         yyerror("out of memory");
00486                         goto bad;
00487                 }
00488                 memset(perdatum, 0, sizeof(perm_datum_t));
00489                 perdatum->s.value = ++cladatum->permissions.nprim;
00490 
00491                 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
00492                         yyerror("too many permissions to fit in an access vector");
00493                         goto bad;
00494                 }
00495                 if (inherits) {
00496                         /*
00497                          * Class-specific permissions and
00498                          * common permissions exist in the same
00499                          * name space.
00500                          */
00501                         perdatum2 = (perm_datum_t *) hashtab_search(cladatum->comdatum->permissions.table, (hashtab_key_t) id);
00502                         if (perdatum2) {
00503                                 yyerror2("permission %s conflicts with an " "inherited permission", id);
00504                                 goto bad;
00505                         }
00506                 }
00507                 ret = hashtab_insert(cladatum->permissions.table, (hashtab_key_t) id, (hashtab_datum_t) perdatum);
00508 
00509                 if (ret == SEPOL_EEXIST) {
00510                         yyerror2("duplicate permission %s", id);
00511                         goto bad;
00512                 }
00513                 if (ret == SEPOL_ENOMEM) {
00514                         yyerror("hash table overflow");
00515                         goto bad;
00516                 }
00517                 if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
00518                         yyerror("out of memory");
00519                         goto bad;
00520                 }
00521         }
00522 
00523         return 0;
00524 
00525       bad:
00526         if (id)
00527                 free(id);
00528         if (perdatum)
00529                 free(perdatum);
00530         return -1;
00531 }
00532 
00533 int define_sens(void)
00534 {
00535         char *id;
00536         mls_level_t *level = 0;
00537         level_datum_t *datum = 0, *aliasdatum = 0;
00538         int ret;
00539         uint32_t value;                /* dummy variable -- its value is never used */
00540 
00541         if (!mlspol) {
00542                 yyerror("sensitivity definition in non-MLS configuration");
00543                 return -1;
00544         }
00545 
00546         if (pass == 2) {
00547                 while ((id = queue_remove(id_queue)))
00548                         free(id);
00549                 return 0;
00550         }
00551 
00552         id = (char *)queue_remove(id_queue);
00553         if (!id) {
00554                 yyerror("no sensitivity name for sensitivity definition?");
00555                 return -1;
00556         }
00557         if (id_has_dot(id)) {
00558                 yyerror("sensitivity identifiers may not contain periods");
00559                 goto bad;
00560         }
00561         level = (mls_level_t *) malloc(sizeof(mls_level_t));
00562         if (!level) {
00563                 yyerror("out of memory");
00564                 goto bad;
00565         }
00566         mls_level_init(level);
00567         level->sens = 0;               /* actual value set in define_dominance */
00568         ebitmap_init(&level->cat);     /* actual value set in define_level */
00569 
00570         datum = (level_datum_t *) malloc(sizeof(level_datum_t));
00571         if (!datum) {
00572                 yyerror("out of memory");
00573                 goto bad;
00574         }
00575         level_datum_init(datum);
00576         datum->isalias = FALSE;
00577         datum->level = level;
00578 
00579         ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
00580         switch (ret) {
00581         case -3:{
00582                 yyerror("Out of memory!");
00583                 goto bad;
00584         }
00585         case -2:{
00586                 yyerror("duplicate declaration of sensitivity level");
00587                 goto bad;
00588         }
00589         case -1:{
00590                 yyerror("could not declare sensitivity level here");
00591                 goto bad;
00592         }
00593         case 0:
00594         case 1:{
00595                 break;
00596         }
00597         default:{
00598                 assert(0);             /* should never get here */
00599         }
00600         }
00601 
00602         while ((id = queue_remove(id_queue))) {
00603                 if (id_has_dot(id)) {
00604                         yyerror("sensitivity aliases may not contain periods");
00605                         goto bad_alias;
00606                 }
00607                 aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
00608                 if (!aliasdatum) {
00609                         yyerror("out of memory");
00610                         goto bad_alias;
00611                 }
00612                 level_datum_init(aliasdatum);
00613                 aliasdatum->isalias = TRUE;
00614                 aliasdatum->level = level;
00615 
00616                 ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
00617                 switch (ret) {
00618                 case -3:{
00619                         yyerror("Out of memory!");
00620                         goto bad_alias;
00621                 }
00622                 case -2:{
00623                         yyerror("duplicate declaration of sensitivity alias");
00624                         goto bad_alias;
00625                 }
00626                 case -1:{
00627                         yyerror("could not declare sensitivity alias here");
00628                         goto bad_alias;
00629                 }
00630                 case 0:
00631                 case 1:{
00632                         break;
00633                 }
00634                 default:{
00635                         assert(0);     /* should never get here */
00636                 }
00637                 }
00638         }
00639 
00640         return 0;
00641 
00642       bad:
00643         if (id)
00644                 free(id);
00645         if (level)
00646                 free(level);
00647         if (datum) {
00648                 level_datum_destroy(datum);
00649                 free(datum);
00650         }
00651         return -1;
00652 
00653       bad_alias:
00654         if (id)
00655                 free(id);
00656         if (aliasdatum) {
00657                 level_datum_destroy(aliasdatum);
00658                 free(aliasdatum);
00659         }
00660         return -1;
00661 }
00662 
00663 int define_dominance(void)
00664 {
00665         level_datum_t *datum;
00666         int order;
00667         char *id;
00668 
00669         if (!mlspol) {
00670                 yyerror("dominance definition in non-MLS configuration");
00671                 return -1;
00672         }
00673 
00674         if (pass == 2) {
00675                 while ((id = queue_remove(id_queue)))
00676                         free(id);
00677                 return 0;
00678         }
00679 
00680         order = 0;
00681         while ((id = (char *)queue_remove(id_queue))) {
00682                 datum = (level_datum_t *) hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
00683                 if (!datum) {
00684                         yyerror2("unknown sensitivity %s used in dominance " "definition", id);
00685                         free(id);
00686                         return -1;
00687                 }
00688                 if (datum->level->sens != 0) {
00689                         yyerror2("sensitivity %s occurs multiply in dominance " "definition", id);
00690                         free(id);
00691                         return -1;
00692                 }
00693                 datum->level->sens = ++order;
00694 
00695                 /* no need to keep sensitivity name */
00696                 free(id);
00697         }
00698 
00699         if (order != policydbp->p_levels.nprim) {
00700                 yyerror("all sensitivities must be specified in dominance definition");
00701                 return -1;
00702         }
00703         return 0;
00704 }
00705 
00706 int define_category(void)
00707 {
00708         char *id;
00709         cat_datum_t *datum = 0, *aliasdatum = 0;
00710         int ret;
00711         uint32_t value;
00712 
00713         if (!mlspol) {
00714                 yyerror("category definition in non-MLS configuration");
00715                 return -1;
00716         }
00717 
00718         if (pass == 2) {
00719                 while ((id = queue_remove(id_queue)))
00720                         free(id);
00721                 return 0;
00722         }
00723 
00724         id = (char *)queue_remove(id_queue);
00725         if (!id) {
00726                 yyerror("no category name for category definition?");
00727                 return -1;
00728         }
00729         if (id_has_dot(id)) {
00730                 yyerror("category identifiers may not contain periods");
00731                 goto bad;
00732         }
00733         datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
00734         if (!datum) {
00735                 yyerror("out of memory");
00736                 goto bad;
00737         }
00738         cat_datum_init(datum);
00739         datum->isalias = FALSE;
00740 
00741         ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
00742         switch (ret) {
00743         case -3:{
00744                 yyerror("Out of memory!");
00745                 goto bad;
00746         }
00747         case -2:{
00748                 yyerror("duplicate declaration of category");
00749                 goto bad;
00750         }
00751         case -1:{
00752                 yyerror("could not declare category here");
00753                 goto bad;
00754         }
00755         case 0:
00756         case 1:{
00757                 break;
00758         }
00759         default:{
00760                 assert(0);             /* should never get here */
00761         }
00762         }
00763         datum->s.value = value;
00764 
00765         while ((id = queue_remove(id_queue))) {
00766                 if (id_has_dot(id)) {
00767                         yyerror("category aliases may not contain periods");
00768                         goto bad_alias;
00769                 }
00770                 aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
00771                 if (!aliasdatum) {
00772                         yyerror("out of memory");
00773                         goto bad_alias;
00774                 }
00775                 cat_datum_init(aliasdatum);
00776                 aliasdatum->isalias = TRUE;
00777                 aliasdatum->s.value = datum->s.value;
00778 
00779                 ret = declare_symbol(SYM_CATS, id, aliasdatum, NULL, &datum->s.value);
00780                 switch (ret) {
00781                 case -3:{
00782                         yyerror("Out of memory!");
00783                         goto bad_alias;
00784                 }
00785                 case -2:{
00786                         yyerror("duplicate declaration of category aliases");
00787                         goto bad_alias;
00788                 }
00789                 case -1:{
00790                         yyerror("could not declare category aliases here");
00791                         goto bad_alias;
00792                 }
00793                 case 0:
00794                 case 1:{
00795                         break;
00796                 }
00797                 default:{
00798                         assert(0);     /* should never get here */
00799                 }
00800                 }
00801         }
00802 
00803         return 0;
00804 
00805       bad:
00806         if (id)
00807                 free(id);
00808         if (datum) {
00809                 cat_datum_destroy(datum);
00810                 free(datum);
00811         }
00812         return -1;
00813 
00814       bad_alias:
00815         if (id)
00816                 free(id);
00817         if (aliasdatum) {
00818                 cat_datum_destroy(aliasdatum);
00819                 free(aliasdatum);
00820         }
00821         return -1;
00822 }
00823 
00824 static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
00825 {
00826         level_datum_t *levdatum = (level_datum_t *) datum;
00827         mls_level_t *level = (mls_level_t *) arg, *newlevel;
00828 
00829         if (levdatum->level == level) {
00830                 levdatum->defined = 1;
00831                 if (!levdatum->isalias)
00832                         return 0;
00833                 newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
00834                 if (!newlevel)
00835                         return -1;
00836                 if (mls_level_cpy(newlevel, level)) {
00837                         free(newlevel);
00838                         return -1;
00839                 }
00840                 levdatum->level = newlevel;
00841         }
00842         return 0;
00843 }
00844 
00845 int define_level(void)
00846 {
00847         char *id;
00848         level_datum_t *levdatum;
00849 
00850         if (!mlspol) {
00851                 yyerror("level definition in non-MLS configuration");
00852                 return -1;
00853         }
00854 
00855         if (pass == 2) {
00856                 while ((id = queue_remove(id_queue)))
00857                         free(id);
00858                 return 0;
00859         }
00860 
00861         id = (char *)queue_remove(id_queue);
00862         if (!id) {
00863                 yyerror("no level name for level definition?");
00864                 return -1;
00865         }
00866         levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
00867         if (!levdatum) {
00868                 yyerror2("unknown sensitivity %s used in level definition", id);
00869                 free(id);
00870                 return -1;
00871         }
00872         if (ebitmap_length(&levdatum->level->cat)) {
00873                 yyerror2("sensitivity %s used in multiple level definitions", id);
00874                 free(id);
00875                 return -1;
00876         }
00877         free(id);
00878 
00879         levdatum->defined = 1;
00880 
00881         while ((id = queue_remove(id_queue))) {
00882                 cat_datum_t *cdatum;
00883                 int range_start, range_end, i;
00884 
00885                 if (id_has_dot(id)) {
00886                         char *id_start = id;
00887                         char *id_end = strchr(id, '.');
00888 
00889                         *(id_end++) = '\0';
00890 
00891                         cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t)
00892                                                                 id_start);
00893                         if (!cdatum) {
00894                                 yyerror2("unknown category %s", id_start);
00895                                 free(id);
00896                                 return -1;
00897                         }
00898                         range_start = cdatum->s.value - 1;
00899                         cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t)
00900                                                                 id_end);
00901                         if (!cdatum) {
00902                                 yyerror2("unknown category %s", id_end);
00903                                 free(id);
00904                                 return -1;
00905                         }
00906                         range_end = cdatum->s.value - 1;
00907 
00908                         if (range_end < range_start) {
00909                                 yyerror2("category range is invalid");
00910                                 free(id);
00911                                 return -1;
00912                         }
00913                 } else {
00914                         cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id);
00915                         range_start = range_end = cdatum->s.value - 1;
00916                 }
00917 
00918                 for (i = range_start; i <= range_end; i++) {
00919                         if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
00920                                 yyerror("out of memory");
00921                                 free(id);
00922                                 return -1;
00923                         }
00924                 }
00925 
00926                 free(id);
00927         }
00928 
00929         if (hashtab_map(policydbp->p_levels.table, clone_level, levdatum->level)) {
00930                 yyerror("out of memory");
00931                 return -1;
00932         }
00933 
00934         return 0;
00935 }
00936 
00937 int define_attrib(void)
00938 {
00939         if (pass == 2) {
00940                 free(queue_remove(id_queue));
00941                 return 0;
00942         }
00943 
00944         if (declare_type(TRUE, TRUE) == NULL) {
00945                 return -1;
00946         }
00947         return 0;
00948 }
00949 
00950 static int add_aliases_to_type(type_datum_t * type)
00951 {
00952         char *id;
00953         type_datum_t *aliasdatum = NULL;
00954         int ret;
00955         while ((id = queue_remove(id_queue))) {
00956                 if (id_has_dot(id)) {
00957                         free(id);
00958                         yyerror("type alias identifiers may not contain periods");
00959                         return -1;
00960                 }
00961                 aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
00962                 if (!aliasdatum) {
00963                         free(id);
00964                         yyerror("Out of memory!");
00965                         return -1;
00966                 }
00967                 memset(aliasdatum, 0, sizeof(type_datum_t));
00968                 aliasdatum->s.value = type->s.value;
00969 
00970                 ret = declare_symbol(SYM_TYPES, id, aliasdatum, NULL, &aliasdatum->s.value);
00971                 switch (ret) {
00972                 case -3:{
00973                         yyerror("Out of memory!");
00974                         goto cleanup;
00975                 }
00976                 case -2:{
00977                         yyerror2("duplicate declaration of alias %s", id);
00978                         goto cleanup;
00979                 }
00980                 case -1:{
00981                         yyerror("could not declare alias here");
00982                         goto cleanup;
00983                 }
00984                 case 0:
00985                 case 1:{
00986                         break;
00987                 }
00988                 default:{
00989                         assert(0);     /* should never get here */
00990                 }
00991                 }
00992         }
00993         return 0;
00994       cleanup:
00995         free(id);
00996         type_datum_destroy(aliasdatum);
00997         free(aliasdatum);
00998         return -1;
00999 }
01000 
01001 int define_typealias(void)
01002 {
01003         char *id;
01004         type_datum_t *t;
01005 
01006         if (pass == 2) {
01007                 while ((id = queue_remove(id_queue)))
01008                         free(id);
01009                 return 0;
01010         }
01011 
01012         id = (char *)queue_remove(id_queue);
01013         if (!id) {
01014                 yyerror("no type name for typealias definition?");
01015                 return -1;
01016         }
01017 
01018         if (!is_id_in_scope(SYM_TYPES, id)) {
01019                 yyerror2("type %s is not within scope", id);
01020                 free(id);
01021                 return -1;
01022         }
01023         t = hashtab_search(policydbp->p_types.table, id);
01024         if (!t || t->flavor == TYPE_ATTRIB) {
01025                 yyerror2("unknown type %s, or it was already declared as an " "attribute", id);
01026                 free(id);
01027                 return -1;
01028         }
01029         free(id);
01030         return add_aliases_to_type(t);
01031 }
01032 
01033 int define_typeattribute(void)
01034 {
01035         char *id;
01036         type_datum_t *t, *attr;
01037 
01038         if (pass == 2) {
01039                 while ((id = queue_remove(id_queue)))
01040                         free(id);
01041                 return 0;
01042         }
01043 
01044         id = (char *)queue_remove(id_queue);
01045         if (!id) {
01046                 yyerror("no type name for typeattribute definition?");
01047                 return -1;
01048         }
01049 
01050         if (!is_id_in_scope(SYM_TYPES, id)) {
01051                 yyerror2("type %s is not within scope", id);
01052                 free(id);
01053                 return -1;
01054         }
01055         t = hashtab_search(policydbp->p_types.table, id);
01056         if (!t || t->flavor == TYPE_ATTRIB) {
01057                 yyerror2("unknown type %s", id);
01058                 free(id);
01059                 return -1;
01060         }
01061         free(id);
01062 
01063         while ((id = queue_remove(id_queue))) {
01064                 if (!is_id_in_scope(SYM_TYPES, id)) {
01065                         yyerror2("attribute %s is not within scope", id);
01066                         free(id);
01067                         return -1;
01068                 }
01069                 attr = hashtab_search(policydbp->p_types.table, id);
01070                 if (!attr) {
01071                         /* treat it as a fatal error */
01072                         yyerror2("attribute %s is not declared", id);
01073                         free(id);
01074                         return -1;
01075                 }
01076 
01077                 if (attr->flavor != TYPE_ATTRIB) {
01078                         yyerror2("%s is a type, not an attribute", id);
01079                         free(id);
01080                         return -1;
01081                 }
01082 
01083                 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
01084                         yyerror("Out of memory!");
01085                         return -1;
01086                 }
01087 
01088                 if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
01089                         yyerror("out of memory");
01090                         return -1;
01091                 }
01092         }
01093 
01094         return 0;
01095 }
01096 
01097 int define_type(int alias)
01098 {
01099         char *id;
01100         type_datum_t *datum, *attr;
01101         int newattr = 0;
01102 
01103         if (pass == 2) {
01104                 while ((id = queue_remove(id_queue)))
01105                         free(id);
01106                 if (alias) {
01107                         while ((id = queue_remove(id_queue)))
01108                                 free(id);
01109                 }
01110                 return 0;
01111         }
01112 
01113         if ((datum = declare_type(TRUE, FALSE)) == NULL) {
01114                 return -1;
01115         }
01116 
01117         if (alias) {
01118                 if (add_aliases_to_type(datum) == -1) {
01119                         return -1;
01120                 }
01121         }
01122 
01123         while ((id = queue_remove(id_queue))) {
01124                 if (!is_id_in_scope(SYM_TYPES, id)) {
01125                         yyerror2("attribute %s is not within scope", id);
01126                         free(id);
01127                         return -1;
01128                 }
01129                 attr = hashtab_search(policydbp->p_types.table, id);
01130                 if (!attr) {
01131                         /* treat it as a fatal error */
01132                         yyerror2("attribute %s is not declared", id);
01133                         return -1;
01134                 } else {
01135                         newattr = 0;
01136                 }
01137 
01138                 if (attr->flavor != TYPE_ATTRIB) {
01139                         yyerror2("%s is a type, not an attribute", id);
01140                         return -1;
01141                 }
01142 
01143                 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
01144                         yyerror("Out of memory!");
01145                         return -1;
01146                 }
01147 
01148                 if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
01149                         yyerror("Out of memory");
01150                         return -1;
01151                 }
01152         }
01153 
01154         return 0;
01155 }
01156 
01157 struct val_to_name
01158 {
01159         unsigned int val;
01160         char *name;
01161 };
01162 
01163 /* Adds a type, given by its textual name, to a typeset.  If *add is
01164    0, then add the type to the negative set; otherwise if *add is 1
01165    then add it to the positive side. */
01166 static int set_types(type_set_t * set, char *id, int *add, char starallowed)
01167 {
01168         type_datum_t *t;
01169 
01170         if (strcmp(id, "*") == 0) {
01171                 if (!starallowed) {
01172                         yyerror("* not allowed in this type of rule");
01173                         return -1;
01174                 }
01175                 /* set TYPE_STAR flag */
01176                 set->flags = TYPE_STAR;
01177                 free(id);
01178                 *add = 1;
01179                 return 0;
01180         }
01181 
01182         if (strcmp(id, "~") == 0) {
01183                 if (!starallowed) {
01184                         yyerror("~ not allowed in this type of rule");
01185                         return -1;
01186                 }
01187                 /* complement the set */
01188                 set->flags = TYPE_COMP;
01189                 free(id);
01190                 *add = 1;
01191                 return 0;
01192         }
01193 
01194         if (strcmp(id, "-") == 0) {
01195                 *add = 0;
01196                 free(id);
01197                 return 0;
01198         }
01199 
01200         if (!is_id_in_scope(SYM_TYPES, id)) {
01201                 yyerror2("type %s is not within scope", id);
01202                 free(id);
01203                 return -1;
01204         }
01205         t = hashtab_search(policydbp->p_types.table, id);
01206         if (!t) {
01207                 yyerror2("unknown type %s", id);
01208                 free(id);
01209                 return -1;
01210         }
01211 
01212         if (*add == 0) {
01213                 if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
01214                         goto oom;
01215         } else {
01216                 if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
01217                         goto oom;
01218         }
01219         free(id);
01220         *add = 1;
01221         return 0;
01222       oom:
01223         yyerror("Out of memory");
01224         free(id);
01225         return -1;
01226 }
01227 
01228 int define_compute_type_helper(int which, avrule_t ** rule)
01229 {
01230         char *id;
01231         type_datum_t *datum;
01232         class_datum_t *cladatum;
01233         ebitmap_t tclasses;
01234         ebitmap_node_t *node;
01235         avrule_t *avrule;
01236         class_perm_node_t *perm;
01237         int i, add = 1;
01238 
01239         avrule = malloc(sizeof(avrule_t));
01240         if (!avrule) {
01241                 yyerror("out of memory");
01242                 return -1;
01243         }
01244         avrule_init(avrule);
01245         avrule->specified = which;
01246         avrule->line = policydb_lineno;
01247 
01248         while ((id = queue_remove(id_queue))) {
01249                 if (set_types(&avrule->stypes, id, &add, 0))
01250                         return -1;
01251         }
01252         add = 1;
01253         while ((id = queue_remove(id_queue))) {
01254                 if (set_types(&avrule->ttypes, id, &add, 0))
01255                         return -1;
01256         }
01257 
01258         ebitmap_init(&tclasses);
01259         while ((id = queue_remove(id_queue))) {
01260                 if (!is_id_in_scope(SYM_CLASSES, id)) {
01261                         yyerror2("class %s is not within scope", id);
01262                         free(id);
01263                         goto bad;
01264                 }
01265                 cladatum = hashtab_search(policydbp->p_classes.table, id);
01266                 if (!cladatum) {
01267                         yyerror2("unknown class %s", id);
01268                         goto bad;
01269                 }
01270                 if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
01271                         yyerror("Out of memory");
01272                         goto bad;
01273                 }
01274                 free(id);
01275         }
01276 
01277         id = (char *)queue_remove(id_queue);
01278         if (!id) {
01279                 yyerror("no newtype?");
01280                 goto bad;
01281         }
01282         if (!is_id_in_scope(SYM_TYPES, id)) {
01283                 yyerror2("type %s is not within scope", id);
01284                 free(id);
01285                 goto bad;
01286         }
01287         datum = (type_datum_t *) hashtab_search(policydbp->p_types.table, (hashtab_key_t) id);
01288         if (!datum || datum->flavor == TYPE_ATTRIB) {
01289                 yyerror2("unknown type %s", id);
01290                 goto bad;
01291         }
01292         free(id);
01293 
01294         ebitmap_for_each_bit(&tclasses, node, i) {
01295                 if (ebitmap_node_get_bit(node, i)) {
01296                         perm = malloc(sizeof(class_perm_node_t));
01297                         if (!perm) {
01298                                 yyerror("out of memory");
01299                                 return -1;
01300                         }
01301                         class_perm_node_init(perm);
01302                         perm->class = i + 1;
01303                         perm->data = datum->s.value;
01304                         perm->next = avrule->perms;
01305                         avrule->perms = perm;
01306                 }
01307         }
01308         ebitmap_destroy(&tclasses);
01309 
01310         *rule = avrule;
01311         return 0;
01312 
01313       bad:
01314         avrule_destroy(avrule);
01315         free(avrule);
01316         return -1;
01317 }
01318 
01319 int define_compute_type(int which)
01320 {
01321         char *id;
01322         avrule_t *avrule;
01323         int retval;
01324 
01325         if (pass == 1 || (num_rules && !load_rules)) {
01326                 while ((id = queue_remove(id_queue)))
01327                         free(id);
01328                 while ((id = queue_remove(id_queue)))
01329                         free(id);
01330                 while ((id = queue_remove(id_queue)))
01331                         free(id);
01332                 id = queue_remove(id_queue);
01333                 free(id);
01334                 return 0;
01335         }
01336 
01337         num_rules++;
01338 
01339         if (define_compute_type_helper(which, &avrule))
01340                 return -1;
01341 
01342         retval = insert_check_type_rule(avrule, &policydbp->te_avtab, NULL, NULL);
01343         switch (retval) {
01344         case 1:{
01345                 /* append this avrule to the end of the current rules list */
01346                 append_avrule(avrule);
01347                 return 0;
01348         }
01349         case 2:                /* FALLTHROUGH */
01350         case 0:{
01351                 /* rule conflicted, so don't actually add this rule */
01352                 avrule_destroy(avrule);
01353                 free(avrule);
01354                 return 0;
01355         }
01356         case -1:{
01357                 avrule_destroy(avrule);
01358                 free(avrule);
01359                 return -1;
01360         }
01361         default:{
01362                 assert(0);             /* should never get here */
01363         }
01364         }
01365 }
01366 
01367 avrule_t *define_cond_compute_type(int which)
01368 {
01369         char *id;
01370         avrule_t *avrule;
01371 
01372         if (pass == 1 || (num_rules && !load_rules)) {
01373                 while ((id = queue_remove(id_queue)))
01374                         free(id);
01375                 while ((id = queue_remove(id_queue)))
01376                         free(id);
01377                 while ((id = queue_remove(id_queue)))
01378                         free(id);
01379                 id = queue_remove(id_queue);
01380                 free(id);
01381                 return (avrule_t *) 1;
01382         }
01383 
01384         num_rules++;
01385 
01386         if (define_compute_type_helper(which, &avrule))
01387                 return COND_ERR;
01388 
01389         return avrule;
01390 }
01391 
01392 int define_bool(void)
01393 {
01394         char *id, *bool_value;
01395         cond_bool_datum_t *datum;
01396         int ret;
01397         uint32_t value;
01398 
01399         if (pass == 2) {
01400                 while ((id = queue_remove(id_queue)))
01401                         free(id);
01402                 return 0;
01403         }
01404 
01405         id = (char *)queue_remove(id_queue);
01406         if (!id) {
01407                 yyerror("no identifier for bool definition?");
01408                 return -1;
01409         }
01410         if (id_has_dot(id)) {
01411                 free(id);
01412                 yyerror("boolean identifiers may not contain periods");
01413                 return -1;
01414         }
01415         datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
01416         if (!datum) {
01417                 yyerror("out of memory");
01418                 free(id);
01419                 return -1;
01420         }
01421         memset(datum, 0, sizeof(cond_bool_datum_t));
01422         ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
01423         switch (ret) {
01424         case -3:{
01425                 yyerror("Out of memory!");
01426                 goto cleanup;
01427         }
01428         case -2:{
01429                 yyerror2("duplicate declaration of boolean %s", id);
01430                 goto cleanup;
01431         }
01432         case -1:{
01433                 yyerror("could not declare boolean here");
01434                 goto cleanup;
01435         }
01436         case 0:
01437         case 1:{
01438                 break;
01439         }
01440         default:{
01441                 assert(0);             /* should never get here */
01442         }
01443         }
01444         datum->s.value = value;
01445 
01446         bool_value = (char *)queue_remove(id_queue);
01447         if (!bool_value) {
01448                 yyerror("no default value for bool definition?");
01449                 free(id);
01450                 return -1;
01451         }
01452 
01453         datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
01454         free(bool_value);
01455         return 0;
01456       cleanup:
01457         cond_destroy_bool(id, datum, NULL);
01458         return -1;
01459 }
01460 
01461 avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
01462 {
01463         if (pass == 1 || (num_rules && !load_rules)) {
01464                 /* return something so we get through pass 1 */
01465                 return (avrule_t *) 1;
01466         }
01467 
01468         if (sl == NULL) {
01469                 /* This is a require block, return previous list */
01470                 return avlist;
01471         }
01472 
01473         /* prepend the new avlist to the pre-existing one */
01474         sl->next = avlist;
01475         return sl;
01476 }
01477 
01478 int define_te_avtab_helper(int which, avrule_t ** rule)
01479 {
01480         char *id;
01481         class_datum_t *cladatum;
01482         perm_datum_t *perdatum = NULL;
01483         class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
01484         ebitmap_t tclasses;
01485         ebitmap_node_t *node;
01486         avrule_t *avrule;
01487         unsigned int i;
01488         int add = 1, ret = 0;
01489         int suppress = 0;
01490 
01491         avrule = (avrule_t *) malloc(sizeof(avrule_t));
01492         if (!avrule) {
01493                 yyerror("memory error");
01494                 ret = -1;
01495                 goto out;
01496         }
01497         avrule_init(avrule);
01498         avrule->specified = which;
01499         avrule->line = policydb_lineno;
01500 
01501         while ((id = queue_remove(id_queue))) {
01502                 if (set_types(&avrule->stypes, id, &add, which == AVRULE_NEVERALLOW ? 1 : 0)) {
01503                         ret = -1;
01504                         goto out;
01505                 }
01506         }
01507         add = 1;
01508         while ((id = queue_remove(id_queue))) {
01509                 if (strcmp(id, "self") == 0) {
01510                         free(id);
01511                         avrule->flags |= RULE_SELF;
01512                         continue;
01513                 }
01514                 if (set_types(&avrule->ttypes, id, &add, which == AVRULE_NEVERALLOW ? 1 : 0)) {
01515                         ret = -1;
01516                         goto out;
01517                 }
01518         }
01519 
01520         ebitmap_init(&tclasses);
01521         while ((id = queue_remove(id_queue))) {
01522                 if (!is_id_in_scope(SYM_CLASSES, id)) {
01523                         yyerror2("class %s is not within scope", id);
01524                         ret = -1;
01525                         goto out;
01526                 }
01527                 cladatum = hashtab_search(policydbp->p_classes.table, id);
01528                 if (!cladatum) {
01529                         yyerror2("unknown class %s used in rule", id);
01530                         ret = -1;
01531                         goto out;
01532                 }
01533                 if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
01534                         yyerror("Out of memory");
01535                         ret = -1;
01536                         goto out;
01537                 }
01538                 free(id);
01539         }
01540 
01541         perms = NULL;
01542         ebitmap_for_each_bit(&tclasses, node, i) {
01543                 if (!ebitmap_node_get_bit(node, i))
01544                         continue;
01545                 cur_perms = (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
01546                 if (!cur_perms) {
01547                         yyerror("out of memory");
01548                         ret = -1;
01549                         goto out;
01550                 }
01551                 class_perm_node_init(cur_perms);
01552                 cur_perms->class = i + 1;
01553                 if (!perms)
01554                         perms = cur_perms;
01555                 if (tail)
01556                         tail->next = cur_perms;
01557                 tail = cur_perms;
01558         }
01559 
01560         while ((id = queue_remove(id_queue))) {
01561                 cur_perms = perms;
01562                 ebitmap_for_each_bit(&tclasses, node, i) {
01563                         if (!ebitmap_node_get_bit(node, i))
01564                                 continue;
01565                         cladatum = policydbp->class_val_to_struct[i];
01566 
01567                         if (strcmp(id, "*") == 0) {
01568                                 /* set all permissions in the class */
01569                                 cur_perms->data = ~0U;
01570                                 goto next;
01571                         }
01572 
01573                         if (strcmp(id, "~") == 0) {
01574                                 /* complement the set */
01575                                 if (which == AVRULE_DONTAUDIT)
01576                                         yywarn("dontaudit rule with a ~?");
01577                                 cur_perms->data = ~cur_perms->data;
01578                                 goto next;
01579                         }
01580 
01581                         perdatum = hashtab_search(cladatum->permissions.table, id);
01582                         if (!perdatum) {
01583                                 if (cladatum->comdatum) {
01584                                         perdatum = hashtab_search(cladatum->comdatum->permissions.table, id);
01585                                 }
01586                         }
01587                         if (!perdatum) {
01588                                 if (!suppress)
01589                                         yyerror2("permission %s is not defined"
01590                                                  " for class %s", id, policydbp->p_class_val_to_name[i]);
01591                                 continue;
01592                         } else if (!is_perm_in_scope(id, policydbp->p_class_val_to_name[i])) {
01593                                 if (!suppress) {
01594                                         yyerror2("permission %s of class %s is"
01595                                                  " not within scope", id, policydbp->p_class_val_to_name[i]);
01596                                 }
01597                                 continue;
01598                         } else {
01599                                 cur_perms->data |= 1U << (perdatum->s.value - 1);
01600                         }
01601                       next:
01602                         cur_perms = cur_perms->next;
01603                 }
01604 
01605                 free(id);
01606         }
01607 
01608         ebitmap_destroy(&tclasses);
01609 
01610         avrule->perms = perms;
01611         *rule = avrule;
01612 
01613       out:
01614         return ret;
01615 
01616 }
01617 
01618 avrule_t *define_cond_te_avtab(int which)
01619 {
01620         char *id;
01621         avrule_t *avrule;
01622         int i;
01623 
01624         if (pass == 1 || (num_rules && !load_rules)) {
01625                 for (i = 0; i < 4; i++) {
01626                         while ((id = queue_remove(id_queue)))
01627                                 free(id);
01628                 }
01629                 return (avrule_t *) 1; /* any non-NULL value */
01630         }
01631 
01632         num_rules++;
01633 
01634         if (define_te_avtab_helper(which, &avrule))
01635                 return COND_ERR;
01636 
01637         return avrule;
01638 }
01639 
01640 int define_te_avtab(int which)
01641 {
01642         char *id;
01643         avrule_t *avrule;
01644         int i;
01645 
01646         if (pass == 1 || (num_rules && !load_rules)) {
01647                 for (i = 0; i < 4; i++) {
01648                         while ((id = queue_remove(id_queue)))
01649                                 free(id);
01650                 }
01651                 return 0;
01652         }
01653 
01654         num_rules++;
01655 
01656         if (define_te_avtab_helper(which, &avrule))
01657                 return -1;
01658 
01659         /* append this avrule to the end of the current rules list */
01660         append_avrule(avrule);
01661         return 0;
01662 }
01663 
01664 int define_role_types(void)
01665 {
01666         role_datum_t *role;
01667         char *id;
01668         int add = 1;
01669 
01670         if (pass == 1) {
01671                 while ((id = queue_remove(id_queue)))
01672                         free(id);
01673                 return 0;
01674         }
01675 
01676         if ((role = declare_role()) == NULL) {
01677                 return -1;
01678         }
01679         while ((id = queue_remove(id_queue))) {
01680                 if (set_types(&role->types, id, &add, 0))
01681                         return -1;
01682         }
01683 
01684         return 0;
01685 }
01686 
01687 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
01688 {
01689         role_datum_t *new;
01690 
01691         if (pass == 1) {
01692                 return (role_datum_t *) 1;      /* any non-NULL value */
01693         }
01694 
01695         new = malloc(sizeof(role_datum_t));
01696         if (!new) {
01697                 yyerror("out of memory");
01698                 return NULL;
01699         }
01700         memset(new, 0, sizeof(role_datum_t));
01701         new->s.value = 0;              /* temporary role */
01702         if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
01703                 yyerror("out of memory");
01704                 return NULL;
01705         }
01706         if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
01707                 yyerror("out of memory");
01708                 return NULL;
01709         }
01710         if (!r1->s.value) {
01711                 /* free intermediate result */
01712                 type_set_destroy(&r1->types);
01713                 ebitmap_destroy(&r1->dominates);
01714                 free(r1);
01715         }
01716         if (!r2->s.value) {
01717                 /* free intermediate result */
01718                 yyerror("right hand role is temporary?");
01719                 type_set_destroy(&r2->types);
01720                 ebitmap_destroy(&r2->dominates);
01721                 free(r2);
01722         }
01723         return new;
01724 }
01725 
01726 /* This function eliminates the ordering dependency of role dominance rule */
01727 static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum, void *arg)
01728 {
01729         role_datum_t *rdp = (role_datum_t *) arg;
01730         role_datum_t *rdatum = (role_datum_t *) datum;
01731         ebitmap_node_t *node;
01732         int i;
01733 
01734         /* Don't bother to process against self role */
01735         if (rdatum->s.value == rdp->s.value)
01736                 return 0;
01737 
01738         /* If a dominating role found */
01739         if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
01740                 ebitmap_t types;
01741                 ebitmap_init(&types);
01742                 if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
01743                         ebitmap_destroy(&types);
01744                         return -1;
01745                 }
01746                 /* raise types and dominates from dominated role */
01747                 ebitmap_for_each_bit(&rdp->dominates, node, i) {
01748                         if (ebitmap_node_get_bit(node, i))
01749                                 if (ebitmap_set_bit(&rdatum->dominates, i, TRUE))
01750                                         goto oom;
01751                 }
01752                 ebitmap_for_each_bit(&types, node, i) {
01753                         if (ebitmap_node_get_bit(node, i))
01754                                 if (ebitmap_set_bit(&rdatum->types.types, i, TRUE))
01755                                         goto oom;
01756                 }
01757                 ebitmap_destroy(&types);
01758         }
01759 
01760         /* go through all the roles */
01761         return 0;
01762       oom:
01763         yyerror("Out of memory");
01764         return -1;
01765 }
01766 
01767 role_datum_t *define_role_dom(role_datum_t * r)
01768 {
01769         role_datum_t *role;
01770         char *role_id;
01771         ebitmap_node_t *node;
01772         unsigned int i;
01773         int ret;
01774 
01775         if (pass == 1) {
01776                 role_id = queue_remove(id_queue);
01777                 free(role_id);
01778                 return (role_datum_t *) 1;      /* any non-NULL value */
01779         }
01780 
01781         yywarn("Role dominance has been deprecated");
01782 
01783         role_id = queue_remove(id_queue);
01784         if (!is_id_in_scope(SYM_ROLES, role_id)) {
01785                 yyerror2("role %s is not within scope", role_id);
01786                 free(role_id);
01787                 return NULL;
01788         }
01789         role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, role_id);
01790         if (!role) {
01791                 role = (role_datum_t *) malloc(sizeof(role_datum_t));
01792                 if (!role) {
01793                         yyerror("out of memory");
01794                         free(role_id);
01795                         return NULL;
01796                 }
01797                 memset(role, 0, sizeof(role_datum_t));
01798                 ret = declare_symbol(SYM_ROLES, (hashtab_key_t) role_id, (hashtab_datum_t) role, &role->s.value, &role->s.value);
01799                 switch (ret) {
01800                 case -3:{
01801                         yyerror("Out of memory!");
01802                         goto cleanup;
01803                 }
01804                 case -2:{
01805                         yyerror2("duplicate declaration of role %s", role_id);
01806                         goto cleanup;
01807                 }
01808                 case -1:{
01809                         yyerror("could not declare role here");
01810                         goto cleanup;
01811                 }
01812                 case 0:
01813                 case 1:{
01814                         break;
01815                 }
01816                 default:{
01817                         assert(0);     /* should never get here */
01818                 }
01819                 }
01820                 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
01821                         yyerror("Out of memory!");
01822                         goto cleanup;
01823                 }
01824         }
01825         if (r) {
01826                 ebitmap_t types;
01827                 ebitmap_init(&types);
01828                 ebitmap_for_each_bit(&r->dominates, node, i) {
01829                         if (ebitmap_node_get_bit(node, i))
01830                                 if (ebitmap_set_bit(&role->dominates, i, TRUE))
01831                                         goto oom;
01832                 }
01833                 if (type_set_expand(&r->types, &types, policydbp, 1)) {
01834                         ebitmap_destroy(&types);
01835                         return NULL;
01836                 }
01837                 ebitmap_for_each_bit(&types, node, i) {
01838                         if (ebitmap_node_get_bit(node, i))
01839                                 if (ebitmap_set_bit(&role->types.types, i, TRUE))
01840                                         goto oom;
01841                 }
01842                 ebitmap_destroy(&types);
01843                 if (!r->s.value) {
01844                         /* free intermediate result */
01845                         type_set_destroy(&r->types);
01846                         ebitmap_destroy(&r->dominates);
01847                         free(r);
01848                 }
01849                 /*
01850                  * Now go through all the roles and escalate this role's
01851                  * dominates and types if a role dominates this role.
01852                  */
01853                 hashtab_map(policydbp->p_roles.table, dominate_role_recheck, role);
01854         }
01855         return role;
01856       cleanup:
01857         free(role_id);
01858         role_datum_destroy(role);
01859         free(role);
01860         return NULL;
01861       oom:
01862         yyerror("Out of memory");
01863         goto cleanup;
01864 }
01865 
01866 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p)
01867 {
01868         struct val_to_name *v = p;
01869         role_datum_t *roldatum;
01870 
01871         roldatum = (role_datum_t *) datum;
01872 
01873         if (v->val == roldatum->s.value) {
01874                 v->name = key;
01875                 return 1;
01876         }
01877 
01878         return 0;
01879 }
01880 
01881 static char *role_val_to_name(unsigned int val)
01882 {
01883         struct val_to_name v;
01884         int rc;
01885 
01886         v.val = val;
01887         rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
01888         if (rc)
01889                 return v.name;
01890         return NULL;
01891 }
01892 
01893 static int set_roles(role_set_t * set, char *id)
01894 {
01895         role_datum_t *r;
01896 
01897         if (strcmp(id, "*") == 0) {
01898                 free(id);
01899                 yyerror("* is not allowed for role sets");
01900                 return -1;
01901         }
01902 
01903         if (strcmp(id, "~") == 0) {
01904                 free(id);
01905                 yyerror("~ is not allowed for role sets");
01906                 return -1;
01907         }
01908         if (!is_id_in_scope(SYM_ROLES, id)) {
01909                 yyerror2("role %s is not within scope", id);
01910                 free(id);
01911                 return -1;
01912         }
01913         r = hashtab_search(policydbp->p_roles.table, id);
01914         if (!r) {
01915                 yyerror2("unknown role %s", id);
01916                 free(id);
01917                 return -1;
01918         }
01919 
01920         if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
01921                 yyerror("out of memory");
01922                 free(id);
01923                 return -1;
01924         }
01925         free(id);
01926         return 0;
01927 }
01928 
01929 int define_role_trans(void)
01930 {
01931         char *id;
01932         role_datum_t *role;
01933         role_set_t roles;
01934         type_set_t types;
01935         ebitmap_t e_types, e_roles;
01936         ebitmap_node_t *tnode, *rnode;
01937         struct role_trans *tr = NULL;
01938         struct role_trans_rule *rule = NULL;
01939         unsigned int i, j;
01940         int add = 1;
01941 
01942         if (pass == 1) {
01943                 while ((id = queue_remove(id_queue)))
01944                         free(id);
01945                 while ((id = queue_remove(id_queue)))
01946                         free(id);
01947                 id = queue_remove(id_queue);
01948                 free(id);
01949                 return 0;
01950         }
01951 
01952         role_set_init(&roles);
01953         ebitmap_init(&e_roles);
01954         type_set_init(&types);
01955         ebitmap_init(&e_types);
01956 
01957         while ((id = queue_remove(id_queue))) {
01958                 if (set_roles(&roles, id))
01959                         return -1;
01960         }
01961         add = 1;
01962         while ((id = queue_remove(id_queue))) {
01963                 if (set_types(&types, id, &add, 0))
01964                         return -1;
01965         }
01966 
01967         id = (char *)queue_remove(id_queue);
01968         if (!id) {
01969                 yyerror("no new role in transition definition?");
01970                 goto bad;
01971         }
01972         if (!is_id_in_scope(SYM_ROLES, id)) {
01973                 yyerror2("role %s is not within scope", id);
01974                 free(id);
01975                 goto bad;
01976         }
01977         role = hashtab_search(policydbp->p_roles.table, id);
01978         if (!role) {
01979                 yyerror2("unknown role %s used in transition definition", id);
01980                 goto bad;
01981         }
01982         free(id);
01983 
01984         /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
01985         if (role_set_expand(&roles, &e_roles, policydbp))
01986                 goto bad;
01987 
01988         if (type_set_expand(&types, &e_types, policydbp, 1))
01989                 goto bad;
01990 
01991         ebitmap_for_each_bit(&e_roles, rnode, i) {
01992                 if (!ebitmap_node_get_bit(rnode, i))
01993                         continue;
01994                 ebitmap_for_each_bit(&e_types, tnode, j) {
01995                         if (!ebitmap_node_get_bit(tnode, j))
01996                                 continue;
01997 
01998                         for (tr = policydbp->role_tr; tr; tr = tr->next) {
01999                                 if (tr->role == (i + 1) && tr->type == (j + 1)) {
02000                                         yyerror2("duplicate role transition for (%s,%s)",
02001                                                  role_val_to_name(i + 1), policydbp->p_type_val_to_name[j]);
02002                                         goto bad;
02003                                 }
02004                         }
02005 
02006                         tr = malloc(sizeof(struct role_trans));
02007                         if (!tr) {
02008                                 yyerror("out of memory");
02009                                 return -1;
02010                         }
02011                         memset(tr, 0, sizeof(struct role_trans));
02012                         tr->role = i + 1;
02013                         tr->type = j + 1;
02014                         tr->new_role = role->s.value;
02015                         tr->next = policydbp->role_tr;
02016                         policydbp->role_tr = tr;
02017                 }
02018         }
02019         /* Now add the real rule */
02020         rule = malloc(sizeof(struct role_trans_rule));
02021         if (!rule) {
02022                 yyerror("out of memory");
02023                 return -1;
02024         }
02025         memset(rule, 0, sizeof(struct role_trans_rule));
02026         rule->roles = roles;
02027         rule->types = types;
02028         rule->new_role = role->s.value;
02029 
02030         append_role_trans(rule);
02031 
02032         ebitmap_destroy(&e_roles);
02033         ebitmap_destroy(&e_types);
02034 
02035         return 0;
02036 
02037       bad:
02038         return -1;
02039 }
02040 
02041 int define_role_allow(void)
02042 {
02043         char *id;
02044         struct role_allow_rule *ra = 0;
02045 
02046         if (pass == 1) {
02047                 while ((id = queue_remove(id_queue)))
02048                         free(id);
02049                 while ((id = queue_remove(id_queue)))
02050                         free(id);
02051                 return 0;
02052         }
02053 
02054         ra = malloc(sizeof(role_allow_rule_t));
02055         if (!ra) {
02056                 yyerror("out of memory");
02057                 return -1;
02058         }
02059         role_allow_rule_init(ra);
02060 
02061         while ((id = queue_remove(id_queue))) {
02062                 if (set_roles(&ra->roles, id))
02063                         return -1;
02064         }
02065 
02066         while ((id = queue_remove(id_queue))) {
02067                 if (set_roles(&ra->new_roles, id))
02068                         return -1;
02069         }
02070 
02071         append_role_allow(ra);
02072         return 0;
02073 }
02074 
02075 static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
02076 {
02077         constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
02078         for (e = expr; e; e = e->next) {
02079                 newe = malloc(sizeof(*newe));
02080                 if (!newe)
02081                         goto oom;
02082                 if (constraint_expr_init(newe) == -1) {
02083                         free(newe);
02084                         goto oom;
02085                 }
02086                 if (l)
02087                         l->next = newe;
02088                 else
02089                         h = newe;
02090                 l = newe;
02091                 newe->expr_type = e->expr_type;
02092                 newe->attr = e->attr;
02093                 newe->op = e->op;
02094                 if (newe->expr_type == CEXPR_NAMES) {
02095                         if (newe->attr & CEXPR_TYPE) {
02096                                 if (type_set_cpy(newe->type_names, e->type_names))
02097                                         goto oom;
02098                         } else {
02099                                 if (ebitmap_cpy(&newe->names, &e->names))
02100                                         goto oom;
02101                         }
02102                 }
02103         }
02104 
02105         return h;
02106       oom:
02107         e = h;
02108         while (e) {
02109                 l = e;
02110                 e = e->next;
02111                 constraint_expr_destroy(l);
02112         }
02113         return NULL;
02114 }
02115 
02116 int define_constraint(constraint_expr_t * expr)
02117 {
02118         struct constraint_node *node;
02119         char *id;
02120         class_datum_t *cladatum;
02121         perm_datum_t *perdatum;
02122         ebitmap_t classmap;
02123         ebitmap_node_t *enode;
02124         constraint_expr_t *e;
02125         unsigned int i;
02126         int depth;
02127         unsigned char useexpr = 1;
02128 
02129         if (pass == 1) {
02130                 while ((id = queue_remove(id_queue)))
02131                         free(id);
02132                 while ((id = queue_remove(id_queue)))
02133                         free(id);
02134                 return 0;
02135         }
02136 
02137         depth = -1;
02138         for (e = expr; e; e = e->next) {
02139                 switch (e->expr_type) {
02140                 case CEXPR_NOT:
02141                         if (depth < 0) {
02142                                 yyerror("illegal constraint expression");
02143                                 return -1;
02144                         }
02145                         break;
02146                 case CEXPR_AND:
02147                 case CEXPR_OR:
02148                         if (depth < 1) {
02149                                 yyerror("illegal constraint expression");
02150                                 return -1;
02151                         }
02152                         depth--;
02153                         break;
02154                 case CEXPR_ATTR:
02155                 case CEXPR_NAMES:
02156                         if (e->attr & CEXPR_XTARGET) {
02157                                 yyerror("illegal constraint expression");
02158                                 return -1;      /* only for validatetrans rules */
02159                         }
02160                         if (depth == (CEXPR_MAXDEPTH - 1)) {
02161                                 yyerror("constraint expression is too deep");
02162                                 return -1;
02163                         }
02164                         depth++;
02165                         break;
02166                 default:
02167                         yyerror("illegal constraint expression");
02168                         return -1;
02169                 }
02170         }
02171         if (depth != 0) {
02172                 yyerror("illegal constraint expression");
02173                 return -1;
02174         }
02175 
02176         ebitmap_init(&classmap);
02177         while ((id = queue_remove(id_queue))) {
02178                 if (!is_id_in_scope(SYM_CLASSES, id)) {
02179                         yyerror2("class %s is not within scope", id);
02180                         free(id);
02181                         return -1;
02182                 }
02183                 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, (hashtab_key_t) id);
02184                 if (!cladatum) {
02185                         yyerror2("class %s is not defined", id);
02186                         ebitmap_destroy(&classmap);
02187                         free(id);
02188                         return -1;
02189                 }
02190                 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
02191                         yyerror("out of memory");
02192                         ebitmap_destroy(&classmap);
02193                         free(id);
02194                         return -1;
02195                 }
02196                 node = malloc(sizeof(struct constraint_node));
02197                 if (!node) {
02198                         yyerror("out of memory");
02199                         return -1;
02200                 }
02201                 memset(node, 0, sizeof(constraint_node_t));
02202                 if (useexpr) {
02203                         node->expr = expr;
02204                         useexpr = 0;
02205                 } else {
02206                         node->expr = constraint_expr_clone(expr);
02207                 }
02208                 if (!node->expr) {
02209                         yyerror("out of memory");
02210                         return -1;
02211                 }
02212                 node->permissions = 0;
02213 
02214                 node->next = cladatum->constraints;
02215                 cladatum->constraints = node;
02216 
02217                 free(id);
02218         }
02219 
02220         while ((id = queue_remove(id_queue))) {
02221                 ebitmap_for_each_bit(&classmap, enode, i) {
02222                         if (ebitmap_node_get_bit(enode, i)) {
02223                                 cladatum = policydbp->class_val_to_struct[i];
02224                                 node = cladatum->constraints;
02225 
02226                                 perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table, (hashtab_key_t)
02227                                                                            id);
02228                                 if (!perdatum) {
02229                                         if (cladatum->comdatum) {
02230                                                 perdatum = (perm_datum_t *)
02231                                                         hashtab_search(cladatum->comdatum->permissions.table, (hashtab_key_t)
02232                                                                        id);
02233                                         }
02234                                         if (!perdatum) {
02235                                                 yyerror2("permission %s is not" " defined", id);
02236                                                 free(id);
02237                                                 ebitmap_destroy(&classmap);
02238                                                 return -1;
02239                                         }
02240                                 }
02241                                 node->permissions |= (1 << (perdatum->s.value - 1));
02242                         }
02243                 }
02244                 free(id);
02245         }
02246 
02247         ebitmap_destroy(&classmap);
02248 
02249         return 0;
02250 }
02251 
02252 int define_validatetrans(constraint_expr_t * expr)
02253 {
02254         struct constraint_node *node;
02255         char *id;
02256         class_datum_t *cladatum;
02257         ebitmap_t classmap;
02258         constraint_expr_t *e;
02259         int depth;
02260         unsigned char useexpr = 1;
02261 
02262         if (pass == 1) {
02263                 while ((id = queue_remove(id_queue)))
02264                         free(id);
02265                 return 0;
02266         }
02267 
02268         depth = -1;
02269         for (e = expr; e; e = e->next) {
02270                 switch (e->expr_type) {
02271                 case CEXPR_NOT:
02272                         if (depth < 0) {
02273                                 yyerror("illegal validatetrans expression");
02274                                 return -1;
02275                         }
02276                         break;
02277                 case CEXPR_AND:
02278                 case CEXPR_OR:
02279                         if (depth < 1) {
02280                                 yyerror("illegal validatetrans expression");
02281                                 return -1;
02282                         }
02283                         depth--;
02284                         break;
02285                 case CEXPR_ATTR:
02286                 case CEXPR_NAMES:
02287                         if (depth == (CEXPR_MAXDEPTH - 1)) {
02288                                 yyerror("validatetrans expression is too deep");
02289                                 return -1;
02290                         }
02291                         depth++;
02292                         break;
02293                 default:
02294                         yyerror("illegal validatetrans expression");
02295                         return -1;
02296                 }
02297         }
02298         if (depth != 0) {
02299                 yyerror("illegal validatetrans expression");
02300                 return -1;
02301         }
02302 
02303         ebitmap_init(&classmap);
02304         while ((id = queue_remove(id_queue))) {
02305                 if (!is_id_in_scope(SYM_CLASSES, id)) {
02306                         yyerror2("class %s is not within scope", id);
02307                         free(id);
02308                         return -1;
02309                 }
02310                 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, (hashtab_key_t) id);
02311                 if (!cladatum) {
02312                         yyerror2("class %s is not defined", id);
02313                         ebitmap_destroy(&classmap);
02314                         free(id);
02315                         return -1;
02316                 }
02317                 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
02318                         yyerror("out of memory");
02319                         ebitmap_destroy(&classmap);
02320                         free(id);
02321                         return -1;
02322                 }
02323 
02324                 node = malloc(sizeof(struct constraint_node));
02325                 if (!node) {
02326                         yyerror("out of memory");
02327                         return -1;
02328                 }
02329                 memset(node, 0, sizeof(constraint_node_t));
02330                 if (useexpr) {
02331                         node->expr = expr;
02332                         useexpr = 0;
02333                 } else {
02334                         node->expr = constraint_expr_clone(expr);
02335                 }
02336                 node->permissions = 0;
02337 
02338                 node->next = cladatum->validatetrans;
02339                 cladatum->validatetrans = node;
02340 
02341                 free(id);
02342         }
02343 
02344         ebitmap_destroy(&classmap);
02345 
02346         return 0;
02347 }
02348 
02349 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
02350 {
02351         struct constraint_expr *expr, *e1 = NULL, *e2;
02352         user_datum_t *user;
02353         role_datum_t *role;
02354         ebitmap_t negset;
02355         char *id;
02356         uint32_t val;
02357         int add = 1;
02358 
02359         if (pass == 1) {
02360                 if (expr_type == CEXPR_NAMES) {
02361                         while ((id = queue_remove(id_queue)))
02362                                 free(id);
02363                 }
02364                 return 1;              /* any non-NULL value */
02365         }
02366 
02367         if ((expr = malloc(sizeof(*expr))) == NULL || constraint_expr_init(expr) == -1) {
02368                 yyerror("out of memory");
02369                 free(expr);
02370                 return 0;
02371         }
02372         expr->expr_type = expr_type;
02373 
02374         switch (expr_type) {
02375         case CEXPR_NOT:
02376                 e1 = NULL;
02377                 e2 = (struct constraint_expr *)arg1;
02378                 while (e2) {
02379                         e1 = e2;
02380                         e2 = e2->next;
02381                 }
02382                 if (!e1 || e1->next) {
02383                         yyerror("illegal constraint expression");
02384                         constraint_expr_destroy(expr);
02385                         return 0;
02386                 }
02387                 e1->next = expr;
02388                 return arg1;
02389         case CEXPR_AND:
02390         case CEXPR_OR:
02391                 e1 = NULL;
02392                 e2 = (struct constraint_expr *)arg1;
02393                 while (e2) {
02394                         e1 = e2;
02395                         e2 = e2->next;
02396                 }
02397                 if (!e1 || e1->next) {
02398                         yyerror("illegal constraint expression");
02399                         constraint_expr_destroy(expr);
02400                         return 0;
02401                 }
02402                 e1->next = (struct constraint_expr *)arg2;
02403 
02404                 e1 = NULL;
02405                 e2 = (struct constraint_expr *)arg2;
02406                 while (e2) {
02407                         e1 = e2;
02408                         e2 = e2->next;
02409                 }
02410                 if (!e1 || e1->next) {
02411                         yyerror("illegal constraint expression");
02412                         constraint_expr_destroy(expr);
02413                         return 0;
02414                 }
02415                 e1->next = expr;
02416                 return arg1;
02417         case CEXPR_ATTR:
02418                 expr->attr = arg1;
02419                 expr->op = arg2;
02420                 return (uintptr_t) expr;
02421         case CEXPR_NAMES:
02422                 add = 1;
02423                 expr->attr = arg1;
02424                 expr->op = arg2;
02425                 ebitmap_init(&negset);
02426                 while ((id = (char *)queue_remove(id_queue))) {
02427                         if (expr->attr & CEXPR_USER) {
02428                                 if (!is_id_in_scope(SYM_USERS, id)) {
02429                                         yyerror2("user %s is not within scope", id);
02430                                         constraint_expr_destroy(expr);
02431                                         return 0;
02432                                 }
02433                                 user = (user_datum_t *) hashtab_search(policydbp->p_users.table, (hashtab_key_t)
02434                                                                        id);
02435                                 if (!user) {
02436                                         yyerror2("unknown user %s", id);
02437                                         constraint_expr_destroy(expr);
02438                                         return 0;
02439                                 }
02440                                 val = user->s.value;
02441                         } else if (expr->attr & CEXPR_ROLE) {
02442                                 if (!is_id_in_scope(SYM_ROLES, id)) {
02443                                         yyerror2("role %s is not within scope", id);
02444                                         constraint_expr_destroy(expr);
02445                                         return 0;
02446                                 }
02447                                 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, (hashtab_key_t)
02448                                                                        id);
02449                                 if (!role) {
02450                                         yyerror2("unknown role %s", id);
02451                                         constraint_expr_destroy(expr);
02452                                         return 0;
02453                                 }
02454                                 val = role->s.value;
02455                         } else if (expr->attr & CEXPR_TYPE) {
02456                                 if (set_types(expr->type_names, id, &add, 0)) {
02457                                         constraint_expr_destroy(expr);
02458                                         return 0;
02459                                 }
02460                                 continue;
02461                         } else {
02462                                 yyerror("invalid constraint expression");
02463                                 constraint_expr_destroy(expr);
02464                                 return 0;
02465                         }
02466                         if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
02467                                 yyerror("out of memory");
02468                                 ebitmap_destroy(&expr->names);
02469                                 constraint_expr_destroy(expr);
02470                                 return 0;
02471                         }
02472                         free(id);
02473                 }
02474                 ebitmap_destroy(&negset);
02475                 return (uintptr_t) expr;
02476         default:
02477                 yyerror("invalid constraint expression");
02478                 constraint_expr_destroy(expr);
02479                 return 0;
02480         }
02481 
02482         yyerror("invalid constraint expression");
02483         free(expr);
02484         return 0;
02485 }
02486 
02487 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
02488 {
02489         cond_expr_t *e;
02490         int depth, retval;
02491         cond_node_t cn, *cn_old;
02492         avrule_t *tmp, *last_tmp;
02493 
02494         /* expression cannot be NULL */
02495         if (!expr) {
02496                 yyerror("illegal conditional expression");
02497                 return -1;
02498         }
02499         if (!t) {
02500                 if (!f) {
02501                         /* empty is fine, destroy expression and return */
02502                         cond_expr_destroy(expr);
02503                         return 0;
02504                 }
02505                 /* Invert */
02506                 t = f;
02507                 f = 0;
02508                 expr = define_cond_expr(COND_NOT, expr, 0);
02509                 if (!expr) {
02510                         yyerror("unable to invert");
02511                         return -1;
02512                 }
02513         }
02514 
02515         /* verify expression */
02516         depth = -1;
02517         for (e = expr; e; e = e->next) {
02518                 switch (e->expr_type) {
02519                 case COND_NOT:
02520                         if (depth < 0) {
02521                                 yyerror("illegal conditional expression; Bad NOT");
02522                                 return -1;
02523                         }
02524                         break;
02525                 case COND_AND:
02526                 case COND_OR:
02527                 case COND_XOR:
02528                 case COND_EQ:
02529                 case COND_NEQ:
02530                         if (depth < 1) {
02531                                 yyerror("illegal conditional expression; Bad binary op");
02532                                 return -1;
02533                         }
02534                         depth--;
02535                         break;
02536                 case COND_BOOL:
02537                         if (depth == (COND_EXPR_MAXDEPTH - 1)) {
02538                                 yyerror("conditional expression is like totally too deep");
02539                                 return -1;
02540                         }
02541                         depth++;
02542                         break;
02543                 default:
02544                         yyerror("illegal conditional expression");
02545                         return -1;
02546                 }
02547         }
02548         if (depth != 0) {
02549                 yyerror("illegal conditional expression");
02550                 return -1;
02551         }
02552 
02553         /*  use tmp conditional node to partially build new node */
02554         memset(&cn, 0, sizeof(cn));
02555         cn.expr = expr;
02556         cn.avtrue_list = t;
02557         cn.avfalse_list = f;
02558 
02559         /* normalize/precompute expression */
02560         if (cond_normalize_expr(policydbp, &cn) < 0) {
02561                 yyerror("problem normalizing conditional expression");
02562                 return -1;
02563         }
02564 
02565         /* get the existing conditional node, or create a new one */
02566         cn_old = get_current_cond_list(&cn);
02567         if (!cn_old) {
02568                 return -1;
02569         }
02570 
02571         /* verify te rules -- both true and false branches of conditional */
02572         tmp = cn.avtrue_list;
02573         last_tmp = NULL;
02574         while (tmp) {
02575                 if (!tmp->specified & AVRULE_TRANSITION)
02576                         continue;
02577                 retval = insert_check_type_rule(tmp, &policydbp->te_cond_avtab, &cn_old->true_list, &cn_old->false_list);
02578                 switch (retval) {
02579                 case 1:{
02580                         last_tmp = tmp;
02581                         tmp = tmp->next;
02582                         break;
02583                 }
02584                 case 0:{
02585                         /* rule conflicted, so remove it from consideration */
02586                         if (last_tmp == NULL) {
02587                                 cn.avtrue_list = cn.avtrue_list->next;
02588                                 avrule_destroy(tmp);
02589                                 free(tmp);
02590                                 tmp = cn.avtrue_list;
02591                         } else {
02592                                 last_tmp->next = tmp->next;
02593                                 avrule_destroy(tmp);
02594                                 free(tmp);
02595                                 tmp = last_tmp->next;
02596                         }
02597                         break;
02598                 }
02599                 case -1:{
02600                         return -1;
02601                 }
02602                 case 2:{
02603                         return 0;
02604                 }
02605                 default:{
02606                         assert(0);     /* should never get here */
02607                 }
02608                 }
02609         }
02610 
02611         tmp = cn.avfalse_list;
02612         last_tmp = NULL;
02613         while (tmp) {
02614                 if (!tmp->specified & AVRULE_TRANSITION)
02615                         continue;
02616                 retval = insert_check_type_rule(tmp, &policydbp->te_cond_avtab, &cn_old->false_list, &cn_old->true_list);
02617                 switch (retval) {
02618                 case 1:{
02619                         last_tmp = tmp;
02620                         tmp = tmp->next;
02621                         break;
02622                 }
02623                 case 0:{
02624                         /* rule conflicted, so remove it from consideration  */
02625                         if (last_tmp == NULL) {
02626                                 cn.avfalse_list = cn.avfalse_list->next;
02627                                 avrule_destroy(tmp);
02628                                 free(tmp);
02629                                 tmp = cn.avfalse_list;
02630                         } else {
02631                                 last_tmp->next = tmp->next;
02632                                 avrule_destroy(tmp);
02633                                 free(tmp);
02634                                 tmp = last_tmp->next;
02635                         }
02636                         break;
02637                 }
02638                 case -1:{
02639                         return -1;
02640                 }
02641                 case 2:{
02642                         return 0;
02643                 }
02644                 default:{
02645                         assert(0);     /* should never get here */
02646                 }
02647                 }
02648         }
02649 
02650         append_cond_list(&cn);
02651 
02652         /* note that there is no check here for duplicate rules, nor
02653          * check that rule already exists in base -- that will be
02654          * handled during conditional expansion, in expand.c */
02655 
02656         cn.avtrue_list = NULL;
02657         cn.avfalse_list = NULL;
02658         cond_node_destroy(&cn);
02659 
02660         return 0;
02661 }
02662 
02663 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
02664 {
02665         struct cond_expr *expr, *e1 = NULL, *e2;
02666         cond_bool_datum_t *bool_var;
02667         char *id;
02668 
02669         /* expressions are handled in the second pass */
02670         if (pass == 1) {
02671                 if (expr_type == COND_BOOL) {
02672                         while ((id = queue_remove(id_queue))) {
02673                                 free(id);
02674                         }
02675                 }
02676                 return (cond_expr_t *) 1;       /* any non-NULL value */
02677         }
02678 
02679         /* create a new expression struct */
02680         expr = malloc(sizeof(struct cond_expr));
02681         if (!expr) {
02682                 yyerror("out of memory");
02683                 return NULL;
02684         }
02685         memset(expr, 0, sizeof(cond_expr_t));
02686         expr->expr_type = expr_type;
02687 
02688         /* create the type asked for */
02689         switch (expr_type) {
02690         case COND_NOT:
02691                 e1 = NULL;
02692                 e2 = (struct cond_expr *)arg1;
02693                 while (e2) {
02694                         e1 = e2;
02695                         e2 = e2->next;
02696                 }
02697                 if (!e1 || e1->next) {
02698                         yyerror("illegal conditional NOT expression");
02699                         free(expr);
02700                         return NULL;
02701                 }
02702                 e1->next = expr;
02703                 return (struct cond_expr *)arg1;
02704         case COND_AND:
02705         case COND_OR:
02706         case COND_XOR:
02707         case COND_EQ:
02708         case COND_NEQ:
02709                 e1 = NULL;
02710                 e2 = (struct cond_expr *)arg1;
02711                 while (e2) {
02712                         e1 = e2;
02713                         e2 = e2->next;
02714                 }
02715                 if (!e1 || e1->next) {
02716                         yyerror("illegal left side of conditional binary op expression");
02717                         free(expr);
02718                         return NULL;
02719                 }
02720                 e1->next = (struct cond_expr *)arg2;
02721 
02722                 e1 = NULL;
02723                 e2 = (struct cond_expr *)arg2;
02724                 while (e2) {
02725                         e1 = e2;
02726                         e2 = e2->next;
02727                 }
02728                 if (!e1 || e1->next) {
02729                         yyerror("illegal right side of conditional binary op expression");
02730                         free(expr);
02731                         return NULL;
02732                 }
02733                 e1->next = expr;
02734                 return (struct cond_expr *)arg1;
02735         case COND_BOOL:
02736                 id = (char *)queue_remove(id_queue);
02737                 if (!id) {
02738                         yyerror("bad conditional; expected boolean id");
02739                         free(id);
02740                         free(expr);
02741                         return NULL;
02742                 }
02743                 if (!is_id_in_scope(SYM_BOOLS, id)) {
02744                         yyerror2("boolean %s is not within scope", id);
02745                         free(id);
02746                         free(expr);
02747                         return NULL;
02748                 }
02749                 bool_var = (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.table, (hashtab_key_t) id);
02750                 if (!bool_var) {
02751                         yyerror2("unknown boolean %s in conditional expression", id);
02752                         free(expr);
02753                         free(id);
02754                         return NULL;
02755                 }
02756                 expr->bool = bool_var->s.value;
02757                 free(id);
02758                 return expr;
02759         default:
02760                 yyerror("illegal conditional expression");
02761                 return NULL;
02762         }
02763 }
02764 
02765 static int set_user_roles(role_set_t * set, char *id)
02766 {
02767         role_datum_t *r;
02768         unsigned int i;
02769         ebitmap_node_t *node;
02770 
02771         if (strcmp(id, "*") == 0) {
02772                 free(id);
02773                 yyerror("* is not allowed in user declarations");
02774                 return -1;
02775         }
02776 
02777         if (strcmp(id, "~") == 0) {
02778                 free(id);
02779                 yyerror("~ is not allowed in user declarations");
02780                 return -1;
02781         }
02782 
02783         if (!is_id_in_scope(SYM_ROLES, id)) {
02784                 yyerror2("role %s is not within scope", id);
02785                 free(id);
02786                 return -1;
02787         }
02788         r = hashtab_search(policydbp->p_roles.table, id);
02789         if (!r) {
02790                 yyerror2("unknown role %s", id);
02791                 free(id);
02792                 return -1;
02793         }
02794 
02795         /* set the role and every role it dominates */
02796         ebitmap_for_each_bit(&r->dominates, node, i) {
02797                 if (ebitmap_node_get_bit(node, i))
02798                         if (ebitmap_set_bit(&set->roles, i, TRUE))
02799                                 goto oom;
02800         }
02801         free(id);
02802         return 0;
02803       oom:
02804         yyerror("out of memory");
02805         return -1;
02806 }
02807 
02808 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
02809 {
02810         cat_datum_t *cdatum;
02811         int range_start, range_end, i;
02812 
02813         if (id_has_dot(id)) {
02814                 char *id_start = id;
02815                 char *id_end = strchr(id, '.');
02816 
02817                 *(id_end++) = '\0';
02818 
02819                 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t)
02820                                                         id_start);
02821                 if (!cdatum) {
02822                         yyerror2("unknown category %s", id_start);
02823                         return -1;
02824                 }
02825                 range_start = cdatum->s.value - 1;
02826                 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id_end);
02827                 if (!cdatum) {
02828                         yyerror2("unknown category %s", id_end);
02829                         return -1;
02830                 }
02831                 range_end = cdatum->s.value - 1;
02832 
02833                 if (range_end < range_start) {
02834                         yyerror2("category range is invalid");
02835                         return -1;
02836                 }
02837         } else {
02838                 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id);
02839                 if (!cdatum) {
02840                         yyerror2("unknown category %s", id);
02841                         return -1;
02842                 }
02843                 range_start = range_end = cdatum->s.value - 1;
02844         }
02845 
02846         for (i = range_start; i <= range_end; i++) {
02847                 if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
02848                         uint32_t level_value = levdatum->level->sens - 1;
02849                         policydb_index_others(NULL, policydbp, 0);
02850                         yyerror2("category %s can not be associated "
02851                                  "with level %s", policydbp->p_cat_val_to_name[i], policydbp->p_sens_val_to_name[level_value]);
02852                         return -1;
02853                 }
02854                 if (ebitmap_set_bit(cats, i, TRUE)) {
02855                         yyerror("out of memory");
02856                         return -1;
02857                 }
02858         }
02859 
02860         return 0;
02861 }
02862 
02863 static int parse_semantic_categories(char *id, level_datum_t * levdatum, mls_semantic_cat_t ** cats)
02864 {
02865         cat_datum_t *cdatum;
02866         mls_semantic_cat_t *newcat;
02867         unsigned int range_start, range_end;
02868 
02869         if (id_has_dot(id)) {
02870                 char *id_start = id;
02871                 char *id_end = strchr(id, '.');
02872 
02873                 *(id_end++) = '\0';
02874 
02875                 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t)
02876                                                         id_start);
02877                 if (!cdatum) {
02878                         yyerror2("unknown category %s", id_start);
02879                         return -1;
02880                 }
02881                 range_start = cdatum->s.value;
02882 
02883                 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id_end);
02884                 if (!cdatum) {
02885                         yyerror2("unknown category %s", id_end);
02886                         return -1;
02887                 }
02888                 range_end = cdatum->s.value;
02889         } else {
02890                 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, (hashtab_key_t) id);
02891                 if (!cdatum) {
02892                         yyerror2("unknown category %s", id);
02893                         return -1;
02894                 }
02895                 range_start = range_end = cdatum->s.value;
02896         }
02897 
02898         newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
02899         if (!newcat) {
02900                 yyerror("out of memory");
02901                 return -1;
02902         }
02903 
02904         mls_semantic_cat_init(newcat);
02905         newcat->next = *cats;
02906         newcat->low = range_start;
02907         newcat->high = range_end;
02908 
02909         *cats = newcat;
02910 
02911         return 0;
02912 }
02913 
02914 int define_user(void)
02915 {
02916         char *id;
02917         user_datum_t *usrdatum;
02918         level_datum_t *levdatum;
02919         int l;
02920 
02921         if (pass == 1) {
02922                 while ((id = queue_remove(id_queue)))
02923                         free(id);
02924                 if (mlspol) {
02925                         while ((id = queue_remove(id_queue)))
02926                                 free(id);
02927                         id = queue_remove(id_queue);
02928                         free(id);
02929                         for (l = 0; l < 2; l++) {
02930                                 while ((id = queue_remove(id_queue))) {
02931                                         free(id);
02932                                 }
02933                                 id = queue_remove(id_queue);
02934                                 if (!id)
02935                                         break;
02936                                 free(id);
02937                         }
02938                 }
02939                 return 0;
02940         }
02941 
02942         if ((usrdatum = declare_user()) == NULL) {
02943                 return -1;
02944         }
02945 
02946         while ((id = queue_remove(id_queue))) {
02947                 if (set_user_roles(&usrdatum->roles, id))
02948                         continue;
02949         }
02950 
02951         if (mlspol) {
02952                 id = queue_remove(id_queue);
02953                 if (!id) {
02954                         yyerror("no default level specified for user");
02955                         return -1;
02956                 }
02957 
02958                 levdatum = (level_datum_t *)
02959                         hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
02960                 if (!levdatum) {
02961                         yyerror2("unknown sensitivity %s used in user" " level definition", id);
02962                         free(id);
02963                         return -1;
02964                 }
02965                 free(id);
02966 
02967                 usrdatum->dfltlevel.sens = levdatum->level->sens;
02968 
02969                 while ((id = queue_remove(id_queue))) {
02970                         if (parse_semantic_categories(id, levdatum, &usrdatum->dfltlevel.cat)) {
02971                                 free(id);
02972                                 return -1;
02973                         }
02974                         free(id);
02975                 }
02976 
02977                 id = queue_remove(id_queue);
02978 
02979                 for (l = 0; l < 2; l++) {
02980                         levdatum = (level_datum_t *)
02981                                 hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
02982                         if (!levdatum) {
02983                                 yyerror2("unknown sensitivity %s used in user" " range definition", id);
02984                                 free(id);
02985                                 return -1;
02986                         }
02987                         free(id);
02988 
02989                         usrdatum->range.level[l].sens = levdatum->level->sens;
02990 
02991                         while ((id = queue_remove(id_queue))) {
02992                                 if (parse_semantic_categories(id, levdatum, &usrdatum->range.level[l].cat)) {
02993                                         free(id);
02994                                         return -1;
02995                                 }
02996                                 free(id);
02997                         }
02998 
02999                         id = queue_remove(id_queue);
03000                         if (!id)
03001                                 break;
03002                 }
03003 
03004                 if (l == 0) {
03005                         if (mls_semantic_level_cpy(&usrdatum->range.level[1], &usrdatum->range.level[0])) {
03006                                 yyerror("out of memory");
03007                                 return -1;
03008                         }
03009                 }
03010         }
03011         return 0;
03012 }
03013 
03014 static int parse_security_context(context_struct_t * c)
03015 {
03016         char *id;
03017         role_datum_t *role;
03018         type_datum_t *typdatum;
03019         user_datum_t *usrdatum;
03020         level_datum_t *levdatum;
03021         int l;
03022 
03023         if (pass == 1) {
03024                 id = queue_remove(id_queue);
03025                 free(id);              /* user  */
03026                 id = queue_remove(id_queue);
03027                 free(id);              /* role  */
03028                 id = queue_remove(id_queue);
03029                 free(id);              /* type  */
03030                 if (mlspol) {
03031                         id = queue_remove(id_queue);
03032                         free(id);
03033                         for (l = 0; l < 2; l++) {
03034                                 while ((id = queue_remove(id_queue))) {
03035                                         free(id);
03036                                 }
03037                                 id = queue_remove(id_queue);
03038                                 if (!id)
03039                                         break;
03040                                 free(id);
03041                         }
03042                 }
03043                 return 0;
03044         }
03045 
03046         context_init(c);
03047 
03048         /* extract the user */
03049         id = queue_remove(id_queue);
03050         if (!id) {
03051                 yyerror("no effective user?");
03052                 goto bad;
03053         }
03054         if (!is_id_in_scope(SYM_USERS, id)) {
03055                 yyerror2("user %s is not within scope", id);
03056                 free(id);
03057                 goto bad;
03058         }
03059         usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table, (hashtab_key_t) id);
03060         if (!usrdatum) {
03061                 yyerror2("user %s is not defined", id);
03062                 free(id);
03063                 goto bad;
03064         }
03065         c->user = usrdatum->s.value;
03066 
03067         /* no need to keep the user name */
03068         free(id);
03069 
03070         /* extract the role */
03071         id = (char *)queue_remove(id_queue);
03072         if (!id) {
03073                 yyerror("no role name for sid context definition?");
03074                 return -1;
03075         }
03076         if (!is_id_in_scope(SYM_ROLES, id)) {
03077                 yyerror2("role %s is not within scope", id);
03078                 free(id);
03079                 return -1;
03080         }
03081         role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, (hashtab_key_t) id);
03082         if (!role) {
03083                 yyerror2("role %s is not defined", id);
03084                 free(id);
03085                 return -1;
03086         }
03087         c->role = role->s.value;
03088 
03089         /* no need to keep the role name */
03090         free(id);
03091 
03092         /* extract the type */
03093         id = (char *)queue_remove(id_queue);
03094         if (!id) {
03095                 yyerror("no type name for sid context definition?");
03096                 return -1;
03097         }
03098         if (!is_id_in_scope(SYM_TYPES, id)) {
03099                 yyerror2("type %s is not within scope", id);
03100                 free(id);
03101                 return -1;
03102         }
03103         typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table, (hashtab_key_t) id);
03104         if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
03105                 yyerror2("type %s is not defined or is an attribute", id);
03106                 free(id);
03107                 return -1;
03108         }
03109         c->type = typdatum->s.value;
03110 
03111         /* no need to keep the type name */
03112         free(id);
03113 
03114         if (mlspol) {
03115                 /* extract the low sensitivity */
03116                 id = (char *)queue_head(id_queue);
03117                 if (!id) {
03118                         yyerror("no sensitivity name for sid context" " definition?");
03119                         return -1;
03120                 }
03121 
03122                 id = (char *)queue_remove(id_queue);
03123                 for (l = 0; l < 2; l++) {
03124                         levdatum = (level_datum_t *)
03125                                 hashtab_search(policydbp->p_levels.table, (hashtab_key_t) id);
03126                         if (!levdatum) {
03127                                 yyerror2("Sensitivity %s is not defined", id);
03128                                 free(id);
03129                                 return -1;
03130                         }
03131                         free(id);
03132                         c->range.level[l].sens = levdatum->level->sens;
03133 
03134                         /* extract low category set */
03135                         while ((id = queue_remove(id_queue))) {
03136                                 if (parse_categories(id, levdatum, &c->range.level[l].cat)) {
03137                                         free(id);
03138                                         return -1;
03139                                 }
03140                                 free(id);
03141                         }
03142 
03143                         /* extract high sensitivity */
03144                         id = (char *)queue_remove(id_queue);
03145                         if (!id)
03146                                 break;
03147                 }
03148 
03149                 if (l == 0) {
03150                         c->range.level[1].sens = c->range.level[0].sens;
03151                         if (ebitmap_cpy(&c->range.level[1].cat, &c->range.level[0].cat)) {
03152 
03153                                 yyerror("out of memory");
03154                                 goto bad;
03155                         }
03156                 }
03157         }
03158 
03159         if (!policydb_context_isvalid(policydbp, c)) {
03160                 yyerror("invalid security context");
03161                 goto bad;
03162         }
03163         return 0;
03164 
03165       bad:
03166         context_destroy(c);
03167 
03168         return -1;
03169 }
03170 
03171 int define_initial_sid_context(void)
03172 {
03173         char *id;
03174         ocontext_t *c, *head;
03175 
03176         if (pass == 1) {
03177                 id = (char *)queue_remove(id_queue);
03178                 free(id);
03179                 parse_security_context(NULL);
03180                 return 0;
03181         }
03182 
03183         id = (char *)queue_remove(id_queue);
03184         if (!id) {
03185                 yyerror("no sid name for SID context definition?");
03186                 return -1;
03187         }
03188         head = policydbp->ocontexts[OCON_ISID];
03189         for (c = head; c; c = c->next) {
03190                 if (!strcmp(id, c->u.name))
03191                         break;
03192         }
03193 
03194         if (!c) {
03195                 yyerror2("SID %s is not defined", id);
03196                 free(id);
03197                 return -1;
03198         }
03199         if (c->context[0].user) {
03200                 yyerror2("The context for SID %s is multiply defined", id);
03201                 free(id);
03202                 return -1;
03203         }
03204         /* no need to keep the sid name */
03205         free(id);
03206 
03207         if (parse_security_context(&c->context[0]))
03208                 return -1;
03209 
03210         return 0;
03211 }
03212 
03213 int define_fs_context(unsigned int major, unsigned int minor)
03214 {
03215         ocontext_t *newc, *c, *head;
03216 
03217         if (pass == 1) {
03218                 parse_security_context(NULL);
03219                 parse_security_context(NULL);
03220                 return 0;
03221         }
03222 
03223         newc = (ocontext_t *) malloc(sizeof(ocontext_t));
03224         if (!newc) {
03225                 yyerror("out of memory");
03226                 return -1;
03227         }
03228         memset(newc, 0, sizeof(ocontext_t));
03229 
03230         newc->u.name = (char *)malloc(6);
03231         if (!newc->u.name) {
03232                 yyerror("out of memory");
03233                 free(newc);
03234                 return -1;
03235         }
03236         sprintf(newc->u.name, "%02x:%02x", major, minor);
03237 
03238         if (parse_security_context(&newc->context[0])) {
03239                 free(newc->u.name);
03240                 free(newc);
03241                 return -1;
03242         }
03243         if (parse_security_context(&newc->context[1])) {
03244                 context_destroy(&newc->context[0]);
03245                 free(newc->u.name);
03246                 free(newc);
03247                 return -1;
03248         }
03249         head = policydbp->ocontexts[OCON_FS];
03250 
03251         for (c = head; c; c = c->next) {
03252                 if (!strcmp(newc->u.name, c->u.name)) {
03253                         yyerror2("duplicate entry for file system %s", newc->u.name);
03254                         context_destroy(&newc->context[0]);
03255                         context_destroy(&newc->context[1]);
03256                         free(newc->u.name);
03257                         free(newc);
03258                         return -1;
03259                 }
03260         }
03261 
03262         newc->next = head;
03263         policydbp->ocontexts[OCON_FS] = newc;
03264 
03265         return 0;
03266 }
03267 
03268 int define_port_context(unsigned int low, unsigned int high)
03269 {
03270         ocontext_t *newc, *c, *l, *head;
03271         unsigned int protocol;
03272         char *id;
03273 
03274         if (pass == 1) {
03275                 id = (char *)queue_remove(id_queue);
03276                 free(id);
03277                 parse_security_context(NULL);
03278                 return 0;
03279         }
03280 
03281         newc = malloc(sizeof(ocontext_t));
03282         if (!newc) {
03283                 yyerror("out of memory");
03284                 return -1;
03285         }
03286         memset(newc, 0, sizeof(ocontext_t));
03287 
03288         id = (char *)queue_remove(id_queue);
03289         if (!id) {
03290                 free(newc);
03291                 return -1;
03292         }
03293         if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
03294                 protocol = IPPROTO_TCP;
03295         } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
03296                 protocol = IPPROTO_UDP;
03297         } else {
03298                 yyerror2("unrecognized protocol %s", id);
03299                 free(newc);
03300                 return -1;
03301         }
03302 
03303         newc->u.port.protocol = protocol;
03304         newc->u.port.low_port = low;
03305         newc->u.port.high_port = high;
03306 
03307         if (low > high) {
03308                 yyerror2("low port %d exceeds high port %d", low, high);
03309                 free(newc);
03310                 return -1;
03311         }
03312 
03313         if (parse_security_context(&newc->context[0])) {
03314                 free(newc);
03315                 return -1;
03316         }
03317 
03318         /* Preserve the matching order specified in the configuration. */
03319         head = policydbp->ocontexts[OCON_PORT];
03320         for (l = NULL, c = head; c; l = c, c = c->next) {
03321                 unsigned int prot2, low2, high2;
03322 
03323                 prot2 = c->u.port.protocol;
03324                 low2 = c->u.port.low_port;
03325                 high2 = c->u.port.high_port;
03326                 if (protocol != prot2)
03327                         continue;
03328                 if (low == low2 && high == high2) {
03329                         yyerror2("duplicate portcon entry for %s %d-%d ", id, low, high);
03330                         goto bad;
03331                 }
03332                 if (low2 <= low && high2 >= high) {
03333                         yyerror2("portcon entry for %s %d-%d hidden by earlier " "entry for %d-%d", id, low, high, low2, high2);
03334                         goto bad;
03335                 }
03336         }
03337         free(id);
03338 
03339         if (l)
03340                 l->next = newc;
03341         else
03342                 policydbp->ocontexts[OCON_PORT] = newc;
03343 
03344         return 0;
03345 
03346       bad:
03347         free(newc);
03348         return -1;
03349 }
03350 
03351 int define_netif_context(void)
03352 {
03353         ocontext_t *newc, *c, *head;
03354 
03355         if (pass == 1) {
03356                 free(queue_remove(id_queue));
03357                 parse_security_context(NULL);
03358                 parse_security_context(NULL);
03359                 return 0;
03360         }
03361 
03362         newc = (ocontext_t *) malloc(sizeof(ocontext_t));
03363         if (!newc) {
03364                 yyerror("out of memory");
03365                 return -1;
03366         }
03367         memset(newc, 0, sizeof(ocontext_t));
03368 
03369         newc->u.name = (char *)queue_remove(id_queue);
03370         if (!newc->u.name) {
03371                 free(newc);
03372                 return -1;
03373         }
03374         if (parse_security_context(&newc->context[0])) {
03375                 free(newc->u.name);
03376                 free(newc);
03377                 return -1;
03378         }
03379         if (parse_security_context(&newc->context[1])) {
03380                 context_destroy(&newc->context[0]);
03381                 free(newc->u.name);
03382                 free(newc);
03383                 return -1;
03384         }
03385         head = policydbp->ocontexts[OCON_NETIF];
03386 
03387         for (c = head; c; c = c->next) {
03388                 if (!strcmp(newc->u.name, c->u.name)) {
03389                         yyerror2("duplicate entry for network interface %s", newc->u.name);
03390                         context_destroy(&newc->context[0]);
03391                         context_destroy(&newc->context[1]);
03392                         free(newc->u.name);
03393                         free(newc);
03394                         return -1;
03395                 }
03396         }
03397 
03398         newc->next = head;
03399         policydbp->ocontexts[OCON_NETIF] = newc;
03400         return 0;
03401 }
03402 
03403 int define_ipv4_node_context()
03404 {
03405         char *id;
03406         int rc = 0;
03407         struct in_addr addr, mask;
03408         ocontext_t *newc, *c, *l, *head;
03409 
03410         if (pass == 1) {
03411                 free(queue_remove(id_queue));
03412                 free(queue_remove(id_queue));
03413                 parse_security_context(NULL);
03414                 goto out;
03415         }
03416 
03417         id = queue_remove(id_queue);
03418         if (!id) {
03419                 yyerror("failed to read ipv4 address");
03420                 rc = -1;
03421                 goto out;
03422         }
03423 
03424         rc = inet_pton(AF_INET, id, &addr);
03425         free(id);
03426         if (rc < 1) {
03427                 yyerror("failed to parse ipv4 address");
03428                 if (rc == 0)
03429                         rc = -1;
03430                 goto out;
03431         }
03432 
03433         id = queue_remove(id_queue);
03434         if (!id) {
03435                 yyerror("failed to read ipv4 address");
03436                 rc = -1;
03437                 goto out;
03438         }
03439 
03440         rc = inet_pton(AF_INET, id, &mask);
03441         free(id);
03442         if (rc < 1) {
03443                 yyerror("failed to parse ipv4 mask");
03444                 if (rc == 0)
03445                         rc = -1;
03446                 goto out;
03447         }
03448 
03449         newc = malloc(sizeof(ocontext_t));
03450         if (!newc) {
03451                 yyerror("out of memory");
03452                 rc = -1;
03453                 goto out;
03454         }
03455 
03456         memset(newc, 0, sizeof(ocontext_t));
03457         newc->u.node.addr = addr.s_addr;
03458         newc->u.node.mask = mask.s_addr;
03459 
03460         if (parse_security_context(&newc->context[0])) {
03461                 free(newc);
03462                 return -1;
03463         }
03464 
03465         /* Create order of most specific to least retaining
03466            the order specified in the configuration. */
03467         head = policydbp->ocontexts[OCON_NODE];
03468         for (l = NULL, c = head; c; l = c, c = c->next) {
03469                 if (newc->u.node.mask > c->u.node.mask)
03470                         break;
03471         }
03472 
03473         newc->next = c;
03474 
03475         if (l)
03476                 l->next = newc;
03477         else
03478                 policydbp->ocontexts[OCON_NODE] = newc;
03479         rc = 0;
03480       out:
03481         return rc;
03482 }
03483 
03484 int define_ipv6_node_context(void)
03485 {
03486         char *id;
03487         int rc = 0;
03488         struct in6_addr addr, mask;
03489         ocontext_t *newc, *c, *l, *head;
03490 
03491         if (pass == 1) {
03492                 free(queue_remove(id_queue));
03493                 free(queue_remove(id_queue));
03494                 parse_security_context(NULL);
03495                 goto out;
03496         }
03497 
03498         id = queue_remove(id_queue);
03499         if (!id) {
03500                 yyerror("failed to read ipv6 address");
03501                 rc = -1;
03502                 goto out;
03503         }
03504 
03505         rc = inet_pton(AF_INET6, id, &addr);
03506         free(id);
03507         if (rc < 1) {
03508                 yyerror("failed to parse ipv6 address");
03509                 if (rc == 0)
03510                         rc = -1;
03511                 goto out;
03512         }
03513 
03514         id = queue_remove(id_queue);
03515         if (!id) {
03516                 yyerror("failed to read ipv6 address");
03517                 rc = -1;
03518                 goto out;
03519         }
03520 
03521         rc = inet_pton(AF_INET6, id, &mask);
03522         free(id);
03523         if (rc < 1) {
03524                 yyerror("failed to parse ipv6 mask");
03525                 if (rc == 0)
03526                         rc = -1;
03527                 goto out;
03528         }
03529 
03530         newc = malloc(sizeof(ocontext_t));
03531         if (!newc) {
03532                 yyerror("out of memory");
03533                 rc = -1;
03534                 goto out;
03535         }
03536 
03537         memset(newc, 0, sizeof(ocontext_t));
03538         memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
03539         memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
03540 
03541         if (parse_security_context(&newc->context[0])) {
03542                 free(newc);
03543                 rc = -1;
03544                 goto out;
03545         }
03546 
03547         /* Create order of most specific to least retaining
03548            the order specified in the configuration. */
03549         head = policydbp->ocontexts[OCON_NODE6];
03550         for (l = NULL, c = head; c; l = c, c = c->next) {
03551                 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
03552                         break;
03553         }
03554 
03555         newc->next = c;
03556 
03557         if (l)
03558                 l->next = newc;
03559         else
03560                 policydbp->ocontexts[OCON_NODE6] = newc;
03561 
03562         rc = 0;
03563       out:
03564         return rc;
03565 }
03566 
03567 int define_fs_use(int behavior)
03568 {
03569         ocontext_t *newc, *c, *head;
03570 
03571         if (pass == 1) {
03572                 free(queue_remove(id_queue));
03573                 if (behavior != SECURITY_FS_USE_PSIDS)
03574                         parse_security_context(NULL);
03575                 return 0;
03576         }
03577 
03578         newc = (ocontext_t *) malloc(sizeof(ocontext_t));
03579         if (!newc) {
03580                 yyerror("out of memory");
03581                 return -1;
03582         }
03583         memset(newc, 0, sizeof(ocontext_t));
03584 
03585         newc->u.name = (char *)queue_remove(id_queue);
03586         if (!newc->u.name) {
03587                 free(newc);
03588                 return -1;
03589         }
03590         newc->v.behavior = behavior;
03591         if (newc->v.behavior != SECURITY_FS_USE_PSIDS) {
03592                 if (parse_security_context(&newc->context[0])) {
03593                         free(newc->u.name);
03594                         free(newc);
03595                         return -1;
03596                 }
03597         } else
03598                 memset(&newc->context[0], 0, sizeof(context_struct_t) * 2);
03599 
03600         head = policydbp->ocontexts[OCON_FSUSE];
03601 
03602         for (c = head; c; c = c->next) {
03603                 if (!strcmp(newc->u.name, c->u.name)) {
03604                         yyerror2("duplicate fs_use entry for filesystem type %s", newc->u.name);
03605                         context_destroy(&newc->context[0]);
03606                         free(newc->u.name);
03607                         free(newc);
03608                         return -1;
03609                 }
03610         }
03611 
03612         newc->next = head;
03613         policydbp->ocontexts[OCON_FSUSE] = newc;
03614         return 0;
03615 }
03616 
03617 int define_genfs_context_helper(char *fstype, int has_type)
03618 {
03619         struct genfs *genfs_p, *genfs, *newgenfs;
03620         ocontext_t *newc, *c, *head, *p;
03621         char *type = NULL;
03622         int len, len2;
03623 
03624         if (pass == 1) {
03625                 free(fstype);
03626                 free(queue_remove(id_queue));
03627                 if (has_type)
03628                         free(queue_remove(id_queue));
03629                 parse_security_context(NULL);
03630                 return 0;
03631         }
03632 
03633         for (genfs_p = NULL, genfs = policydbp->genfs; genfs; genfs_p = genfs, genfs = genfs->next) {
03634                 if (strcmp(fstype, genfs->fstype) <= 0)
03635                         break;
03636         }
03637 
03638         if (!genfs || strcmp(fstype, genfs->fstype)) {
03639                 newgenfs = malloc(sizeof(struct genfs));
03640                 if (!newgenfs) {
03641                         yyerror("out of memory");
03642                         return -1;
03643                 }
03644                 memset(newgenfs, 0, sizeof(struct genfs));
03645                 newgenfs->fstype = fstype;
03646                 newgenfs->next = genfs;
03647                 if (genfs_p)
03648                         genfs_p->next = newgenfs;
03649                 else
03650                         policydbp->genfs = newgenfs;
03651                 genfs = newgenfs;
03652         } else {
03653                 free(fstype);
03654         }
03655 
03656         newc = (ocontext_t *) malloc(sizeof(ocontext_t));
03657         if (!newc) {
03658                 yyerror("out of memory");
03659                 return -1;
03660         }
03661         memset(newc, 0, sizeof(ocontext_t));
03662 
03663         newc->u.name = (char *)queue_remove(id_queue);
03664         if (!newc->u.name)
03665                 goto fail;
03666         if (has_type) {
03667                 type = (char *)queue_remove(id_queue);
03668                 if (!type)
03669                         goto fail;
03670                 if (type[1] != 0) {
03671                         yyerror2("invalid type %s", type);
03672                         goto fail;
03673                 }
03674                 switch (type[0]) {
03675                 case 'b':
03676                         newc->v.sclass = SECCLASS_BLK_FILE;
03677                         break;
03678                 case 'c':
03679                         newc->v.sclass = SECCLASS_CHR_FILE;
03680                         break;
03681                 case 'd':
03682                         newc->v.sclass = SECCLASS_DIR;
03683                         break;
03684                 case 'p':
03685                         newc->v.sclass = SECCLASS_FIFO_FILE;
03686                         break;
03687                 case 'l':
03688                         newc->v.sclass = SECCLASS_LNK_FILE;
03689                         break;
03690                 case 's':
03691                         newc->v.sclass = SECCLASS_SOCK_FILE;
03692                         break;
03693                 case '-':
03694                         newc->v.sclass = SECCLASS_FILE;
03695                         break;
03696                 default:
03697                         yyerror2("invalid type %s", type);
03698                         goto fail;
03699                 }
03700         }
03701         free(type);
03702         type = NULL;
03703         if (parse_security_context(&newc->context[0]))
03704                 goto fail;
03705 
03706         head = genfs->head;
03707 
03708         for (p = NULL, c = head; c; p = c, c = c->next) {
03709                 if (!strcmp(newc->u.name, c->u.name) && (!newc->v.sclass || !c->v.sclass || newc->v.sclass == c->v.sclass)) {
03710                         yyerror2("duplicate entry for genfs entry (%s, %s)", fstype, newc->u.name);
03711                         goto fail;
03712                 }
03713                 len = strlen(newc->u.name);
03714                 len2 = strlen(c->u.name);
03715                 if (len > len2)
03716                         break;
03717         }
03718 
03719         newc->next = c;
03720         if (p)
03721                 p->next = newc;
03722         else
03723                 genfs->head = newc;
03724         return 0;
03725       fail:
03726         if (type)
03727                 free(type);
03728         context_destroy(&newc->context[0]);
03729         if (fstype)
03730                 free(fstype);
03731         if (newc->u.name)
03732                 free(newc->u.name);
03733         free(newc);
03734         return -1;
03735 }
03736 
03737 int define_genfs_context(int has_type)
03738 {
03739         return define_genfs_context_helper(queue_remove(id_queue), has_type);
03740 }
03741 
03742 int define_range_trans(int class_specified)
03743 {
03744         char *id;
03745         level_datum_t *levdatum = 0;
03746         class_datum_t *cladatum;
03747         range_trans_rule_t *rule;
03748         int l, add = 1;
03749 
03750         if (!mlspol) {
03751                 yyerror("range_transition rule in non-MLS configuration");
03752                 return -1;
03753         }
03754 
03755         if (pass == 1) {
03756                 while ((id = queue_remove(id_queue)))
03757                         free(id);
03758                 while ((id = queue_remove(id_queue)))
03759                         free(id);
03760                 if (class_specified)
03761                         while ((id = queue_remove(id_queue)))
03762                                 free(id);
03763                 id = queue_remove(id_queue);
03764                 free(id);
03765                 for (l = 0; l < 2; l++) {
03766                         while ((id = queue_remove(id_queue))) {
03767                                 free(id);
03768                         }
03769                         id = queue_remove(id_queue);
03770                         if (!id)
03771                                 break;
03772                         free(id);
03773                 }
03774                 return 0;
03775         }
03776 
03777         rule = malloc(sizeof(struct range_trans_rule));
03778         if (!rule) {
03779                 yyerror("out of memory");
03780                 return -1;
03781         }
03782         range_trans_rule_init(rule);
03783 
03784         while ((id = queue_remove(id_queue))) {
03785                 if (set_types(&rule->stypes, id, &add, 0))
03786                         goto out;
03787         }
03788         add = 1;
03789         while ((id = queue_remove(id_queue))) {
03790                 if (set_types(&rule->ttypes, id, &add, 0))
03791                         goto out;
03792         }
03793 
03794         if (class_specified) {
03795                 while ((id = queue_remove(id_queue))) {
03796                         if (!is_id_in_scope(SYM_CLASSES, id)) {
03797                                 yyerror2("class %s is not within scope", id);
03798                                 free(id);
03799                                 goto out;
03800                         }
03801                         cladatum = hashtab_search(policydbp->p_classes.table, id);
03802                         if (!cladatum) {
03803                                 yyerror2("unknown class %s", id);
03804                                 goto out;
03805                         }
03806 
03807                         ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
03808                         free(id);
03809                 }
03810         } else {
03811                 cladatum = hashtab_search(policydbp->p_classes.table, "process");
03812                 if (!cladatum) {
03813                         yyerror2("could not find process class for " "legacy range_transition statement");
03814                         goto out;
03815                 }
03816 
03817                 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
03818         }
03819 
03820         id = (char *)queue_remove(id_queue);
03821         if (!id) {
03822                 yyerror("no range in range_transition definition?");
03823                 goto out;
03824         }
03825         for (l = 0; l < 2; l++) {
03826                 levdatum = hashtab_search(policydbp->p_levels.table, id);
03827                 if (!levdatum) {
03828                         yyerror2("unknown level %s used in range_transition " "definition", id);
03829                         free(id);
03830                         goto out;
03831                 }
03832                 free(id);
03833 
03834                 rule->trange.level[l].sens = levdatum->level->sens;
03835 
03836                 while ((id = queue_remove(id_queue))) {
03837                         if (parse_semantic_categories(id, levdatum, &rule->trange.level[l].cat)) {
03838                                 free(id);
03839                                 goto out;
03840                         }
03841                         free(id);
03842                 }
03843 
03844                 id = (char *)queue_remove(id_queue);
03845                 if (!id)
03846                         break;
03847         }
03848         if (l == 0) {
03849                 if (mls_semantic_level_cpy(&rule->trange.level[1], &rule->trange.level[0])) {
03850                         yyerror("out of memory");
03851                         goto out;
03852                 }
03853         }
03854 
03855         append_range_trans(rule);
03856         return 0;
03857 
03858       out:
03859         range_trans_rule_destroy(rule);
03860         return -1;
03861 }
03862 
03863 /* FLASK */