policy_define.h File Reference


Detailed Description

This file is based upon checkpolicy/policy_define.h from NSA's SVN repository.

Definition in file policy_define.h.

Go to the source code of this file.


Defines

#define COND_ERR   ((avrule_t *)-1)
#define TRUE   1
#define FALSE   0
#define SECURITY_FS_USE_PSIDS   6
 parser used to support fs_use_psid declarations, so revert that bit of code here

Functions

avrule_t * define_cond_compute_type (int which)
avrule_t * define_cond_pol_list (avrule_t *avlist, avrule_t *stmt)
avrule_t * define_cond_te_avtab (int which)
cond_expr_t * define_cond_expr (uint32_t expr_type, void *arg1, void *arg2)
int define_attrib (void)
int define_av_perms (int inherits)
int define_bool (void)
int define_category (void)
int define_class (void)
int define_common_perms (void)
int define_compute_type (int which)
int define_conditional (cond_expr_t *expr, avrule_t *t_list, avrule_t *f_list)
int define_constraint (constraint_expr_t *expr)
int define_dominance (void)
int define_fs_context (unsigned int major, unsigned int minor)
int define_fs_use (int behavior)
int define_genfs_context (int has_type)
int define_initial_sid_context (void)
int define_initial_sid (void)
int define_ipv4_node_context (void)
int define_ipv6_node_context (void)
int define_level (void)
int define_mls (void)
int define_netif_context (void)
int define_polcap (void)
int define_port_context (unsigned int low, unsigned int high)
int define_range_trans (int class_specified)
int define_role_allow (void)
int define_role_trans (void)
int define_role_types (void)
int define_sens (void)
int define_te_avtab (int which)
int define_typealias (void)
int define_typeattribute (void)
int define_type (int alias)
int define_user (void)
int define_validatetrans (constraint_expr_t *expr)
int insert_id (char *id, int push)
int insert_separator (int push)
role_datum_t * define_role_dom (role_datum_t *r)
role_datum_t * merge_roles_dom (role_datum_t *r1, role_datum_t *r2)
uintptr_t define_cexpr (uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)

Define Documentation

#define COND_ERR   ((avrule_t *)-1)
 

Definition at line 17 of file policy_define.h.

#define TRUE   1
 

Definition at line 19 of file policy_define.h.

Referenced by define_attrib(), define_cexpr(), define_compute_type_helper(), define_constraint(), define_level(), define_polcap(), define_range_trans(), define_role_dom(), define_te_avtab_helper(), define_type(), define_typeattribute(), define_validatetrans(), dominate_role_recheck(), filter_view_context_item_to_entry(), filter_view_init_date(), find_dialog_search(), message_view_create(), message_view_on_column_click(), message_view_update_visible_columns(), modify_view_init_signals(), open_policy_init_pane(), open_policy_init_value(), open_policy_init_values(), open_policy_init_widgets(), open_policy_on_policy_type_toggle(), parse_categories(), policy_components_view_init_lists(), policy_components_view_on_to_inc_click(), policy_view_find_terules(), policy_view_load_policy_source(), policy_view_notebook_on_event_after(), policy_view_on_line_event(), policy_view_show_policy_line(), policy_view_source_update(), preferences_view_init_values(), progress_create(), remap_types_highlight_entries(), remap_types_init_widgets(), remap_types_update_view(), result_item_avrule_print_diff(), result_item_inline_link_event(), result_item_print_header(), result_item_print_modified_range(), result_item_print_summary(), result_item_terule_print_diff(), result_item_user_print_modified(), results_create_summary(), results_get_slow_buffer(), results_populate_key_buffer(), results_summary_on_change(), results_update_stats(), results_update_summary(), select_diff_dialog_run(), select_diff_on_select_all_click(), set_roles(), set_types(), set_user_roles(), toplevel_add_new_view(), toplevel_on_edit_menu_activate(), toplevel_open_log(), toplevel_open_policies(), toplevel_open_policy(), toplevel_set_recent_policies_submenu(), toplevel_set_sort_menu_selection(), util_save_file(), and yyparse().

#define FALSE   0
 

Definition at line 20 of file policy_define.h.

Referenced by define_type(), filter_view_apply(), find_dialog_search(), message_view_dialog_change(), message_view_messages_vector(), message_view_on_column_click(), message_view_popup_menu(), message_view_store_get_iter(), message_view_store_iter_children(), message_view_store_iter_next(), message_view_store_iter_nth_child(), message_view_update_rows(), message_view_update_visible_columns(), modify_view_init_signals(), open_policy_on_policy_type_toggle(), policy_components_view_init_lists(), policy_components_view_on_to_exc_click(), policy_view_find_terules(), policy_view_on_find_terules_click(), preferences_view_init_values(), preferences_view_init_widgets(), progress_create(), progress_wait(), remap_types_highlight_entries(), remap_types_update_view(), report_window_on_output_format_toggle(), report_window_run(), result_item_inline_link_event(), results_create(), results_get_slow_buffer(), results_summary_on_change(), results_update_summary(), select_diff_dialog_run(), select_diff_on_select_none_click(), toplevel_add_new_view(), toplevel_on_edit_menu_activate(), toplevel_on_help_activate(), toplevel_on_switch_page(), toplevel_open_log(), toplevel_open_policies(), toplevel_open_policy(), toplevel_run_diff(), and yyparse().

#define SECURITY_FS_USE_PSIDS   6
 

parser used to support fs_use_psid declarations, so revert that bit of code here

Definition at line 24 of file policy_define.h.

Referenced by yyparse().


Function Documentation

avrule_t* define_cond_compute_type int  which  ) 
 

Definition at line 1367 of file policy_define.c.

References define_compute_type_helper(), id_queue, num_rules, pass, and queue_remove().

Referenced by yyparse().

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 }

avrule_t* define_cond_pol_list avrule_t *  avlist,
avrule_t *  stmt
 

Definition at line 1461 of file policy_define.c.

References num_rules, and pass.

Referenced by yyparse().

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 }

avrule_t* define_cond_te_avtab int  which  ) 
 

Definition at line 1618 of file policy_define.c.

References define_te_avtab_helper(), id_queue, num_rules, pass, and queue_remove().

Referenced by yyparse().

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 }

cond_expr_t* define_cond_expr uint32_t  expr_type,
void *  arg1,
void *  arg2
 

Definition at line 2663 of file policy_define.c.

References id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by define_conditional(), and yyparse().

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 }

int define_attrib void   ) 
 

Definition at line 937 of file policy_define.c.

References declare_type(), id_queue, pass, queue_remove(), and TRUE.

Referenced by yyparse().

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 }

int define_av_perms int  inherits  ) 
 

Definition at line 427 of file policy_define.c.

References add_perm_to_class(), id_queue, pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_bool void   ) 
 

Definition at line 1392 of file policy_define.c.

References declare_symbol(), id_has_dot(), id_queue, pass, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_category void   ) 
 

Definition at line 706 of file policy_define.c.

References declare_symbol(), id_has_dot(), id_queue, pass, queue_remove(), and yyerror().

Referenced by yyparse().

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 }

int define_class void   ) 
 

Definition at line 190 of file policy_define.c.

References declare_symbol(), id_queue, pass, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_common_perms void   ) 
 

Definition at line 339 of file policy_define.c.

References id_queue, pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_compute_type int  which  ) 
 

Definition at line 1319 of file policy_define.c.

References append_avrule(), avrule_destroy(), define_compute_type_helper(), id_queue, insert_check_type_rule(), num_rules, pass, policydbp, and queue_remove().

Referenced by yyparse().

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 }

int define_conditional cond_expr_t *  expr,
avrule_t *  t_list,
avrule_t *  f_list
 

Definition at line 2487 of file policy_define.c.

References append_cond_list(), avrule_destroy(), define_cond_expr(), get_current_cond_list(), insert_check_type_rule(), policydbp, and yyerror().

Referenced by yyparse().

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 }

int define_constraint constraint_expr_t *  expr  ) 
 

Definition at line 2116 of file policy_define.c.

References constraint_expr_clone(), id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), TRUE, yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_dominance void   ) 
 

Definition at line 663 of file policy_define.c.

References id_queue, pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_fs_context unsigned int  major,
unsigned int  minor
 

Definition at line 3213 of file policy_define.c.

References val_to_name::name, parse_security_context(), pass, policydbp, yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_fs_use int  behavior  ) 
 

Definition at line 3567 of file policy_define.c.

References id_queue, val_to_name::name, parse_security_context(), pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_genfs_context int  has_type  ) 
 

Definition at line 3737 of file policy_define.c.

References define_genfs_context_helper(), id_queue, and queue_remove().

Referenced by yyparse().

03738 {
03739         return define_genfs_context_helper(queue_remove(id_queue), has_type);
03740 }

int define_initial_sid_context void   ) 
 

Definition at line 3171 of file policy_define.c.

References id_queue, parse_security_context(), pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_initial_sid void   ) 
 

Definition at line 288 of file policy_define.c.

References id_queue, pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_ipv4_node_context void   ) 
 

Definition at line 3403 of file policy_define.c.

References id_queue, parse_security_context(), pass, policydbp, queue_remove(), and yyerror().

Referenced by yyparse().

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 }

int define_ipv6_node_context void   ) 
 

Definition at line 3484 of file policy_define.c.

References id_queue, parse_security_context(), pass, policydbp, queue_remove(), and yyerror().

Referenced by yyparse().

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 }

int define_level void   ) 
 

Definition at line 845 of file policy_define.c.

References clone_level(), id_has_dot(), id_queue, pass, policydbp, queue_remove(), TRUE, yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_mls void   ) 
 

Definition at line 107 of file policy_define.c.

References mlspol, and policydbp.

Referenced by yyparse().

00108 {
00109         mlspol = 1;
00110         policydbp->mls = 1;
00111 
00112         return 0;
00113 }

int define_netif_context void   ) 
 

Definition at line 3351 of file policy_define.c.

References id_queue, val_to_name::name, parse_security_context(), pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_polcap void   ) 
 

Definition at line 247 of file policy_define.c.

References id_queue, pass, policydbp, queue_remove(), TRUE, yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_port_context unsigned int  low,
unsigned int  high
 

Definition at line 3268 of file policy_define.c.

References id_queue, parse_security_context(), pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_range_trans int  class_specified  ) 
 

Definition at line 3742 of file policy_define.c.

References append_range_trans(), id_queue, is_id_in_scope(), parse_semantic_categories(), pass, policydbp, queue_remove(), set_types(), TRUE, yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_role_allow void   ) 
 

Definition at line 2041 of file policy_define.c.

References append_role_allow(), id_queue, pass, queue_remove(), set_roles(), and yyerror().

Referenced by yyparse().

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 }

int define_role_trans void   ) 
 

Definition at line 1929 of file policy_define.c.

References append_role_trans(), id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), role_val_to_name(), set_roles(), set_types(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_role_types void   ) 
 

Definition at line 1664 of file policy_define.c.

References declare_role(), id_queue, pass, queue_remove(), and set_types().

Referenced by yyparse().

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 }

int define_sens void   ) 
 

Definition at line 533 of file policy_define.c.

References declare_symbol(), id_has_dot(), id_queue, level, pass, queue_remove(), and yyerror().

Referenced by yyparse().

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 }

int define_te_avtab int  which  ) 
 

Definition at line 1640 of file policy_define.c.

References append_avrule(), define_te_avtab_helper(), id_queue, num_rules, pass, and queue_remove().

Referenced by yyparse().

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 }

int define_typealias void   ) 
 

Definition at line 1001 of file policy_define.c.

References add_aliases_to_type(), id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_typeattribute void   ) 
 

Definition at line 1033 of file policy_define.c.

References get_local_type(), id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), TRUE, yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_type int  alias  ) 
 

Definition at line 1097 of file policy_define.c.

References add_aliases_to_type(), declare_type(), FALSE, get_local_type(), id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), TRUE, yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_user void   ) 
 

Definition at line 2914 of file policy_define.c.

References declare_user(), id_queue, parse_semantic_categories(), pass, policydbp, queue_remove(), set_user_roles(), yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int define_validatetrans constraint_expr_t *  expr  ) 
 

Definition at line 2252 of file policy_define.c.

References constraint_expr_clone(), id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), TRUE, yyerror(), and yyerror2().

Referenced by yyparse().

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 }

int insert_id char *  id,
int  push
 

Definition at line 156 of file policy_define.c.

References id_queue, queue_element_t, queue_insert(), queue_push(), and yyerror().

Referenced by yyparse().

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 }

int insert_separator int  push  ) 
 

Definition at line 140 of file policy_define.c.

References id_queue, queue_insert(), queue_push(), and yyerror().

Referenced by yyparse().

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 }

role_datum_t* define_role_dom role_datum_t *  r  ) 
 

Definition at line 1767 of file policy_define.c.

References declare_symbol(), dominate_role_recheck(), id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), TRUE, yyerror(), yyerror2(), and yywarn().

Referenced by yyparse().

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 }

role_datum_t* merge_roles_dom role_datum_t *  r1,
role_datum_t *  r2
 

Definition at line 1687 of file policy_define.c.

References pass, and yyerror().

Referenced by yyparse().

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 }

uintptr_t define_cexpr uint32_t  expr_type,
uintptr_t  arg1,
uintptr_t  arg2
 

Definition at line 2349 of file policy_define.c.

References id_queue, is_id_in_scope(), pass, policydbp, queue_remove(), set_types(), TRUE, yyerror(), and yyerror2().

Referenced by yyparse().

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 }