1 /* 2 * Copyright 2011 Tresys Technology, LLC. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * The views and conclusions contained in the software and documentation are those 26 * of the authors and should not be interpreted as representing official policies, 27 * either expressed or implied, of Tresys Technology, LLC. 28 */ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <string.h> 33 #include <ctype.h> 34 35 #include <sepol/policydb/conditional.h> 36 37 #include "cil_internal.h" 38 #include "cil_flavor.h" 39 #include "cil_log.h" 40 #include "cil_mem.h" 41 #include "cil_tree.h" 42 #include "cil_list.h" 43 #include "cil_parser.h" 44 #include "cil_build_ast.h" 45 #include "cil_copy_ast.h" 46 #include "cil_verify.h" 47 #include "cil_strpool.h" 48 49 struct cil_args_build { 50 struct cil_tree_node *ast; 51 struct cil_db *db; 52 struct cil_tree_node *macro; 53 struct cil_tree_node *boolif; 54 struct cil_tree_node *tunif; 55 struct cil_tree_node *in; 56 }; 57 58 int cil_fill_list(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **list) 59 { 60 int rc = SEPOL_ERR; 61 struct cil_tree_node *curr; 62 enum cil_syntax syntax[] = { 63 CIL_SYN_N_STRINGS, 64 CIL_SYN_END 65 }; 66 int syntax_len = sizeof(syntax)/sizeof(*syntax); 67 68 rc = __cil_verify_syntax(current, syntax, syntax_len); 69 if (rc != SEPOL_OK) { 70 goto exit; 71 } 72 73 cil_list_init(list, flavor); 74 75 for (curr = current; curr != NULL; curr = curr->next) { 76 cil_list_append(*list, CIL_STRING, curr->data); 77 } 78 79 return SEPOL_OK; 80 81 exit: 82 return rc; 83 } 84 85 /* 86 * Determine whether or not multiple declarations of the same key can share a 87 * datum, given the new datum and the one already present in a given symtab. 88 */ 89 int cil_is_datum_multiple_decl(__attribute__((unused)) struct cil_symtab_datum *cur, 90 __attribute__((unused)) struct cil_symtab_datum *old, 91 enum cil_flavor f) 92 { 93 int rc = CIL_FALSE; 94 95 switch (f) { 96 case CIL_TYPE: 97 case CIL_TYPEATTRIBUTE: 98 /* type and typeattribute statements insert empty datums, ret true */ 99 rc = CIL_TRUE; 100 break; 101 default: 102 break; 103 } 104 return rc; 105 } 106 107 int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor) 108 { 109 int rc = SEPOL_ERR; 110 symtab_t *symtab = NULL; 111 struct cil_symtab_datum *prev; 112 113 rc = __cil_verify_name((const char*)key); 114 if (rc != SEPOL_OK) { 115 goto exit; 116 } 117 118 rc = cil_get_symtab(ast_node->parent, &symtab, sflavor); 119 if (rc != SEPOL_OK) { 120 goto exit; 121 } 122 123 ast_node->data = datum; 124 ast_node->flavor = nflavor; 125 126 if (symtab != NULL) { 127 rc = cil_symtab_insert(symtab, (hashtab_key_t)key, datum, ast_node); 128 if (rc == SEPOL_EEXIST) { 129 if (!db->multiple_decls || 130 cil_symtab_get_datum(symtab, (hashtab_key_t)key, &prev) != SEPOL_OK || 131 !cil_is_datum_multiple_decl(datum, prev, nflavor)) { 132 133 /* multiple_decls not ok, ret error */ 134 cil_log(CIL_ERR, "Re-declaration of %s %s\n", 135 cil_node_to_string(ast_node), key); 136 if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) { 137 if (sflavor == CIL_SYM_BLOCKS) { 138 struct cil_tree_node *node = datum->nodes->head->data; 139 cil_tree_log(node, CIL_ERR, "Previous declaration"); 140 } 141 } 142 goto exit; 143 } 144 /* multiple_decls is enabled and works for this datum type, add node */ 145 cil_list_append(prev->nodes, CIL_NODE, ast_node); 146 ast_node->data = prev; 147 cil_symtab_datum_destroy(datum); 148 free(datum); 149 } 150 } 151 152 if (ast_node->flavor >= CIL_MIN_DECLARATIVE && ast_node->parent->flavor == CIL_MACRO) { 153 struct cil_list_item *item; 154 struct cil_list *param_list = ((struct cil_macro*)ast_node->parent->data)->params; 155 if (param_list != NULL) { 156 cil_list_for_each(item, param_list) { 157 struct cil_param *param = item->data; 158 if (param->flavor == ast_node->flavor) { 159 if (param->str == key) { 160 cil_log(CIL_ERR, "%s %s shadows a macro parameter in macro declaration\n", cil_node_to_string(ast_node), key); 161 rc = SEPOL_ERR; 162 goto exit; 163 } 164 } 165 } 166 } 167 } 168 169 return SEPOL_OK; 170 171 exit: 172 cil_log(CIL_ERR, "Failed to create node\n"); 173 return rc; 174 } 175 176 void cil_clear_node(struct cil_tree_node *ast_node) 177 { 178 if (ast_node == NULL) { 179 return; 180 } 181 182 ast_node->data = NULL; 183 ast_node->flavor = CIL_NONE; 184 } 185 186 int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint16_t is_abstract) 187 { 188 enum cil_syntax syntax[] = { 189 CIL_SYN_STRING, 190 CIL_SYN_STRING, 191 CIL_SYN_N_LISTS | CIL_SYN_END, 192 CIL_SYN_END 193 }; 194 int syntax_len = sizeof(syntax)/sizeof(*syntax); 195 char *key = NULL; 196 struct cil_block *block = NULL; 197 int rc = SEPOL_ERR; 198 199 if (db == NULL || parse_current == NULL || ast_node == NULL) { 200 goto exit; 201 } 202 203 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 204 if (rc != SEPOL_OK) { 205 goto exit; 206 } 207 208 cil_block_init(&block); 209 210 block->is_abstract = is_abstract; 211 212 key = parse_current->next->data; 213 214 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)block, (hashtab_key_t)key, CIL_SYM_BLOCKS, CIL_BLOCK); 215 if (rc != SEPOL_OK) { 216 goto exit; 217 } 218 219 return SEPOL_OK; 220 221 exit: 222 cil_tree_log(parse_current, CIL_ERR, "Bad block declaration"); 223 cil_destroy_block(block); 224 cil_clear_node(ast_node); 225 return rc; 226 } 227 228 void cil_destroy_block(struct cil_block *block) 229 { 230 if (block == NULL) { 231 return; 232 } 233 234 cil_symtab_datum_destroy(&block->datum); 235 cil_symtab_array_destroy(block->symtab); 236 cil_list_destroy(&block->bi_nodes, CIL_FALSE); 237 238 free(block); 239 } 240 241 int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 242 { 243 enum cil_syntax syntax[] = { 244 CIL_SYN_STRING, 245 CIL_SYN_STRING, 246 CIL_SYN_END 247 }; 248 int syntax_len = sizeof(syntax)/sizeof(*syntax); 249 struct cil_blockinherit *inherit = NULL; 250 int rc = SEPOL_ERR; 251 252 if (db == NULL || parse_current == NULL || ast_node == NULL) { 253 goto exit; 254 } 255 256 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 257 if (rc != SEPOL_OK) { 258 goto exit; 259 } 260 261 cil_blockinherit_init(&inherit); 262 263 inherit->block_str = parse_current->next->data; 264 265 ast_node->data = inherit; 266 ast_node->flavor = CIL_BLOCKINHERIT; 267 268 return SEPOL_OK; 269 270 exit: 271 cil_tree_log(parse_current, CIL_ERR, "Bad blockinherit declaration"); 272 cil_destroy_blockinherit(inherit); 273 return rc; 274 } 275 276 void cil_destroy_blockinherit(struct cil_blockinherit *inherit) 277 { 278 if (inherit == NULL) { 279 return; 280 } 281 282 free(inherit); 283 } 284 285 int cil_gen_blockabstract(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 286 { 287 enum cil_syntax syntax[] = { 288 CIL_SYN_STRING, 289 CIL_SYN_STRING, 290 CIL_SYN_END 291 }; 292 int syntax_len = sizeof(syntax)/sizeof(*syntax); 293 struct cil_blockabstract *abstract = NULL; 294 int rc = SEPOL_ERR; 295 296 if (db == NULL || parse_current == NULL || ast_node == NULL) { 297 goto exit; 298 } 299 300 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 301 if (rc != SEPOL_OK) { 302 goto exit; 303 } 304 305 cil_blockabstract_init(&abstract); 306 307 abstract->block_str = parse_current->next->data; 308 309 ast_node->data = abstract; 310 ast_node->flavor = CIL_BLOCKABSTRACT; 311 312 return SEPOL_OK; 313 314 exit: 315 cil_tree_log(parse_current, CIL_ERR, "Bad blockabstract declaration"); 316 cil_destroy_blockabstract(abstract); 317 return rc; 318 } 319 320 void cil_destroy_blockabstract(struct cil_blockabstract *abstract) 321 { 322 if (abstract == NULL) { 323 return; 324 } 325 326 free(abstract); 327 } 328 329 int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 330 { 331 enum cil_syntax syntax[] = { 332 CIL_SYN_STRING, 333 CIL_SYN_STRING, 334 CIL_SYN_N_LISTS, 335 CIL_SYN_END 336 }; 337 int syntax_len = sizeof(syntax)/sizeof(*syntax); 338 int rc = SEPOL_ERR; 339 struct cil_in *in = NULL; 340 341 if (db == NULL || parse_current == NULL || ast_node == NULL) { 342 goto exit; 343 } 344 345 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 346 if (rc != SEPOL_OK) { 347 goto exit; 348 } 349 350 cil_in_init(&in); 351 352 in->block_str = parse_current->next->data; 353 354 ast_node->data = in; 355 ast_node->flavor = CIL_IN; 356 357 return SEPOL_OK; 358 exit: 359 cil_tree_log(parse_current, CIL_ERR, "Bad in statement"); 360 cil_destroy_in(in); 361 return rc; 362 } 363 364 void cil_destroy_in(struct cil_in *in) 365 { 366 if (in == NULL) { 367 return; 368 } 369 370 cil_symtab_array_destroy(in->symtab); 371 372 free(in); 373 } 374 375 int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 376 { 377 enum cil_syntax syntax[] = { 378 CIL_SYN_STRING, 379 CIL_SYN_STRING, 380 CIL_SYN_LIST | CIL_SYN_EMPTY_LIST, 381 CIL_SYN_END 382 }; 383 int syntax_len = sizeof(syntax)/sizeof(*syntax); 384 char *key = NULL; 385 struct cil_class *class = NULL; 386 struct cil_tree_node *perms = NULL; 387 int rc = SEPOL_ERR; 388 389 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 390 if (rc != SEPOL_OK) { 391 goto exit; 392 } 393 394 cil_class_init(&class); 395 396 key = parse_current->next->data; 397 if (key == CIL_KEY_UNORDERED) { 398 cil_log(CIL_ERR, "'unordered' keyword is reserved and not a valid class name.\n"); 399 rc = SEPOL_ERR; 400 goto exit; 401 } 402 403 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)class, (hashtab_key_t)key, CIL_SYM_CLASSES, CIL_CLASS); 404 if (rc != SEPOL_OK) { 405 goto exit; 406 } 407 408 if (parse_current->next->next != NULL) { 409 perms = parse_current->next->next->cl_head; 410 rc = cil_gen_perm_nodes(db, perms, ast_node, CIL_PERM, &class->num_perms); 411 if (rc != SEPOL_OK) { 412 goto exit; 413 } 414 if (class->num_perms > CIL_PERMS_PER_CLASS) { 415 cil_tree_log(parse_current, CIL_ERR, "Too many permissions in class '%s'", class->datum.name); 416 goto exit; 417 } 418 419 } 420 421 return SEPOL_OK; 422 423 exit: 424 cil_tree_log(parse_current, CIL_ERR, "Bad class declaration"); 425 cil_destroy_class(class); 426 cil_clear_node(ast_node); 427 return rc; 428 } 429 430 void cil_destroy_class(struct cil_class *class) 431 { 432 if (class == NULL) { 433 return; 434 } 435 436 cil_symtab_datum_destroy(&class->datum); 437 cil_symtab_destroy(&class->perms); 438 439 free(class); 440 } 441 442 int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 443 { 444 enum cil_syntax syntax[] = { 445 CIL_SYN_STRING, 446 CIL_SYN_LIST, 447 CIL_SYN_END 448 }; 449 int syntax_len = sizeof(syntax)/sizeof(*syntax); 450 struct cil_classorder *classorder = NULL; 451 struct cil_list_item *curr = NULL; 452 struct cil_list_item *head = NULL; 453 int rc = SEPOL_ERR; 454 455 if (db == NULL || parse_current == NULL || ast_node == NULL) { 456 goto exit; 457 } 458 459 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 460 if (rc != SEPOL_OK) { 461 goto exit; 462 } 463 464 cil_classorder_init(&classorder); 465 466 rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASSORDER, &classorder->class_list_str); 467 if (rc != SEPOL_OK) { 468 goto exit; 469 } 470 471 head = classorder->class_list_str->head; 472 cil_list_for_each(curr, classorder->class_list_str) { 473 if (curr->data == CIL_KEY_UNORDERED) { 474 if (curr == head && curr->next == NULL) { 475 cil_log(CIL_ERR, "Classorder 'unordered' keyword must be followed by one or more class.\n"); 476 rc = SEPOL_ERR; 477 goto exit; 478 } else if (curr != head) { 479 cil_log(CIL_ERR, "Classorder can only use 'unordered' keyword as the first item in the list.\n"); 480 rc = SEPOL_ERR; 481 goto exit; 482 } 483 } 484 } 485 486 ast_node->data = classorder; 487 ast_node->flavor = CIL_CLASSORDER; 488 489 return SEPOL_OK; 490 491 exit: 492 cil_tree_log(parse_current, CIL_ERR, "Bad classorder declaration"); 493 cil_destroy_classorder(classorder); 494 return rc; 495 } 496 497 void cil_destroy_classorder(struct cil_classorder *classorder) 498 { 499 if (classorder == NULL) { 500 return; 501 } 502 503 if (classorder->class_list_str != NULL) { 504 cil_list_destroy(&classorder->class_list_str, 1); 505 } 506 507 free(classorder); 508 } 509 510 int cil_gen_perm(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms) 511 { 512 char *key = NULL; 513 struct cil_perm *perm = NULL; 514 int rc = SEPOL_ERR; 515 516 cil_perm_init(&perm); 517 518 key = parse_current->data; 519 if (key == NULL) { 520 cil_log(CIL_ERR, "Bad permission\n"); 521 goto exit; 522 } 523 524 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)perm, (hashtab_key_t)key, CIL_SYM_PERMS, flavor); 525 if (rc != SEPOL_OK) { 526 goto exit; 527 } 528 529 perm->value = *num_perms; 530 (*num_perms)++; 531 532 return SEPOL_OK; 533 534 exit: 535 cil_destroy_perm(perm); 536 cil_clear_node(ast_node); 537 return rc; 538 } 539 540 void cil_destroy_perm(struct cil_perm *perm) 541 { 542 if (perm == NULL) { 543 return; 544 } 545 546 cil_symtab_datum_destroy(&perm->datum); 547 cil_list_destroy(&perm->classperms, CIL_FALSE); 548 549 free(perm); 550 } 551 552 int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms) 553 { 554 int rc = SEPOL_ERR; 555 struct cil_tree_node *new_ast = NULL; 556 557 while(current_perm != NULL) { 558 if (current_perm->cl_head != NULL) { 559 560 rc = SEPOL_ERR; 561 goto exit; 562 } 563 cil_tree_node_init(&new_ast); 564 new_ast->parent = ast_node; 565 new_ast->line = current_perm->line; 566 new_ast->hll_line = current_perm->hll_line; 567 568 rc = cil_gen_perm(db, current_perm, new_ast, flavor, num_perms); 569 if (rc != SEPOL_OK) { 570 cil_tree_node_destroy(&new_ast); 571 goto exit; 572 } 573 574 if (ast_node->cl_head == NULL) { 575 ast_node->cl_head = new_ast; 576 } else { 577 ast_node->cl_tail->next = new_ast; 578 } 579 ast_node->cl_tail = new_ast; 580 581 current_perm = current_perm->next; 582 } 583 584 return SEPOL_OK; 585 586 exit: 587 cil_log(CIL_ERR, "Bad permissions\n"); 588 cil_tree_children_destroy(ast_node); 589 cil_clear_node(ast_node); 590 return rc; 591 } 592 593 int cil_fill_perms(struct cil_tree_node *start_perm, struct cil_list **perms) 594 { 595 int rc = SEPOL_ERR; 596 enum cil_syntax syntax[] = { 597 CIL_SYN_N_STRINGS | CIL_SYN_N_LISTS, 598 CIL_SYN_END 599 }; 600 int syntax_len = sizeof(syntax)/sizeof(*syntax); 601 602 rc = __cil_verify_syntax(start_perm->cl_head, syntax, syntax_len); 603 if (rc != SEPOL_OK) { 604 goto exit; 605 } 606 607 rc = cil_gen_expr(start_perm, CIL_PERM, perms); 608 if (rc != SEPOL_OK) { 609 goto exit; 610 } 611 612 return SEPOL_OK; 613 614 exit: 615 cil_log(CIL_ERR, "Bad permission list or expression\n"); 616 return rc; 617 } 618 619 int cil_fill_classperms(struct cil_tree_node *parse_current, struct cil_classperms **cp) 620 { 621 int rc = SEPOL_ERR; 622 enum cil_syntax syntax[] = { 623 CIL_SYN_STRING, 624 CIL_SYN_LIST, 625 CIL_SYN_END 626 }; 627 int syntax_len = sizeof(syntax)/sizeof(*syntax); 628 629 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 630 if (rc != SEPOL_OK) { 631 goto exit; 632 } 633 634 cil_classperms_init(cp); 635 636 (*cp)->class_str = parse_current->data; 637 638 rc = cil_fill_perms(parse_current->next, &(*cp)->perm_strs); 639 if (rc != SEPOL_OK) { 640 cil_destroy_classperms(*cp); 641 goto exit; 642 } 643 644 return SEPOL_OK; 645 646 exit: 647 cil_log(CIL_ERR, "Bad class-permissions\n"); 648 *cp = NULL; 649 return rc; 650 } 651 652 void cil_destroy_classperms(struct cil_classperms *cp) 653 { 654 if (cp == NULL) { 655 return; 656 } 657 658 cil_list_destroy(&cp->perm_strs, CIL_TRUE); 659 cil_list_destroy(&cp->perms, CIL_FALSE); 660 661 free(cp); 662 } 663 664 void cil_fill_classperms_set(struct cil_tree_node *parse_current, struct cil_classperms_set **cp_set) 665 { 666 cil_classperms_set_init(cp_set); 667 (*cp_set)->set_str = parse_current->data; 668 } 669 670 void cil_destroy_classperms_set(struct cil_classperms_set *cp_set) 671 { 672 if (cp_set == NULL) { 673 return; 674 } 675 676 free(cp_set); 677 } 678 679 int cil_fill_classperms_list(struct cil_tree_node *parse_current, struct cil_list **cp_list) 680 { 681 int rc = SEPOL_ERR; 682 struct cil_tree_node *curr; 683 enum cil_syntax syntax[] = { 684 CIL_SYN_STRING | CIL_SYN_LIST, 685 }; 686 int syntax_len = sizeof(syntax)/sizeof(*syntax); 687 688 if (parse_current == NULL || cp_list == NULL) { 689 goto exit; 690 } 691 692 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 693 if (rc != SEPOL_OK) { 694 goto exit; 695 } 696 697 cil_list_init(cp_list, CIL_CLASSPERMS); 698 699 curr = parse_current->cl_head; 700 701 if (curr == NULL) { 702 /* Class-perms form: SET1 */ 703 struct cil_classperms_set *new_cp_set; 704 cil_fill_classperms_set(parse_current, &new_cp_set); 705 cil_list_append(*cp_list, CIL_CLASSPERMS_SET, new_cp_set); 706 } else if (curr->cl_head == NULL) { 707 /* Class-perms form: (CLASS1 (PERM1 ...)) */ 708 struct cil_classperms *new_cp; 709 rc = cil_fill_classperms(curr, &new_cp); 710 if (rc != SEPOL_OK) { 711 goto exit; 712 } 713 cil_list_append(*cp_list, CIL_CLASSPERMS, new_cp); 714 } else { 715 cil_log(CIL_ERR, "Bad class-permissions list syntax\n"); 716 rc = SEPOL_ERR; 717 goto exit; 718 } 719 720 return SEPOL_OK; 721 722 exit: 723 cil_log(CIL_ERR, "Problem filling class-permissions list\n"); 724 cil_list_destroy(cp_list, CIL_TRUE); 725 return rc; 726 } 727 728 void cil_destroy_classperms_list(struct cil_list **cp_list) 729 { 730 struct cil_list_item *curr; 731 732 if (cp_list == NULL || *cp_list == NULL) { 733 return; 734 } 735 736 cil_list_for_each(curr, *cp_list) { 737 if (curr->flavor == CIL_CLASSPERMS) { 738 cil_destroy_classperms(curr->data); 739 } else { 740 cil_destroy_classperms_set(curr->data); 741 } 742 } 743 744 cil_list_destroy(cp_list, CIL_FALSE); 745 } 746 747 int cil_gen_classpermission(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 748 { 749 int rc = SEPOL_ERR; 750 char *key = NULL; 751 struct cil_classpermission *cp = NULL; 752 enum cil_syntax syntax[] = { 753 CIL_SYN_STRING, 754 CIL_SYN_STRING, 755 CIL_SYN_END 756 }; 757 int syntax_len = sizeof(syntax)/sizeof(*syntax); 758 759 if (db == NULL || parse_current == NULL || ast_node == NULL) { 760 goto exit; 761 } 762 763 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 764 if (rc != SEPOL_OK) { 765 goto exit; 766 } 767 768 cil_classpermission_init(&cp); 769 770 key = parse_current->next->data; 771 772 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)cp, (hashtab_key_t)key, CIL_SYM_CLASSPERMSETS, CIL_CLASSPERMISSION); 773 if (rc != SEPOL_OK) { 774 goto exit; 775 } 776 777 return SEPOL_OK; 778 779 exit: 780 cil_tree_log(parse_current, CIL_ERR, "Bad classpermission declaration"); 781 cil_destroy_classpermission(cp); 782 cil_clear_node(ast_node); 783 return rc; 784 } 785 786 void cil_destroy_classpermission(struct cil_classpermission *cp) 787 { 788 if (cp == NULL) { 789 return; 790 } 791 792 if (cp->datum.name != NULL) { 793 cil_list_destroy(&cp->classperms, CIL_FALSE); 794 } else { 795 /* anonymous classpermission from call */ 796 cil_destroy_classperms_list(&cp->classperms); 797 } 798 799 cil_symtab_datum_destroy(&cp->datum); 800 801 802 free(cp); 803 } 804 805 int cil_gen_classpermissionset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 806 { 807 int rc = SEPOL_ERR; 808 struct cil_classpermissionset *cps = NULL; 809 enum cil_syntax syntax[] = { 810 CIL_SYN_STRING, 811 CIL_SYN_STRING, 812 CIL_SYN_STRING | CIL_SYN_LIST, 813 CIL_SYN_END 814 }; 815 int syntax_len = sizeof(syntax)/sizeof(*syntax); 816 817 if (db == NULL || parse_current == NULL || ast_node == NULL) { 818 goto exit; 819 } 820 821 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 822 if (rc != SEPOL_OK) { 823 goto exit; 824 } 825 826 cil_classpermissionset_init(&cps); 827 828 cps->set_str = parse_current->next->data; 829 830 rc = cil_fill_classperms_list(parse_current->next->next, &cps->classperms); 831 if (rc != SEPOL_OK) { 832 goto exit; 833 } 834 835 ast_node->data = cps; 836 ast_node->flavor = CIL_CLASSPERMISSIONSET; 837 838 return SEPOL_OK; 839 840 exit: 841 cil_tree_log(parse_current, CIL_ERR, "Bad classpermissionset"); 842 cil_destroy_classpermissionset(cps); 843 return rc; 844 } 845 846 void cil_destroy_classpermissionset(struct cil_classpermissionset *cps) 847 { 848 if (cps == NULL) { 849 return; 850 } 851 852 cil_destroy_classperms_list(&cps->classperms); 853 854 free(cps); 855 } 856 857 int cil_gen_map_class(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 858 { 859 enum cil_syntax syntax[] = { 860 CIL_SYN_STRING, 861 CIL_SYN_STRING, 862 CIL_SYN_LIST, 863 CIL_SYN_END 864 }; 865 int syntax_len = sizeof(syntax)/sizeof(*syntax); 866 char *key = NULL; 867 struct cil_class *map = NULL; 868 int rc = SEPOL_ERR; 869 870 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 871 if (rc != SEPOL_OK) { 872 goto exit; 873 } 874 875 cil_class_init(&map); 876 877 key = parse_current->next->data; 878 879 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)map, (hashtab_key_t)key, CIL_SYM_CLASSES, CIL_MAP_CLASS); 880 if (rc != SEPOL_OK) { 881 goto exit; 882 } 883 884 rc = cil_gen_perm_nodes(db, parse_current->next->next->cl_head, ast_node, CIL_MAP_PERM, &map->num_perms); 885 if (rc != SEPOL_OK) { 886 goto exit; 887 } 888 889 return SEPOL_OK; 890 891 exit: 892 cil_tree_log(parse_current, CIL_ERR, "Bad map class declaration"); 893 cil_destroy_class(map); 894 cil_clear_node(ast_node); 895 return rc; 896 } 897 898 int cil_gen_classmapping(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 899 { 900 int rc = SEPOL_ERR; 901 struct cil_classmapping *mapping = NULL; 902 enum cil_syntax syntax[] = { 903 CIL_SYN_STRING, 904 CIL_SYN_STRING, 905 CIL_SYN_STRING, 906 CIL_SYN_STRING | CIL_SYN_LIST, 907 CIL_SYN_END 908 }; 909 int syntax_len = sizeof(syntax)/sizeof(*syntax); 910 911 if (db == NULL || parse_current == NULL || ast_node == NULL) { 912 goto exit; 913 } 914 915 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 916 if (rc != SEPOL_OK) { 917 goto exit; 918 } 919 920 cil_classmapping_init(&mapping); 921 922 mapping->map_class_str = parse_current->next->data; 923 mapping->map_perm_str = parse_current->next->next->data; 924 925 rc = cil_fill_classperms_list(parse_current->next->next->next, &mapping->classperms); 926 if (rc != SEPOL_OK) { 927 goto exit; 928 } 929 930 ast_node->data = mapping; 931 ast_node->flavor = CIL_CLASSMAPPING; 932 933 return SEPOL_OK; 934 935 exit: 936 cil_tree_log(parse_current, CIL_ERR, "Bad classmapping declaration"); 937 cil_destroy_classmapping(mapping); 938 return rc; 939 } 940 941 void cil_destroy_classmapping(struct cil_classmapping *mapping) 942 { 943 if (mapping == NULL) { 944 return; 945 } 946 947 cil_destroy_classperms_list(&mapping->classperms); 948 949 free(mapping); 950 } 951 952 // TODO try to merge some of this with cil_gen_class (helper function for both) 953 int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 954 { 955 enum cil_syntax syntax[] = { 956 CIL_SYN_STRING, 957 CIL_SYN_STRING, 958 CIL_SYN_LIST, 959 CIL_SYN_END 960 }; 961 int syntax_len = sizeof(syntax)/sizeof(*syntax); 962 char *key = NULL; 963 struct cil_class *common = NULL; 964 int rc = SEPOL_ERR; 965 966 if (db == NULL || parse_current == NULL || ast_node == NULL) { 967 goto exit; 968 } 969 970 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 971 if (rc != SEPOL_OK) { 972 goto exit; 973 } 974 975 cil_class_init(&common); 976 977 key = parse_current->next->data; 978 979 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)common, (hashtab_key_t)key, CIL_SYM_COMMONS, CIL_COMMON); 980 if (rc != SEPOL_OK) { 981 goto exit; 982 } 983 984 rc = cil_gen_perm_nodes(db, parse_current->next->next->cl_head, ast_node, CIL_PERM, &common->num_perms); 985 if (rc != SEPOL_OK) { 986 goto exit; 987 } 988 if (common->num_perms > CIL_PERMS_PER_CLASS) { 989 cil_tree_log(parse_current, CIL_ERR, "Too many permissions in common '%s'", common->datum.name); 990 goto exit; 991 } 992 993 return SEPOL_OK; 994 995 exit: 996 cil_tree_log(parse_current, CIL_ERR, "Bad common declaration"); 997 cil_destroy_class(common); 998 cil_clear_node(ast_node); 999 return rc; 1000 1001 } 1002 1003 int cil_gen_classcommon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1004 { 1005 enum cil_syntax syntax[] = { 1006 CIL_SYN_STRING, 1007 CIL_SYN_STRING, 1008 CIL_SYN_STRING, 1009 CIL_SYN_END 1010 }; 1011 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1012 struct cil_classcommon *clscom = NULL; 1013 int rc = SEPOL_ERR; 1014 1015 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1016 goto exit; 1017 } 1018 1019 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1020 if (rc != SEPOL_OK) { 1021 goto exit; 1022 } 1023 1024 cil_classcommon_init(&clscom); 1025 1026 clscom->class_str = parse_current->next->data; 1027 clscom->common_str = parse_current->next->next->data; 1028 1029 ast_node->data = clscom; 1030 ast_node->flavor = CIL_CLASSCOMMON; 1031 1032 return SEPOL_OK; 1033 1034 exit: 1035 cil_tree_log(parse_current, CIL_ERR, "Bad classcommon declaration"); 1036 cil_destroy_classcommon(clscom); 1037 return rc; 1038 1039 } 1040 1041 void cil_destroy_classcommon(struct cil_classcommon *clscom) 1042 { 1043 if (clscom == NULL) { 1044 return; 1045 } 1046 1047 free(clscom); 1048 } 1049 1050 int cil_gen_sid(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1051 { 1052 enum cil_syntax syntax[] = { 1053 CIL_SYN_STRING, 1054 CIL_SYN_STRING, 1055 CIL_SYN_END 1056 }; 1057 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1058 char *key = NULL; 1059 struct cil_sid *sid = NULL; 1060 int rc = SEPOL_ERR; 1061 1062 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1063 goto exit; 1064 } 1065 1066 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1067 if (rc != SEPOL_OK) { 1068 goto exit; 1069 } 1070 1071 cil_sid_init(&sid); 1072 1073 key = parse_current->next->data; 1074 1075 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)sid, (hashtab_key_t)key, CIL_SYM_SIDS, CIL_SID); 1076 if (rc != SEPOL_OK) { 1077 goto exit; 1078 } 1079 1080 return SEPOL_OK; 1081 1082 exit: 1083 cil_tree_log(parse_current, CIL_ERR, "Bad sid declaration"); 1084 cil_destroy_sid(sid); 1085 cil_clear_node(ast_node); 1086 return rc; 1087 } 1088 1089 void cil_destroy_sid(struct cil_sid *sid) 1090 { 1091 if (sid == NULL) { 1092 return; 1093 } 1094 1095 cil_symtab_datum_destroy(&sid->datum); 1096 free(sid); 1097 } 1098 1099 int cil_gen_sidcontext(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1100 { 1101 enum cil_syntax syntax[] = { 1102 CIL_SYN_STRING, 1103 CIL_SYN_STRING, 1104 CIL_SYN_STRING | CIL_SYN_LIST, 1105 CIL_SYN_END 1106 }; 1107 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1108 struct cil_sidcontext *sidcon = NULL; 1109 int rc = SEPOL_ERR; 1110 1111 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1112 goto exit; 1113 } 1114 1115 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1116 if (rc != SEPOL_OK) { 1117 goto exit; 1118 } 1119 1120 cil_sidcontext_init(&sidcon); 1121 1122 sidcon->sid_str = parse_current->next->data; 1123 1124 if (parse_current->next->next->cl_head == NULL) { 1125 sidcon->context_str = parse_current->next->next->data; 1126 } else { 1127 cil_context_init(&sidcon->context); 1128 1129 rc = cil_fill_context(parse_current->next->next->cl_head, sidcon->context); 1130 if (rc != SEPOL_OK) { 1131 goto exit; 1132 } 1133 } 1134 1135 ast_node->data = sidcon; 1136 ast_node->flavor = CIL_SIDCONTEXT; 1137 1138 return SEPOL_OK; 1139 1140 exit: 1141 cil_tree_log(parse_current, CIL_ERR, "Bad sidcontext declaration"); 1142 cil_destroy_sidcontext(sidcon); 1143 return rc; 1144 } 1145 1146 void cil_destroy_sidcontext(struct cil_sidcontext *sidcon) 1147 { 1148 if (sidcon == NULL) { 1149 return; 1150 } 1151 1152 if (sidcon->context_str == NULL && sidcon->context != NULL) { 1153 cil_destroy_context(sidcon->context); 1154 } 1155 1156 free(sidcon); 1157 } 1158 1159 int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1160 { 1161 enum cil_syntax syntax[] = { 1162 CIL_SYN_STRING, 1163 CIL_SYN_LIST, 1164 CIL_SYN_END 1165 }; 1166 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1167 struct cil_sidorder *sidorder = NULL; 1168 struct cil_list_item *curr = NULL; 1169 int rc = SEPOL_ERR; 1170 1171 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1172 goto exit; 1173 } 1174 1175 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1176 if (rc != SEPOL_OK) { 1177 goto exit; 1178 } 1179 1180 cil_sidorder_init(&sidorder); 1181 1182 rc = cil_fill_list(parse_current->next->cl_head, CIL_SIDORDER, &sidorder->sid_list_str); 1183 if (rc != SEPOL_OK) { 1184 goto exit; 1185 } 1186 1187 cil_list_for_each(curr, sidorder->sid_list_str) { 1188 if (curr->data == CIL_KEY_UNORDERED) { 1189 cil_log(CIL_ERR, "Sidorder cannot be unordered.\n"); 1190 rc = SEPOL_ERR; 1191 goto exit; 1192 } 1193 } 1194 1195 ast_node->data = sidorder; 1196 ast_node->flavor = CIL_SIDORDER; 1197 1198 return SEPOL_OK; 1199 1200 exit: 1201 cil_tree_log(parse_current, CIL_ERR, "Bad sidorder declaration"); 1202 cil_destroy_sidorder(sidorder); 1203 return rc; 1204 } 1205 1206 void cil_destroy_sidorder(struct cil_sidorder *sidorder) 1207 { 1208 if (sidorder == NULL) { 1209 return; 1210 } 1211 1212 if (sidorder->sid_list_str != NULL) { 1213 cil_list_destroy(&sidorder->sid_list_str, 1); 1214 } 1215 1216 free(sidorder); 1217 } 1218 1219 int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1220 { 1221 enum cil_syntax syntax[] = { 1222 CIL_SYN_STRING, 1223 CIL_SYN_STRING, 1224 CIL_SYN_END 1225 }; 1226 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1227 char *key = NULL; 1228 struct cil_user *user = NULL; 1229 int rc = SEPOL_ERR; 1230 1231 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1232 goto exit; 1233 } 1234 1235 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1236 if (rc != SEPOL_OK) { 1237 goto exit; 1238 } 1239 1240 cil_user_init(&user); 1241 1242 key = parse_current->next->data; 1243 1244 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)user, (hashtab_key_t)key, CIL_SYM_USERS, CIL_USER); 1245 if (rc != SEPOL_OK) { 1246 goto exit; 1247 } 1248 1249 return SEPOL_OK; 1250 1251 exit: 1252 cil_tree_log(parse_current, CIL_ERR, "Bad user declaration"); 1253 cil_destroy_user(user); 1254 cil_clear_node(ast_node); 1255 return rc; 1256 } 1257 1258 void cil_destroy_user(struct cil_user *user) 1259 { 1260 if (user == NULL) { 1261 return; 1262 } 1263 1264 cil_symtab_datum_destroy(&user->datum); 1265 ebitmap_destroy(user->roles); 1266 free(user->roles); 1267 free(user); 1268 } 1269 1270 int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1271 { 1272 enum cil_syntax syntax[] = { 1273 CIL_SYN_STRING, 1274 CIL_SYN_STRING, 1275 CIL_SYN_END 1276 }; 1277 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1278 char *key = NULL; 1279 struct cil_userattribute *attr = NULL; 1280 int rc = SEPOL_ERR; 1281 1282 if (parse_current == NULL || ast_node == NULL) { 1283 goto exit; 1284 } 1285 1286 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1287 if (rc != SEPOL_OK) { 1288 goto exit; 1289 } 1290 1291 cil_userattribute_init(&attr); 1292 1293 key = parse_current->next->data; 1294 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)attr, (hashtab_key_t)key, CIL_SYM_USERS, CIL_USERATTRIBUTE); 1295 if (rc != SEPOL_OK) { 1296 goto exit; 1297 } 1298 1299 return SEPOL_OK; 1300 exit: 1301 cil_tree_log(parse_current, CIL_ERR, "Bad userattribute declaration"); 1302 cil_destroy_userattribute(attr); 1303 cil_clear_node(ast_node); 1304 return rc; 1305 } 1306 1307 void cil_destroy_userattribute(struct cil_userattribute *attr) 1308 { 1309 struct cil_list_item *expr = NULL; 1310 struct cil_list_item *next = NULL; 1311 1312 if (attr == NULL) { 1313 return; 1314 } 1315 1316 if (attr->expr_list != NULL) { 1317 /* we don't want to destroy the expression stacks (cil_list) inside 1318 * this list cil_list_destroy destroys sublists, so we need to do it 1319 * manually */ 1320 expr = attr->expr_list->head; 1321 while (expr != NULL) { 1322 next = expr->next; 1323 cil_list_item_destroy(&expr, CIL_FALSE); 1324 expr = next; 1325 } 1326 free(attr->expr_list); 1327 attr->expr_list = NULL; 1328 } 1329 1330 cil_symtab_datum_destroy(&attr->datum); 1331 ebitmap_destroy(attr->users); 1332 free(attr->users); 1333 free(attr); 1334 } 1335 1336 int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1337 { 1338 enum cil_syntax syntax[] = { 1339 CIL_SYN_STRING, 1340 CIL_SYN_STRING, 1341 CIL_SYN_STRING | CIL_SYN_LIST, 1342 CIL_SYN_END 1343 }; 1344 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1345 struct cil_userattributeset *attrset = NULL; 1346 int rc = SEPOL_ERR; 1347 1348 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1349 goto exit; 1350 } 1351 1352 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1353 if (rc != SEPOL_OK) { 1354 goto exit; 1355 } 1356 1357 cil_userattributeset_init(&attrset); 1358 1359 attrset->attr_str = parse_current->next->data; 1360 1361 rc = cil_gen_expr(parse_current->next->next, CIL_USER, &attrset->str_expr); 1362 if (rc != SEPOL_OK) { 1363 goto exit; 1364 } 1365 ast_node->data = attrset; 1366 ast_node->flavor = CIL_USERATTRIBUTESET; 1367 1368 return SEPOL_OK; 1369 1370 exit: 1371 cil_tree_log(parse_current, CIL_ERR, "Bad userattributeset declaration"); 1372 cil_destroy_userattributeset(attrset); 1373 1374 return rc; 1375 } 1376 1377 void cil_destroy_userattributeset(struct cil_userattributeset *attrset) 1378 { 1379 if (attrset == NULL) { 1380 return; 1381 } 1382 1383 cil_list_destroy(&attrset->str_expr, CIL_TRUE); 1384 cil_list_destroy(&attrset->datum_expr, CIL_FALSE); 1385 1386 free(attrset); 1387 } 1388 1389 int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1390 { 1391 enum cil_syntax syntax[] = { 1392 CIL_SYN_STRING, 1393 CIL_SYN_STRING, 1394 CIL_SYN_STRING | CIL_SYN_LIST, 1395 CIL_SYN_END 1396 }; 1397 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1398 struct cil_userlevel *usrlvl = NULL; 1399 int rc = SEPOL_ERR; 1400 1401 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1402 goto exit; 1403 } 1404 1405 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1406 if (rc != SEPOL_OK) { 1407 goto exit; 1408 } 1409 1410 cil_userlevel_init(&usrlvl); 1411 1412 usrlvl->user_str = parse_current->next->data; 1413 1414 if (parse_current->next->next->cl_head == NULL) { 1415 usrlvl->level_str = parse_current->next->next->data; 1416 } else { 1417 cil_level_init(&usrlvl->level); 1418 1419 rc = cil_fill_level(parse_current->next->next->cl_head, usrlvl->level); 1420 if (rc != SEPOL_OK) { 1421 goto exit; 1422 } 1423 } 1424 1425 ast_node->data = usrlvl; 1426 ast_node->flavor = CIL_USERLEVEL; 1427 1428 return SEPOL_OK; 1429 1430 exit: 1431 cil_tree_log(parse_current, CIL_ERR, "Bad userlevel declaration"); 1432 cil_destroy_userlevel(usrlvl); 1433 return rc; 1434 } 1435 1436 void cil_destroy_userlevel(struct cil_userlevel *usrlvl) 1437 { 1438 if (usrlvl == NULL) { 1439 return; 1440 } 1441 1442 if (usrlvl->level_str == NULL && usrlvl->level != NULL) { 1443 cil_destroy_level(usrlvl->level); 1444 } 1445 1446 free(usrlvl); 1447 } 1448 1449 int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1450 { 1451 enum cil_syntax syntax[] = { 1452 CIL_SYN_STRING, 1453 CIL_SYN_STRING, 1454 CIL_SYN_STRING | CIL_SYN_LIST, 1455 CIL_SYN_END 1456 }; 1457 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1458 struct cil_userrange *userrange = NULL; 1459 int rc = SEPOL_ERR; 1460 1461 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1462 goto exit; 1463 } 1464 1465 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1466 if (rc != SEPOL_OK) { 1467 goto exit; 1468 } 1469 1470 cil_userrange_init(&userrange); 1471 1472 userrange->user_str = parse_current->next->data; 1473 1474 if (parse_current->next->next->cl_head == NULL) { 1475 userrange->range_str = parse_current->next->next->data; 1476 } else { 1477 cil_levelrange_init(&userrange->range); 1478 1479 rc = cil_fill_levelrange(parse_current->next->next->cl_head, userrange->range); 1480 if (rc != SEPOL_OK) { 1481 goto exit; 1482 } 1483 } 1484 1485 ast_node->data = userrange; 1486 ast_node->flavor = CIL_USERRANGE; 1487 1488 return SEPOL_OK; 1489 1490 exit: 1491 cil_tree_log(parse_current, CIL_ERR, "Bad userrange declaration"); 1492 cil_destroy_userrange(userrange); 1493 return rc; 1494 } 1495 1496 void cil_destroy_userrange(struct cil_userrange *userrange) 1497 { 1498 if (userrange == NULL) { 1499 return; 1500 } 1501 1502 if (userrange->range_str == NULL && userrange->range != NULL) { 1503 cil_destroy_levelrange(userrange->range); 1504 } 1505 1506 free(userrange); 1507 } 1508 1509 int cil_gen_userprefix(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1510 { 1511 enum cil_syntax syntax[] = { 1512 CIL_SYN_STRING, 1513 CIL_SYN_STRING, 1514 CIL_SYN_STRING, 1515 CIL_SYN_END 1516 }; 1517 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1518 struct cil_userprefix *userprefix = NULL; 1519 int rc = SEPOL_ERR; 1520 1521 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1522 goto exit; 1523 } 1524 1525 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1526 if (rc != SEPOL_OK) { 1527 goto exit; 1528 } 1529 1530 cil_userprefix_init(&userprefix); 1531 1532 userprefix->user_str = parse_current->next->data; 1533 userprefix->prefix_str = parse_current->next->next->data; 1534 1535 ast_node->data = userprefix; 1536 ast_node->flavor = CIL_USERPREFIX; 1537 1538 return SEPOL_OK; 1539 exit: 1540 cil_tree_log(parse_current, CIL_ERR, "Bad userprefix declaration"); 1541 cil_destroy_userprefix(userprefix); 1542 return rc; 1543 } 1544 1545 void cil_destroy_userprefix(struct cil_userprefix *userprefix) 1546 { 1547 if (userprefix == NULL) { 1548 return; 1549 } 1550 1551 free(userprefix); 1552 } 1553 1554 int cil_gen_selinuxuser(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1555 { 1556 enum cil_syntax syntax[] = { 1557 CIL_SYN_STRING, 1558 CIL_SYN_STRING, 1559 CIL_SYN_STRING, 1560 CIL_SYN_STRING | CIL_SYN_LIST, 1561 CIL_SYN_END 1562 }; 1563 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1564 struct cil_selinuxuser *selinuxuser = NULL; 1565 int rc = SEPOL_ERR; 1566 1567 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1568 goto exit; 1569 } 1570 1571 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1572 if (rc != SEPOL_OK) { 1573 goto exit; 1574 } 1575 1576 cil_selinuxuser_init(&selinuxuser); 1577 1578 selinuxuser->name_str = parse_current->next->data; 1579 selinuxuser->user_str = parse_current->next->next->data; 1580 1581 if (parse_current->next->next->next->cl_head == NULL) { 1582 selinuxuser->range_str = parse_current->next->next->next->data; 1583 } else { 1584 cil_levelrange_init(&selinuxuser->range); 1585 1586 rc = cil_fill_levelrange(parse_current->next->next->next->cl_head, selinuxuser->range); 1587 if (rc != SEPOL_OK) { 1588 goto exit; 1589 } 1590 } 1591 1592 ast_node->data = selinuxuser; 1593 ast_node->flavor = CIL_SELINUXUSER; 1594 1595 return SEPOL_OK; 1596 exit: 1597 cil_tree_log(parse_current, CIL_ERR, "Bad selinuxuser declaration"); 1598 cil_destroy_selinuxuser(selinuxuser); 1599 return rc; 1600 } 1601 1602 int cil_gen_selinuxuserdefault(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1603 { 1604 enum cil_syntax syntax[] = { 1605 CIL_SYN_STRING, 1606 CIL_SYN_STRING, 1607 CIL_SYN_STRING | CIL_SYN_LIST, 1608 CIL_SYN_END 1609 }; 1610 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1611 struct cil_selinuxuser *selinuxuser = NULL; 1612 int rc = SEPOL_ERR; 1613 1614 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1615 goto exit; 1616 } 1617 1618 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1619 if (rc != SEPOL_OK) { 1620 goto exit; 1621 } 1622 1623 cil_selinuxuser_init(&selinuxuser); 1624 1625 selinuxuser->name_str = cil_strpool_add("__default__"); 1626 selinuxuser->user_str = parse_current->next->data; 1627 1628 if (parse_current->next->next->cl_head == NULL) { 1629 selinuxuser->range_str = parse_current->next->next->data; 1630 } else { 1631 cil_levelrange_init(&selinuxuser->range); 1632 1633 rc = cil_fill_levelrange(parse_current->next->next->cl_head, selinuxuser->range); 1634 if (rc != SEPOL_OK) { 1635 goto exit; 1636 } 1637 } 1638 1639 ast_node->data = selinuxuser; 1640 ast_node->flavor = CIL_SELINUXUSERDEFAULT; 1641 1642 return SEPOL_OK; 1643 exit: 1644 cil_tree_log(parse_current, CIL_ERR, "Bad selinuxuserdefault declaration"); 1645 cil_destroy_selinuxuser(selinuxuser); 1646 return rc; 1647 } 1648 1649 void cil_destroy_selinuxuser(struct cil_selinuxuser *selinuxuser) 1650 { 1651 if (selinuxuser == NULL) { 1652 return; 1653 } 1654 1655 if (selinuxuser->range_str == NULL && selinuxuser->range != NULL) { 1656 cil_destroy_levelrange(selinuxuser->range); 1657 } 1658 1659 free(selinuxuser); 1660 } 1661 1662 int cil_gen_role(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1663 { 1664 enum cil_syntax syntax[] = { 1665 CIL_SYN_STRING, 1666 CIL_SYN_STRING, 1667 CIL_SYN_END 1668 }; 1669 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1670 char *key = NULL; 1671 struct cil_role *role = NULL; 1672 int rc = SEPOL_ERR; 1673 1674 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1675 goto exit; 1676 } 1677 1678 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1679 if (rc != SEPOL_OK) { 1680 goto exit; 1681 } 1682 1683 cil_role_init(&role); 1684 1685 key = parse_current->next->data; 1686 1687 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)role, (hashtab_key_t)key, CIL_SYM_ROLES, CIL_ROLE); 1688 if (rc != SEPOL_OK) { 1689 goto exit; 1690 } 1691 1692 return SEPOL_OK; 1693 1694 exit: 1695 cil_tree_log(parse_current, CIL_ERR, "Bad role declaration"); 1696 cil_destroy_role(role); 1697 cil_clear_node(ast_node); 1698 return rc; 1699 } 1700 1701 void cil_destroy_role(struct cil_role *role) 1702 { 1703 if (role == NULL) { 1704 return; 1705 } 1706 1707 cil_symtab_datum_destroy(&role->datum); 1708 ebitmap_destroy(role->types); 1709 free(role->types); 1710 free(role); 1711 } 1712 1713 int cil_gen_roletype(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1714 { 1715 enum cil_syntax syntax[] = { 1716 CIL_SYN_STRING, 1717 CIL_SYN_STRING, 1718 CIL_SYN_STRING, 1719 CIL_SYN_END 1720 }; 1721 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1722 struct cil_roletype *roletype = NULL; 1723 int rc = SEPOL_ERR; 1724 1725 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1726 goto exit; 1727 } 1728 1729 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1730 if (rc != SEPOL_OK) { 1731 goto exit; 1732 } 1733 1734 cil_roletype_init(&roletype); 1735 1736 roletype->role_str = parse_current->next->data; 1737 roletype->type_str = parse_current->next->next->data; 1738 1739 ast_node->data = roletype; 1740 ast_node->flavor = CIL_ROLETYPE; 1741 1742 return SEPOL_OK; 1743 1744 exit: 1745 cil_tree_log(parse_current, CIL_ERR, "Bad roletype declaration"); 1746 cil_destroy_roletype(roletype); 1747 return rc; 1748 } 1749 1750 void cil_destroy_roletype(struct cil_roletype *roletype) 1751 { 1752 if (roletype == NULL) { 1753 return; 1754 } 1755 1756 free(roletype); 1757 } 1758 1759 int cil_gen_userrole(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1760 { 1761 enum cil_syntax syntax[] = { 1762 CIL_SYN_STRING, 1763 CIL_SYN_STRING, 1764 CIL_SYN_STRING, 1765 CIL_SYN_END 1766 }; 1767 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1768 struct cil_userrole *userrole = NULL; 1769 int rc = SEPOL_ERR; 1770 1771 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1772 goto exit; 1773 } 1774 1775 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1776 if (rc != SEPOL_OK) { 1777 goto exit; 1778 } 1779 1780 cil_userrole_init(&userrole); 1781 1782 userrole->user_str = parse_current->next->data; 1783 userrole->role_str = parse_current->next->next->data; 1784 1785 ast_node->data = userrole; 1786 ast_node->flavor = CIL_USERROLE; 1787 1788 return SEPOL_OK; 1789 1790 exit: 1791 cil_tree_log(parse_current, CIL_ERR, "Bad userrole declaration"); 1792 cil_destroy_userrole(userrole); 1793 return rc; 1794 } 1795 1796 void cil_destroy_userrole(struct cil_userrole *userrole) 1797 { 1798 if (userrole == NULL) { 1799 return; 1800 } 1801 1802 free(userrole); 1803 } 1804 1805 int cil_gen_roletransition(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1806 { 1807 enum cil_syntax syntax[] = { 1808 CIL_SYN_STRING, 1809 CIL_SYN_STRING, 1810 CIL_SYN_STRING, 1811 CIL_SYN_STRING, 1812 CIL_SYN_STRING, 1813 CIL_SYN_END 1814 }; 1815 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1816 struct cil_roletransition *roletrans = NULL; 1817 int rc = SEPOL_ERR; 1818 1819 if (parse_current == NULL || ast_node == NULL) { 1820 goto exit; 1821 } 1822 1823 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1824 if (rc != SEPOL_OK) { 1825 goto exit; 1826 } 1827 1828 cil_roletransition_init(&roletrans); 1829 1830 roletrans->src_str = parse_current->next->data; 1831 roletrans->tgt_str = parse_current->next->next->data; 1832 roletrans->obj_str = parse_current->next->next->next->data; 1833 roletrans->result_str = parse_current->next->next->next->next->data; 1834 1835 ast_node->data = roletrans; 1836 ast_node->flavor = CIL_ROLETRANSITION; 1837 1838 return SEPOL_OK; 1839 1840 exit: 1841 cil_tree_log(parse_current, CIL_ERR, "Bad roletransition rule"); 1842 cil_destroy_roletransition(roletrans); 1843 return rc; 1844 } 1845 1846 void cil_destroy_roletransition(struct cil_roletransition *roletrans) 1847 { 1848 if (roletrans == NULL) { 1849 return; 1850 } 1851 1852 free(roletrans); 1853 } 1854 1855 int cil_gen_roleallow(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1856 { 1857 enum cil_syntax syntax[] = { 1858 CIL_SYN_STRING, 1859 CIL_SYN_STRING, 1860 CIL_SYN_STRING, 1861 CIL_SYN_END 1862 }; 1863 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1864 struct cil_roleallow *roleallow = NULL; 1865 int rc = SEPOL_ERR; 1866 1867 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1868 goto exit; 1869 } 1870 1871 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1872 if (rc != SEPOL_OK) { 1873 goto exit; 1874 } 1875 1876 cil_roleallow_init(&roleallow); 1877 1878 roleallow->src_str = parse_current->next->data; 1879 roleallow->tgt_str = parse_current->next->next->data; 1880 1881 ast_node->data = roleallow; 1882 ast_node->flavor = CIL_ROLEALLOW; 1883 1884 return SEPOL_OK; 1885 1886 exit: 1887 cil_tree_log(parse_current, CIL_ERR, "Bad roleallow rule"); 1888 cil_destroy_roleallow(roleallow); 1889 return rc; 1890 } 1891 1892 void cil_destroy_roleallow(struct cil_roleallow *roleallow) 1893 { 1894 if (roleallow == NULL) { 1895 return; 1896 } 1897 1898 free(roleallow); 1899 } 1900 1901 int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1902 { 1903 enum cil_syntax syntax[] = { 1904 CIL_SYN_STRING, 1905 CIL_SYN_STRING, 1906 CIL_SYN_END 1907 }; 1908 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1909 char *key = NULL; 1910 struct cil_roleattribute *attr = NULL; 1911 int rc = SEPOL_ERR; 1912 1913 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1914 goto exit; 1915 } 1916 1917 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1918 if (rc != SEPOL_OK) { 1919 goto exit; 1920 } 1921 1922 if (parse_current->next->data == CIL_KEY_SELF) { 1923 cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); 1924 rc = SEPOL_ERR; 1925 goto exit; 1926 } 1927 1928 cil_roleattribute_init(&attr); 1929 1930 key = parse_current->next->data; 1931 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)attr, (hashtab_key_t)key, CIL_SYM_ROLES, CIL_ROLEATTRIBUTE); 1932 if (rc != SEPOL_OK) { 1933 goto exit; 1934 } 1935 1936 return SEPOL_OK; 1937 exit: 1938 cil_tree_log(parse_current, CIL_ERR, "Bad roleattribute declaration"); 1939 cil_destroy_roleattribute(attr); 1940 cil_clear_node(ast_node); 1941 return rc; 1942 } 1943 1944 void cil_destroy_roleattribute(struct cil_roleattribute *attr) 1945 { 1946 if (attr == NULL) { 1947 return; 1948 } 1949 1950 if (attr->expr_list != NULL) { 1951 /* we don't want to destroy the expression stacks (cil_list) inside 1952 * this list cil_list_destroy destroys sublists, so we need to do it 1953 * manually */ 1954 struct cil_list_item *expr = attr->expr_list->head; 1955 while (expr != NULL) { 1956 struct cil_list_item *next = expr->next; 1957 cil_list_item_destroy(&expr, CIL_FALSE); 1958 expr = next; 1959 } 1960 free(attr->expr_list); 1961 attr->expr_list = NULL; 1962 } 1963 1964 cil_symtab_datum_destroy(&attr->datum); 1965 ebitmap_destroy(attr->roles); 1966 free(attr->roles); 1967 free(attr); 1968 } 1969 1970 int cil_gen_roleattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 1971 { 1972 enum cil_syntax syntax[] = { 1973 CIL_SYN_STRING, 1974 CIL_SYN_STRING, 1975 CIL_SYN_STRING | CIL_SYN_LIST, 1976 CIL_SYN_END 1977 }; 1978 int syntax_len = sizeof(syntax)/sizeof(*syntax); 1979 struct cil_roleattributeset *attrset = NULL; 1980 int rc = SEPOL_ERR; 1981 1982 if (db == NULL || parse_current == NULL || ast_node == NULL) { 1983 goto exit; 1984 } 1985 1986 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 1987 if (rc != SEPOL_OK) { 1988 goto exit; 1989 } 1990 1991 cil_roleattributeset_init(&attrset); 1992 1993 attrset->attr_str = parse_current->next->data; 1994 1995 rc = cil_gen_expr(parse_current->next->next, CIL_ROLE, &attrset->str_expr); 1996 if (rc != SEPOL_OK) { 1997 goto exit; 1998 } 1999 ast_node->data = attrset; 2000 ast_node->flavor = CIL_ROLEATTRIBUTESET; 2001 2002 return SEPOL_OK; 2003 2004 exit: 2005 cil_tree_log(parse_current, CIL_ERR, "Bad roleattributeset declaration"); 2006 cil_destroy_roleattributeset(attrset); 2007 2008 return rc; 2009 } 2010 2011 void cil_destroy_roleattributeset(struct cil_roleattributeset *attrset) 2012 { 2013 if (attrset == NULL) { 2014 return; 2015 } 2016 2017 cil_list_destroy(&attrset->str_expr, CIL_TRUE); 2018 cil_list_destroy(&attrset->datum_expr, CIL_FALSE); 2019 2020 free(attrset); 2021 } 2022 2023 int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind) 2024 { 2025 enum cil_syntax syntax[] = { 2026 CIL_SYN_STRING, 2027 CIL_SYN_STRING, 2028 CIL_SYN_STRING, 2029 CIL_SYN_STRING | CIL_SYN_LIST, 2030 CIL_SYN_END 2031 }; 2032 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2033 struct cil_avrule *rule = NULL; 2034 int rc = SEPOL_ERR; 2035 2036 if (parse_current == NULL || ast_node == NULL) { 2037 goto exit; 2038 } 2039 2040 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2041 if (rc != SEPOL_OK) { 2042 goto exit; 2043 } 2044 2045 cil_avrule_init(&rule); 2046 2047 rule->is_extended = 0; 2048 rule->rule_kind = rule_kind; 2049 2050 rule->src_str = parse_current->next->data; 2051 rule->tgt_str = parse_current->next->next->data; 2052 2053 rc = cil_fill_classperms_list(parse_current->next->next->next, &rule->perms.classperms); 2054 if (rc != SEPOL_OK) { 2055 goto exit; 2056 } 2057 2058 ast_node->data = rule; 2059 ast_node->flavor = CIL_AVRULE; 2060 2061 return SEPOL_OK; 2062 2063 exit: 2064 cil_tree_log(parse_current, CIL_ERR, "Bad allow rule"); 2065 cil_destroy_avrule(rule); 2066 return rc; 2067 } 2068 2069 void cil_destroy_avrule(struct cil_avrule *rule) 2070 { 2071 if (rule == NULL) { 2072 return; 2073 } 2074 2075 if (!rule->is_extended) { 2076 cil_destroy_classperms_list(&rule->perms.classperms); 2077 } else { 2078 if (rule->perms.x.permx_str == NULL && rule->perms.x.permx != NULL) { 2079 cil_destroy_permissionx(rule->perms.x.permx); 2080 } 2081 } 2082 2083 free(rule); 2084 } 2085 2086 int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permissionx *permx) 2087 { 2088 enum cil_syntax syntax[] = { 2089 CIL_SYN_STRING, 2090 CIL_SYN_STRING, 2091 CIL_SYN_LIST, 2092 CIL_SYN_END 2093 }; 2094 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2095 int rc = SEPOL_ERR; 2096 2097 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2098 if (rc != SEPOL_OK) { 2099 goto exit; 2100 } 2101 2102 if (parse_current->data == CIL_KEY_IOCTL) { 2103 permx->kind = CIL_PERMX_KIND_IOCTL; 2104 } else { 2105 cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\"\n", (char *)parse_current->data); 2106 rc = SEPOL_ERR; 2107 goto exit; 2108 } 2109 2110 permx->obj_str = parse_current->next->data; 2111 2112 rc = cil_gen_expr(parse_current->next->next, CIL_PERMISSIONX, &permx->expr_str); 2113 if (rc != SEPOL_OK) { 2114 goto exit; 2115 } 2116 2117 return SEPOL_OK; 2118 2119 exit: 2120 cil_tree_log(parse_current, CIL_ERR, "Bad permissionx content"); 2121 return rc; 2122 } 2123 2124 int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 2125 { 2126 enum cil_syntax syntax[] = { 2127 CIL_SYN_STRING, 2128 CIL_SYN_STRING, 2129 CIL_SYN_LIST, 2130 CIL_SYN_END 2131 }; 2132 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2133 char *key = NULL; 2134 struct cil_permissionx *permx = NULL; 2135 int rc = SEPOL_ERR; 2136 2137 if (parse_current == NULL || ast_node == NULL) { 2138 goto exit; 2139 } 2140 2141 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2142 if (rc != SEPOL_OK) { 2143 goto exit; 2144 } 2145 2146 cil_permissionx_init(&permx); 2147 2148 key = parse_current->next->data; 2149 2150 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)permx, (hashtab_key_t)key, CIL_SYM_PERMX, CIL_PERMISSIONX); 2151 if (rc != SEPOL_OK) { 2152 goto exit; 2153 } 2154 2155 rc = cil_fill_permissionx(parse_current->next->next->cl_head, permx); 2156 if (rc != SEPOL_OK) { 2157 goto exit; 2158 } 2159 2160 return SEPOL_OK; 2161 2162 exit: 2163 cil_tree_log(parse_current, CIL_ERR, "Bad permissionx statement"); 2164 cil_destroy_permissionx(permx); 2165 cil_clear_node(ast_node); 2166 return rc; 2167 } 2168 2169 void cil_destroy_permissionx(struct cil_permissionx *permx) 2170 { 2171 if (permx == NULL) { 2172 return; 2173 } 2174 2175 cil_symtab_datum_destroy(&permx->datum); 2176 2177 cil_list_destroy(&permx->expr_str, CIL_TRUE); 2178 ebitmap_destroy(permx->perms); 2179 free(permx->perms); 2180 free(permx); 2181 } 2182 2183 int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind) 2184 { 2185 enum cil_syntax syntax[] = { 2186 CIL_SYN_STRING, 2187 CIL_SYN_STRING, 2188 CIL_SYN_STRING, 2189 CIL_SYN_STRING | CIL_SYN_LIST, 2190 CIL_SYN_END 2191 }; 2192 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2193 struct cil_avrule *rule = NULL; 2194 int rc = SEPOL_ERR; 2195 2196 if (parse_current == NULL || ast_node == NULL) { 2197 goto exit; 2198 } 2199 2200 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2201 if (rc != SEPOL_OK) { 2202 goto exit; 2203 } 2204 2205 cil_avrule_init(&rule); 2206 2207 rule->is_extended = 1; 2208 rule->rule_kind = rule_kind; 2209 rule->src_str = parse_current->next->data; 2210 rule->tgt_str = parse_current->next->next->data; 2211 2212 if (parse_current->next->next->next->cl_head == NULL) { 2213 rule->perms.x.permx_str = parse_current->next->next->next->data; 2214 } else { 2215 cil_permissionx_init(&rule->perms.x.permx); 2216 2217 rc = cil_fill_permissionx(parse_current->next->next->next->cl_head, rule->perms.x.permx); 2218 if (rc != SEPOL_OK) { 2219 goto exit; 2220 } 2221 } 2222 2223 ast_node->data = rule; 2224 ast_node->flavor = CIL_AVRULEX; 2225 2226 return SEPOL_OK; 2227 2228 exit: 2229 cil_tree_log(parse_current, CIL_ERR, "Bad allowx rule"); 2230 cil_destroy_avrule(rule); 2231 return rc; 2232 } 2233 2234 int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind) 2235 { 2236 enum cil_syntax syntax[] = { 2237 CIL_SYN_STRING, 2238 CIL_SYN_STRING, 2239 CIL_SYN_STRING, 2240 CIL_SYN_STRING, 2241 CIL_SYN_STRING, 2242 CIL_SYN_END 2243 }; 2244 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2245 struct cil_type_rule *rule = NULL; 2246 int rc = SEPOL_ERR; 2247 2248 if (parse_current == NULL || ast_node == NULL) { 2249 goto exit; 2250 } 2251 2252 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2253 if (rc != SEPOL_OK) { 2254 goto exit; 2255 } 2256 2257 cil_type_rule_init(&rule); 2258 2259 rule->rule_kind = rule_kind; 2260 rule->src_str = parse_current->next->data; 2261 rule->tgt_str = parse_current->next->next->data; 2262 rule->obj_str = parse_current->next->next->next->data; 2263 rule->result_str = parse_current->next->next->next->next->data; 2264 2265 ast_node->data = rule; 2266 ast_node->flavor = CIL_TYPE_RULE; 2267 2268 return SEPOL_OK; 2269 2270 exit: 2271 cil_tree_log(parse_current, CIL_ERR, "Bad type rule"); 2272 cil_destroy_type_rule(rule); 2273 return rc; 2274 } 2275 2276 void cil_destroy_type_rule(struct cil_type_rule *rule) 2277 { 2278 if (rule == NULL) { 2279 return; 2280 } 2281 2282 free(rule); 2283 } 2284 2285 int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 2286 { 2287 enum cil_syntax syntax[] = { 2288 CIL_SYN_STRING, 2289 CIL_SYN_STRING, 2290 CIL_SYN_END 2291 }; 2292 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2293 char *key = NULL; 2294 struct cil_type *type = NULL; 2295 int rc = SEPOL_ERR; 2296 2297 if (db == NULL || parse_current == NULL || ast_node == NULL) { 2298 goto exit; 2299 } 2300 2301 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2302 if (rc != SEPOL_OK) { 2303 goto exit; 2304 } 2305 2306 if (parse_current->next->data == CIL_KEY_SELF) { 2307 cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); 2308 rc = SEPOL_ERR; 2309 goto exit; 2310 } 2311 2312 cil_type_init(&type); 2313 2314 key = parse_current->next->data; 2315 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)type, (hashtab_key_t)key, CIL_SYM_TYPES, CIL_TYPE); 2316 if (rc != SEPOL_OK) { 2317 goto exit; 2318 } 2319 2320 return SEPOL_OK; 2321 2322 exit: 2323 cil_tree_log(parse_current, CIL_ERR, "Bad type declaration"); 2324 cil_destroy_type(type); 2325 cil_clear_node(ast_node); 2326 return rc; 2327 } 2328 2329 void cil_destroy_type(struct cil_type *type) 2330 { 2331 if (type == NULL) { 2332 return; 2333 } 2334 2335 cil_symtab_datum_destroy(&type->datum); 2336 free(type); 2337 } 2338 2339 int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 2340 { 2341 enum cil_syntax syntax[] = { 2342 CIL_SYN_STRING, 2343 CIL_SYN_STRING, 2344 CIL_SYN_END 2345 }; 2346 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2347 char *key = NULL; 2348 struct cil_typeattribute *attr = NULL; 2349 int rc = SEPOL_ERR; 2350 2351 if (db == NULL || parse_current == NULL || ast_node == NULL) { 2352 goto exit; 2353 } 2354 2355 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2356 if (rc != SEPOL_OK) { 2357 goto exit; 2358 } 2359 2360 if (parse_current->next->data == CIL_KEY_SELF) { 2361 cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); 2362 rc = SEPOL_ERR; 2363 goto exit; 2364 } 2365 2366 cil_typeattribute_init(&attr); 2367 2368 key = parse_current->next->data; 2369 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)attr, (hashtab_key_t)key, CIL_SYM_TYPES, CIL_TYPEATTRIBUTE); 2370 if (rc != SEPOL_OK) { 2371 goto exit; 2372 } 2373 2374 return SEPOL_OK; 2375 2376 exit: 2377 cil_tree_log(parse_current, CIL_ERR, "Bad typeattribute declaration"); 2378 cil_destroy_typeattribute(attr); 2379 cil_clear_node(ast_node); 2380 return rc; 2381 } 2382 2383 void cil_destroy_typeattribute(struct cil_typeattribute *attr) 2384 { 2385 if (attr == NULL) { 2386 return; 2387 } 2388 2389 cil_symtab_datum_destroy(&attr->datum); 2390 2391 if (attr->expr_list != NULL) { 2392 /* we don't want to destroy the expression stacks (cil_list) inside 2393 * this list cil_list_destroy destroys sublists, so we need to do it 2394 * manually */ 2395 struct cil_list_item *expr = attr->expr_list->head; 2396 while (expr != NULL) { 2397 struct cil_list_item *next = expr->next; 2398 cil_list_item_destroy(&expr, CIL_FALSE); 2399 expr = next; 2400 } 2401 free(attr->expr_list); 2402 attr->expr_list = NULL; 2403 } 2404 ebitmap_destroy(attr->types); 2405 free(attr->types); 2406 free(attr); 2407 } 2408 2409 int cil_gen_bool(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, int tunableif) 2410 { 2411 enum cil_syntax syntax[] = { 2412 CIL_SYN_STRING, 2413 CIL_SYN_STRING, 2414 CIL_SYN_STRING, 2415 CIL_SYN_END 2416 }; 2417 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2418 char *key = NULL; 2419 struct cil_bool *boolean = NULL; 2420 int rc = SEPOL_ERR; 2421 2422 if (db == NULL || parse_current == NULL || ast_node == NULL) { 2423 goto exit; 2424 } 2425 2426 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2427 if (rc != SEPOL_OK) { 2428 goto exit; 2429 } 2430 2431 cil_bool_init(&boolean); 2432 2433 key = parse_current->next->data; 2434 2435 if (parse_current->next->next->data == CIL_KEY_CONDTRUE) { 2436 boolean->value = CIL_TRUE; 2437 } else if (parse_current->next->next->data == CIL_KEY_CONDFALSE) { 2438 boolean->value = CIL_FALSE; 2439 } else { 2440 cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); 2441 rc = SEPOL_ERR; 2442 goto exit; 2443 } 2444 2445 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)boolean, (hashtab_key_t)key, CIL_SYM_BOOLS, CIL_BOOL); 2446 if (rc != SEPOL_OK) { 2447 goto exit; 2448 } 2449 2450 return SEPOL_OK; 2451 2452 exit: 2453 if (tunableif) { 2454 cil_tree_log(parse_current, CIL_ERR, "Bad tunable (treated as a boolean due to preserve-tunables) declaration"); 2455 } else { 2456 cil_tree_log(parse_current, CIL_ERR, "Bad boolean declaration"); 2457 } 2458 cil_destroy_bool(boolean); 2459 cil_clear_node(ast_node); 2460 return rc; 2461 } 2462 2463 void cil_destroy_bool(struct cil_bool *boolean) 2464 { 2465 if (boolean == NULL) { 2466 return; 2467 } 2468 2469 cil_symtab_datum_destroy(&boolean->datum); 2470 free(boolean); 2471 } 2472 2473 int cil_gen_tunable(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 2474 { 2475 enum cil_syntax syntax[] = { 2476 CIL_SYN_STRING, 2477 CIL_SYN_STRING, 2478 CIL_SYN_STRING, 2479 CIL_SYN_END 2480 }; 2481 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2482 char *key = NULL; 2483 struct cil_tunable *tunable = NULL; 2484 int rc = SEPOL_ERR; 2485 2486 if (db == NULL || parse_current == NULL || ast_node == NULL) { 2487 goto exit; 2488 } 2489 2490 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2491 if (rc != SEPOL_OK) { 2492 goto exit; 2493 } 2494 2495 cil_tunable_init(&tunable); 2496 2497 key = parse_current->next->data; 2498 2499 if (parse_current->next->next->data == CIL_KEY_CONDTRUE) { 2500 tunable->value = CIL_TRUE; 2501 } else if (parse_current->next->next->data == CIL_KEY_CONDFALSE) { 2502 tunable->value = CIL_FALSE; 2503 } else { 2504 cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); 2505 rc = SEPOL_ERR; 2506 goto exit; 2507 } 2508 2509 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)tunable, (hashtab_key_t)key, CIL_SYM_TUNABLES, CIL_TUNABLE); 2510 if (rc != SEPOL_OK) { 2511 goto exit; 2512 } 2513 2514 return SEPOL_OK; 2515 2516 exit: 2517 cil_tree_log(parse_current, CIL_ERR, "Bad tunable declaration"); 2518 cil_destroy_tunable(tunable); 2519 cil_clear_node(ast_node); 2520 return rc; 2521 } 2522 2523 void cil_destroy_tunable(struct cil_tunable *tunable) 2524 { 2525 if (tunable == NULL) { 2526 return; 2527 } 2528 2529 cil_symtab_datum_destroy(&tunable->datum); 2530 free(tunable); 2531 } 2532 2533 static enum cil_flavor __cil_get_expr_operator_flavor(const char *op) 2534 { 2535 if (op == NULL) return CIL_NONE; 2536 else if (op == CIL_KEY_AND) return CIL_AND; 2537 else if (op == CIL_KEY_OR) return CIL_OR; 2538 else if (op == CIL_KEY_NOT) return CIL_NOT; 2539 else if (op == CIL_KEY_EQ) return CIL_EQ; /* Only conditional */ 2540 else if (op == CIL_KEY_NEQ) return CIL_NEQ; /* Only conditional */ 2541 else if (op == CIL_KEY_XOR) return CIL_XOR; 2542 else if (op == CIL_KEY_ALL) return CIL_ALL; /* Only set and permissionx */ 2543 else if (op == CIL_KEY_RANGE) return CIL_RANGE; /* Only catset and permissionx */ 2544 else return CIL_NONE; 2545 } 2546 2547 static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth); 2548 2549 static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth) 2550 { 2551 int rc = SEPOL_ERR; 2552 enum cil_flavor op; 2553 2554 if (flavor == CIL_BOOL && *depth > COND_EXPR_MAXDEPTH) { 2555 cil_log(CIL_ERR, "Max depth of %d exceeded for boolean expression\n", COND_EXPR_MAXDEPTH); 2556 goto exit; 2557 } 2558 2559 op = __cil_get_expr_operator_flavor(current->data); 2560 2561 rc = cil_verify_expr_syntax(current, op, flavor); 2562 if (rc != SEPOL_OK) { 2563 goto exit; 2564 } 2565 2566 if (op != CIL_NONE) { 2567 cil_list_append(expr, CIL_OP, (void *)op); 2568 current = current->next; 2569 } 2570 2571 if (op == CIL_NONE || op == CIL_ALL) { 2572 (*depth)++; 2573 } 2574 2575 for (;current != NULL; current = current->next) { 2576 rc = __cil_fill_expr(current, flavor, expr, depth); 2577 if (rc != SEPOL_OK) { 2578 goto exit; 2579 } 2580 } 2581 2582 (*depth)--; 2583 2584 return SEPOL_OK; 2585 2586 exit: 2587 return rc; 2588 } 2589 2590 static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth) 2591 { 2592 int rc = SEPOL_ERR; 2593 2594 if (current->cl_head == NULL) { 2595 enum cil_flavor op = __cil_get_expr_operator_flavor(current->data); 2596 if (op != CIL_NONE) { 2597 cil_log(CIL_ERR, "Operator (%s) not in an expression\n", (char*)current->data); 2598 goto exit; 2599 } 2600 cil_list_append(expr, CIL_STRING, current->data); 2601 } else { 2602 struct cil_list *sub_expr; 2603 cil_list_init(&sub_expr, flavor); 2604 rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr, depth); 2605 if (rc != SEPOL_OK) { 2606 cil_list_destroy(&sub_expr, CIL_TRUE); 2607 goto exit; 2608 } 2609 cil_list_append(expr, CIL_LIST, sub_expr); 2610 } 2611 2612 return SEPOL_OK; 2613 2614 exit: 2615 return rc; 2616 } 2617 2618 2619 int cil_gen_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) 2620 { 2621 int rc = SEPOL_ERR; 2622 int depth = 0; 2623 2624 cil_list_init(expr, flavor); 2625 2626 if (current->cl_head == NULL) { 2627 rc = __cil_fill_expr(current, flavor, *expr, &depth); 2628 } else { 2629 rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr, &depth); 2630 } 2631 2632 if (rc != SEPOL_OK) { 2633 cil_list_destroy(expr, CIL_TRUE); 2634 cil_log(CIL_ERR, "Bad expression\n"); 2635 } 2636 2637 return rc; 2638 } 2639 2640 static enum cil_flavor __cil_get_constraint_operator_flavor(const char *op) 2641 { 2642 if (op == CIL_KEY_AND) return CIL_AND; 2643 else if (op == CIL_KEY_OR) return CIL_OR; 2644 else if (op == CIL_KEY_NOT) return CIL_NOT; 2645 else if (op == CIL_KEY_EQ) return CIL_EQ; 2646 else if (op == CIL_KEY_NEQ) return CIL_NEQ; 2647 else if (op == CIL_KEY_CONS_DOM) return CIL_CONS_DOM; 2648 else if (op == CIL_KEY_CONS_DOMBY) return CIL_CONS_DOMBY; 2649 else if (op == CIL_KEY_CONS_INCOMP) return CIL_CONS_INCOMP; 2650 else return CIL_NONE; 2651 } 2652 2653 static enum cil_flavor __cil_get_constraint_operand_flavor(const char *operand) 2654 { 2655 if (operand == NULL) return CIL_LIST; 2656 else if (operand == CIL_KEY_CONS_T1) return CIL_CONS_T1; 2657 else if (operand == CIL_KEY_CONS_T2) return CIL_CONS_T2; 2658 else if (operand == CIL_KEY_CONS_T3) return CIL_CONS_T3; 2659 else if (operand == CIL_KEY_CONS_R1) return CIL_CONS_R1; 2660 else if (operand == CIL_KEY_CONS_R2) return CIL_CONS_R2; 2661 else if (operand == CIL_KEY_CONS_R3) return CIL_CONS_R3; 2662 else if (operand == CIL_KEY_CONS_U1) return CIL_CONS_U1; 2663 else if (operand == CIL_KEY_CONS_U2) return CIL_CONS_U2; 2664 else if (operand == CIL_KEY_CONS_U3) return CIL_CONS_U3; 2665 else if (operand == CIL_KEY_CONS_L1) return CIL_CONS_L1; 2666 else if (operand == CIL_KEY_CONS_L2) return CIL_CONS_L2; 2667 else if (operand == CIL_KEY_CONS_H1) return CIL_CONS_H1; 2668 else if (operand == CIL_KEY_CONS_H2) return CIL_CONS_H2; 2669 else return CIL_STRING; 2670 } 2671 2672 static int __cil_fill_constraint_leaf_expr(struct cil_tree_node *current, enum cil_flavor expr_flavor, enum cil_flavor op, struct cil_list **leaf_expr) 2673 { 2674 int rc = SEPOL_ERR; 2675 enum cil_flavor leaf_expr_flavor = CIL_NONE; 2676 enum cil_flavor l_flavor = CIL_NONE; 2677 enum cil_flavor r_flavor = CIL_NONE; 2678 2679 l_flavor = __cil_get_constraint_operand_flavor(current->next->data); 2680 r_flavor = __cil_get_constraint_operand_flavor(current->next->next->data); 2681 2682 switch (l_flavor) { 2683 case CIL_CONS_U1: 2684 case CIL_CONS_U2: 2685 case CIL_CONS_U3: 2686 leaf_expr_flavor = CIL_USER; 2687 break; 2688 case CIL_CONS_R1: 2689 case CIL_CONS_R2: 2690 case CIL_CONS_R3: 2691 leaf_expr_flavor = CIL_ROLE; 2692 break; 2693 case CIL_CONS_T1: 2694 case CIL_CONS_T2: 2695 case CIL_CONS_T3: 2696 leaf_expr_flavor = CIL_TYPE; 2697 break; 2698 case CIL_CONS_L1: 2699 case CIL_CONS_L2: 2700 case CIL_CONS_H1: 2701 case CIL_CONS_H2: 2702 leaf_expr_flavor = CIL_LEVEL; 2703 break; 2704 default: 2705 cil_log(CIL_ERR, "Invalid left operand (%s)\n", (char*)current->next->data); 2706 goto exit; 2707 } 2708 2709 rc = cil_verify_constraint_leaf_expr_syntax(l_flavor, r_flavor, op, expr_flavor); 2710 if (rc != SEPOL_OK) { 2711 goto exit; 2712 } 2713 2714 cil_list_init(leaf_expr, leaf_expr_flavor); 2715 2716 cil_list_append(*leaf_expr, CIL_OP, (void *)op); 2717 2718 cil_list_append(*leaf_expr, CIL_CONS_OPERAND, (void *)l_flavor); 2719 2720 if (r_flavor == CIL_STRING) { 2721 cil_list_append(*leaf_expr, CIL_STRING, current->next->next->data); 2722 } else if (r_flavor == CIL_LIST) { 2723 struct cil_list *sub_list; 2724 cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list); 2725 cil_list_append(*leaf_expr, CIL_LIST, &sub_list); 2726 } else { 2727 cil_list_append(*leaf_expr, CIL_CONS_OPERAND, (void *)r_flavor); 2728 } 2729 2730 return SEPOL_OK; 2731 2732 exit: 2733 2734 return SEPOL_ERR; 2735 } 2736 2737 static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr, int *depth) 2738 { 2739 int rc = SEPOL_ERR; 2740 enum cil_flavor op; 2741 struct cil_list *lexpr; 2742 struct cil_list *rexpr; 2743 2744 if (current->data == NULL || current->cl_head != NULL) { 2745 cil_log(CIL_ERR, "Expected a string at the start of the constraint expression\n"); 2746 goto exit; 2747 } 2748 2749 if (*depth > CEXPR_MAXDEPTH) { 2750 cil_log(CIL_ERR, "Max depth of %d exceeded for constraint expression\n", CEXPR_MAXDEPTH); 2751 rc = SEPOL_ERR; 2752 goto exit; 2753 } 2754 2755 op = __cil_get_constraint_operator_flavor(current->data); 2756 2757 rc = cil_verify_constraint_expr_syntax(current, op); 2758 if (rc != SEPOL_OK) { 2759 goto exit; 2760 } 2761 2762 switch (op) { 2763 case CIL_EQ: 2764 case CIL_NEQ: 2765 case CIL_CONS_DOM: 2766 case CIL_CONS_DOMBY: 2767 case CIL_CONS_INCOMP: 2768 (*depth)++; 2769 rc = __cil_fill_constraint_leaf_expr(current, flavor, op, expr); 2770 if (rc != SEPOL_OK) { 2771 goto exit; 2772 } 2773 break; 2774 case CIL_NOT: 2775 rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth); 2776 if (rc != SEPOL_OK) { 2777 goto exit; 2778 } 2779 cil_list_init(expr, flavor); 2780 cil_list_append(*expr, CIL_OP, (void *)op); 2781 cil_list_append(*expr, CIL_LIST, lexpr); 2782 break; 2783 default: 2784 rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth); 2785 if (rc != SEPOL_OK) { 2786 goto exit; 2787 } 2788 rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr, depth); 2789 if (rc != SEPOL_OK) { 2790 cil_list_destroy(&lexpr, CIL_TRUE); 2791 goto exit; 2792 } 2793 cil_list_init(expr, flavor); 2794 cil_list_append(*expr, CIL_OP, (void *)op); 2795 cil_list_append(*expr, CIL_LIST, lexpr); 2796 cil_list_append(*expr, CIL_LIST, rexpr); 2797 break; 2798 } 2799 2800 (*depth)--; 2801 2802 return SEPOL_OK; 2803 exit: 2804 2805 return rc; 2806 } 2807 2808 int cil_gen_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) 2809 { 2810 int rc = SEPOL_ERR; 2811 int depth = 0; 2812 2813 if (current->cl_head == NULL) { 2814 goto exit; 2815 } 2816 2817 rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr, &depth); 2818 if (rc != SEPOL_OK) { 2819 goto exit; 2820 } 2821 2822 return SEPOL_OK; 2823 2824 exit: 2825 2826 cil_log(CIL_ERR, "Bad expression tree for constraint\n"); 2827 return rc; 2828 } 2829 2830 int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, int tunableif) 2831 { 2832 enum cil_syntax syntax[] = { 2833 CIL_SYN_STRING, 2834 CIL_SYN_STRING | CIL_SYN_LIST, 2835 CIL_SYN_LIST, 2836 CIL_SYN_LIST | CIL_SYN_END, 2837 CIL_SYN_END 2838 }; 2839 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2840 struct cil_booleanif *bif = NULL; 2841 struct cil_tree_node *next = NULL; 2842 struct cil_tree_node *cond = NULL; 2843 int rc = SEPOL_ERR; 2844 2845 if (db == NULL || parse_current == NULL || ast_node == NULL) { 2846 goto exit; 2847 } 2848 2849 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2850 if (rc != SEPOL_OK) { 2851 goto exit; 2852 } 2853 2854 cil_boolif_init(&bif); 2855 bif->preserved_tunable = tunableif; 2856 2857 rc = cil_gen_expr(parse_current->next, CIL_BOOL, &bif->str_expr); 2858 if (rc != SEPOL_OK) { 2859 goto exit; 2860 } 2861 2862 cond = parse_current->next->next; 2863 2864 /* Destroying expr tree after stack is created*/ 2865 if (cond->cl_head->data != CIL_KEY_CONDTRUE && 2866 cond->cl_head->data != CIL_KEY_CONDFALSE) { 2867 rc = SEPOL_ERR; 2868 cil_log(CIL_ERR, "Conditional neither true nor false\n"); 2869 goto exit; 2870 } 2871 2872 if (cond->next != NULL) { 2873 cond = cond->next; 2874 if (cond->cl_head->data != CIL_KEY_CONDTRUE && 2875 cond->cl_head->data != CIL_KEY_CONDFALSE) { 2876 rc = SEPOL_ERR; 2877 cil_log(CIL_ERR, "Conditional neither true nor false\n"); 2878 goto exit; 2879 } 2880 } 2881 2882 2883 next = parse_current->next->next; 2884 cil_tree_subtree_destroy(parse_current->next); 2885 parse_current->next = next; 2886 2887 ast_node->flavor = CIL_BOOLEANIF; 2888 ast_node->data = bif; 2889 2890 return SEPOL_OK; 2891 2892 exit: 2893 if (tunableif) { 2894 cil_tree_log(parse_current, CIL_ERR, "Bad tunableif (treated as a booleanif due to preserve-tunables) declaration"); 2895 } else { 2896 cil_tree_log(parse_current, CIL_ERR, "Bad booleanif declaration"); 2897 } 2898 cil_destroy_boolif(bif); 2899 return rc; 2900 } 2901 2902 void cil_destroy_boolif(struct cil_booleanif *bif) 2903 { 2904 if (bif == NULL) { 2905 return; 2906 } 2907 2908 cil_list_destroy(&bif->str_expr, CIL_TRUE); 2909 cil_list_destroy(&bif->datum_expr, CIL_FALSE); 2910 2911 free(bif); 2912 } 2913 2914 int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 2915 { 2916 enum cil_syntax syntax[] = { 2917 CIL_SYN_STRING, 2918 CIL_SYN_STRING | CIL_SYN_LIST, 2919 CIL_SYN_LIST, 2920 CIL_SYN_LIST | CIL_SYN_END, 2921 CIL_SYN_END 2922 }; 2923 int syntax_len = sizeof(syntax)/sizeof(*syntax); 2924 struct cil_tunableif *tif = NULL; 2925 struct cil_tree_node *next = NULL; 2926 struct cil_tree_node *cond = NULL; 2927 int rc = SEPOL_ERR; 2928 2929 if (db == NULL || parse_current == NULL || ast_node == NULL) { 2930 goto exit; 2931 } 2932 2933 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 2934 if (rc != SEPOL_OK) { 2935 goto exit; 2936 } 2937 2938 cil_tunif_init(&tif); 2939 2940 rc = cil_gen_expr(parse_current->next, CIL_TUNABLE, &tif->str_expr); 2941 if (rc != SEPOL_OK) { 2942 goto exit; 2943 } 2944 2945 cond = parse_current->next->next; 2946 2947 if (cond->cl_head->data != CIL_KEY_CONDTRUE && 2948 cond->cl_head->data != CIL_KEY_CONDFALSE) { 2949 rc = SEPOL_ERR; 2950 cil_log(CIL_ERR, "Conditional neither true nor false\n"); 2951 goto exit; 2952 } 2953 2954 if (cond->next != NULL) { 2955 cond = cond->next; 2956 2957 if (cond->cl_head->data != CIL_KEY_CONDTRUE && 2958 cond->cl_head->data != CIL_KEY_CONDFALSE) { 2959 rc = SEPOL_ERR; 2960 cil_log(CIL_ERR, "Conditional neither true nor false\n"); 2961 goto exit; 2962 } 2963 } 2964 2965 /* Destroying expr tree after stack is created*/ 2966 next = parse_current->next->next; 2967 cil_tree_subtree_destroy(parse_current->next); 2968 parse_current->next = next; 2969 2970 ast_node->flavor = CIL_TUNABLEIF; 2971 ast_node->data = tif; 2972 2973 return SEPOL_OK; 2974 2975 exit: 2976 cil_tree_log(parse_current, CIL_ERR, "Bad tunableif declaration"); 2977 cil_destroy_tunif(tif); 2978 return rc; 2979 } 2980 2981 void cil_destroy_tunif(struct cil_tunableif *tif) 2982 { 2983 if (tif == NULL) { 2984 return; 2985 } 2986 2987 cil_list_destroy(&tif->str_expr, CIL_TRUE); 2988 cil_list_destroy(&tif->datum_expr, CIL_FALSE); 2989 2990 free(tif); 2991 } 2992 2993 int cil_gen_condblock(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) 2994 { 2995 enum cil_syntax syntax[] = { 2996 CIL_SYN_STRING, 2997 CIL_SYN_N_LISTS, 2998 CIL_SYN_END 2999 }; 3000 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3001 int rc = SEPOL_ERR; 3002 struct cil_condblock *cb = NULL; 3003 3004 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3005 goto exit; 3006 } 3007 3008 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3009 if (rc != SEPOL_OK) { 3010 goto exit; 3011 } 3012 3013 if (ast_node->parent->flavor != CIL_BOOLEANIF && ast_node->parent->flavor != CIL_TUNABLEIF) { 3014 rc = SEPOL_ERR; 3015 cil_log(CIL_ERR, "Conditional statements must be a direct child of a tunableif or booleanif statement.\n"); 3016 goto exit; 3017 } 3018 3019 ast_node->flavor = CIL_CONDBLOCK; 3020 3021 cil_condblock_init(&cb); 3022 cb->flavor = flavor; 3023 3024 ast_node->data = cb; 3025 3026 return SEPOL_OK; 3027 3028 exit: 3029 cil_tree_log(parse_current, CIL_ERR, "Bad %s condition declaration", 3030 (char*)parse_current->data); 3031 cil_destroy_condblock(cb); 3032 return rc; 3033 } 3034 3035 void cil_destroy_condblock(struct cil_condblock *cb) 3036 { 3037 if (cb == NULL) { 3038 return; 3039 } 3040 3041 cil_symtab_array_destroy(cb->symtab); 3042 free(cb); 3043 } 3044 3045 int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) 3046 { 3047 enum cil_syntax syntax[] = { 3048 CIL_SYN_STRING, 3049 CIL_SYN_STRING, 3050 CIL_SYN_END 3051 }; 3052 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3053 char *key = NULL; 3054 struct cil_alias *alias = NULL; 3055 enum cil_sym_index sym_index; 3056 int rc = SEPOL_ERR; 3057 3058 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3059 goto exit; 3060 } 3061 3062 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3063 if (rc != SEPOL_OK) { 3064 goto exit; 3065 } 3066 3067 if (flavor == CIL_TYPEALIAS && parse_current->next->data == CIL_KEY_SELF) { 3068 cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); 3069 rc = SEPOL_ERR; 3070 goto exit; 3071 } 3072 3073 cil_alias_init(&alias); 3074 3075 key = parse_current->next->data; 3076 3077 rc = cil_flavor_to_symtab_index(flavor, &sym_index); 3078 if (rc != SEPOL_OK) { 3079 goto exit; 3080 } 3081 3082 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)alias, (hashtab_key_t)key, sym_index, flavor); 3083 if (rc != SEPOL_OK) { 3084 goto exit; 3085 } 3086 3087 return SEPOL_OK; 3088 3089 exit: 3090 cil_tree_log(parse_current, CIL_ERR, "Bad %s declaration", (char*)parse_current->data); 3091 cil_destroy_alias(alias); 3092 cil_clear_node(ast_node); 3093 return rc; 3094 } 3095 3096 void cil_destroy_alias(struct cil_alias *alias) 3097 { 3098 if (alias == NULL) { 3099 return; 3100 } 3101 3102 cil_symtab_datum_destroy(&alias->datum); 3103 alias->actual = NULL; 3104 3105 free(alias); 3106 } 3107 3108 int cil_gen_aliasactual(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) 3109 { 3110 int rc = SEPOL_ERR; 3111 enum cil_syntax syntax[] = { 3112 CIL_SYN_STRING, 3113 CIL_SYN_STRING, 3114 CIL_SYN_STRING, 3115 CIL_SYN_END 3116 }; 3117 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3118 struct cil_aliasactual *aliasactual = NULL; 3119 3120 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3121 goto exit; 3122 } 3123 3124 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3125 if (rc != SEPOL_OK) { 3126 goto exit; 3127 } 3128 3129 if ((flavor == CIL_TYPEALIAS && parse_current->next->data == CIL_KEY_SELF) || parse_current->next->next->data == CIL_KEY_SELF) { 3130 cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); 3131 rc = SEPOL_ERR; 3132 goto exit; 3133 } 3134 3135 cil_aliasactual_init(&aliasactual); 3136 3137 aliasactual->alias_str = parse_current->next->data; 3138 3139 aliasactual->actual_str = parse_current->next->next->data; 3140 3141 ast_node->data = aliasactual; 3142 ast_node->flavor = flavor; 3143 3144 return SEPOL_OK; 3145 3146 exit: 3147 cil_tree_log(parse_current, CIL_ERR, "Bad %s association", cil_node_to_string(parse_current)); 3148 cil_clear_node(ast_node); 3149 return rc; 3150 } 3151 3152 void cil_destroy_aliasactual(struct cil_aliasactual *aliasactual) 3153 { 3154 if (aliasactual == NULL) { 3155 return; 3156 } 3157 3158 free(aliasactual); 3159 } 3160 3161 int cil_gen_typeattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3162 { 3163 enum cil_syntax syntax[] = { 3164 CIL_SYN_STRING, 3165 CIL_SYN_STRING, 3166 CIL_SYN_STRING | CIL_SYN_LIST, 3167 CIL_SYN_END 3168 }; 3169 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3170 struct cil_typeattributeset *attrset = NULL; 3171 int rc = SEPOL_ERR; 3172 3173 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3174 goto exit; 3175 } 3176 3177 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3178 if (rc != SEPOL_OK) { 3179 goto exit; 3180 } 3181 3182 cil_typeattributeset_init(&attrset); 3183 3184 attrset->attr_str = parse_current->next->data; 3185 3186 rc = cil_gen_expr(parse_current->next->next, CIL_TYPE, &attrset->str_expr); 3187 if (rc != SEPOL_OK) { 3188 goto exit; 3189 } 3190 ast_node->data = attrset; 3191 ast_node->flavor = CIL_TYPEATTRIBUTESET; 3192 3193 return SEPOL_OK; 3194 3195 exit: 3196 cil_tree_log(parse_current, CIL_ERR, "Bad typeattributeset statement"); 3197 cil_destroy_typeattributeset(attrset); 3198 return rc; 3199 } 3200 3201 void cil_destroy_typeattributeset(struct cil_typeattributeset *attrset) 3202 { 3203 if (attrset == NULL) { 3204 return; 3205 } 3206 3207 cil_list_destroy(&attrset->str_expr, CIL_TRUE); 3208 cil_list_destroy(&attrset->datum_expr, CIL_FALSE); 3209 3210 free(attrset); 3211 } 3212 3213 int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3214 { 3215 enum cil_syntax syntax[] = { 3216 CIL_SYN_STRING, 3217 CIL_SYN_STRING | CIL_SYN_LIST, 3218 CIL_SYN_STRING, 3219 CIL_SYN_END 3220 }; 3221 char *expand_str; 3222 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3223 struct cil_expandtypeattribute *expandattr = NULL; 3224 int rc = SEPOL_ERR; 3225 3226 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3227 goto exit; 3228 } 3229 3230 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3231 if (rc != SEPOL_OK) { 3232 goto exit; 3233 } 3234 3235 cil_expandtypeattribute_init(&expandattr); 3236 3237 if (parse_current->next->cl_head == NULL) { 3238 cil_list_init(&expandattr->attr_strs, CIL_TYPE); 3239 cil_list_append(expandattr->attr_strs, CIL_STRING, parse_current->next->data); 3240 } else { 3241 rc = cil_fill_list(parse_current->next->cl_head, CIL_TYPE, &expandattr->attr_strs); 3242 if (rc != SEPOL_OK) { 3243 goto exit; 3244 } 3245 } 3246 3247 expand_str = parse_current->next->next->data; 3248 3249 if (expand_str == CIL_KEY_CONDTRUE) { 3250 expandattr->expand = CIL_TRUE; 3251 } else if (expand_str == CIL_KEY_CONDFALSE) { 3252 expandattr->expand = CIL_FALSE; 3253 } else { 3254 cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); 3255 goto exit; 3256 } 3257 3258 ast_node->data = expandattr; 3259 ast_node->flavor = CIL_EXPANDTYPEATTRIBUTE; 3260 3261 return SEPOL_OK; 3262 3263 exit: 3264 cil_tree_log(parse_current, CIL_ERR, "Bad expandtypeattribute statement"); 3265 cil_destroy_expandtypeattribute(expandattr); 3266 return rc; 3267 } 3268 3269 void cil_destroy_expandtypeattribute(struct cil_expandtypeattribute *expandattr) 3270 { 3271 if (expandattr == NULL) { 3272 return; 3273 } 3274 3275 cil_list_destroy(&expandattr->attr_strs, CIL_TRUE); 3276 3277 cil_list_destroy(&expandattr->attr_datums, CIL_FALSE); 3278 3279 free(expandattr); 3280 } 3281 3282 int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3283 { 3284 enum cil_syntax syntax[] = { 3285 CIL_SYN_STRING, 3286 CIL_SYN_STRING, 3287 CIL_SYN_END 3288 }; 3289 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3290 struct cil_typepermissive *typeperm = NULL; 3291 int rc = SEPOL_ERR; 3292 3293 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3294 goto exit; 3295 } 3296 3297 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3298 if (rc != SEPOL_OK) { 3299 goto exit; 3300 } 3301 3302 cil_typepermissive_init(&typeperm); 3303 3304 typeperm->type_str = parse_current->next->data; 3305 3306 ast_node->data = typeperm; 3307 ast_node->flavor = CIL_TYPEPERMISSIVE; 3308 3309 return SEPOL_OK; 3310 3311 exit: 3312 cil_tree_log(parse_current, CIL_ERR, "Bad typepermissive declaration"); 3313 cil_destroy_typepermissive(typeperm); 3314 return rc; 3315 } 3316 3317 void cil_destroy_typepermissive(struct cil_typepermissive *typeperm) 3318 { 3319 if (typeperm == NULL) { 3320 return; 3321 } 3322 3323 free(typeperm); 3324 } 3325 3326 int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3327 { 3328 int rc = SEPOL_ERR; 3329 enum cil_syntax syntax[] = { 3330 CIL_SYN_STRING, 3331 CIL_SYN_STRING, 3332 CIL_SYN_STRING, 3333 CIL_SYN_STRING, 3334 CIL_SYN_STRING, 3335 CIL_SYN_STRING | CIL_SYN_END, 3336 CIL_SYN_END 3337 }; 3338 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3339 char *s1, *s2, *s3, *s4, *s5; 3340 3341 if (db == NULL || parse_current == NULL || ast_node == NULL ) { 3342 goto exit; 3343 } 3344 3345 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3346 if (rc != SEPOL_OK) { 3347 goto exit; 3348 } 3349 3350 s1 = parse_current->next->data; 3351 s2 = parse_current->next->next->data; 3352 s3 = parse_current->next->next->next->data; 3353 s4 = parse_current->next->next->next->next->data; 3354 s5 = NULL; 3355 3356 if (parse_current->next->next->next->next->next) { 3357 if (s4 == CIL_KEY_STAR) { 3358 s4 = parse_current->next->next->next->next->next->data; 3359 } else { 3360 s5 = parse_current->next->next->next->next->next->data; 3361 } 3362 } 3363 3364 if (s5) { 3365 struct cil_nametypetransition *nametypetrans = NULL; 3366 3367 cil_nametypetransition_init(&nametypetrans); 3368 3369 nametypetrans->src_str = s1; 3370 nametypetrans->tgt_str = s2; 3371 nametypetrans->obj_str = s3; 3372 nametypetrans->result_str = s5; 3373 nametypetrans->name_str = s4; 3374 3375 ast_node->data = nametypetrans; 3376 ast_node->flavor = CIL_NAMETYPETRANSITION; 3377 } else { 3378 struct cil_type_rule *rule = NULL; 3379 3380 cil_type_rule_init(&rule); 3381 3382 rule->rule_kind = CIL_TYPE_TRANSITION; 3383 rule->src_str = s1; 3384 rule->tgt_str = s2; 3385 rule->obj_str = s3; 3386 rule->result_str = s4; 3387 3388 ast_node->data = rule; 3389 ast_node->flavor = CIL_TYPE_RULE; 3390 } 3391 3392 return SEPOL_OK; 3393 3394 exit: 3395 cil_tree_log(parse_current, CIL_ERR, "Bad typetransition declaration"); 3396 return rc; 3397 } 3398 3399 void cil_destroy_name(struct cil_name *name) 3400 { 3401 if (name == NULL) { 3402 return; 3403 } 3404 3405 cil_symtab_datum_destroy(&name->datum); 3406 free(name); 3407 } 3408 3409 void cil_destroy_typetransition(struct cil_nametypetransition *nametypetrans) 3410 { 3411 if (nametypetrans == NULL) { 3412 return; 3413 } 3414 3415 free(nametypetrans); 3416 } 3417 3418 int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3419 { 3420 enum cil_syntax syntax[] = { 3421 CIL_SYN_STRING, 3422 CIL_SYN_STRING, 3423 CIL_SYN_STRING, 3424 CIL_SYN_STRING, 3425 CIL_SYN_STRING | CIL_SYN_LIST, 3426 CIL_SYN_END 3427 }; 3428 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3429 struct cil_rangetransition *rangetrans = NULL; 3430 int rc = SEPOL_ERR; 3431 3432 if (db == NULL || parse_current == NULL || ast_node == NULL ) { 3433 goto exit; 3434 } 3435 3436 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3437 if (rc != SEPOL_OK) { 3438 goto exit; 3439 } 3440 3441 cil_rangetransition_init(&rangetrans); 3442 3443 rangetrans->src_str = parse_current->next->data; 3444 rangetrans->exec_str = parse_current->next->next->data; 3445 rangetrans->obj_str = parse_current->next->next->next->data; 3446 3447 rangetrans->range_str = NULL; 3448 3449 if (parse_current->next->next->next->next->cl_head == NULL) { 3450 rangetrans->range_str = parse_current->next->next->next->next->data; 3451 } else { 3452 cil_levelrange_init(&rangetrans->range); 3453 3454 rc = cil_fill_levelrange(parse_current->next->next->next->next->cl_head, rangetrans->range); 3455 if (rc != SEPOL_OK) { 3456 goto exit; 3457 } 3458 } 3459 3460 ast_node->data = rangetrans; 3461 ast_node->flavor = CIL_RANGETRANSITION; 3462 3463 return SEPOL_OK; 3464 3465 exit: 3466 cil_tree_log(parse_current, CIL_ERR, "Bad rangetransition declaration"); 3467 cil_destroy_rangetransition(rangetrans); 3468 return rc; 3469 } 3470 3471 void cil_destroy_rangetransition(struct cil_rangetransition *rangetrans) 3472 { 3473 if (rangetrans == NULL) { 3474 return; 3475 } 3476 3477 if (rangetrans->range_str == NULL && rangetrans->range != NULL) { 3478 cil_destroy_levelrange(rangetrans->range); 3479 } 3480 3481 free(rangetrans); 3482 } 3483 3484 int cil_gen_sensitivity(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3485 { 3486 enum cil_syntax syntax[] = { 3487 CIL_SYN_STRING, 3488 CIL_SYN_STRING, 3489 CIL_SYN_END 3490 }; 3491 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3492 char *key = NULL; 3493 struct cil_sens *sens = NULL; 3494 int rc = SEPOL_ERR; 3495 3496 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3497 goto exit; 3498 } 3499 3500 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3501 if (rc != SEPOL_OK) { 3502 goto exit; 3503 } 3504 3505 cil_sens_init(&sens); 3506 3507 key = parse_current->next->data; 3508 3509 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)sens, (hashtab_key_t)key, CIL_SYM_SENS, CIL_SENS); 3510 if (rc != SEPOL_OK) { 3511 goto exit; 3512 } 3513 3514 return SEPOL_OK; 3515 3516 exit: 3517 cil_tree_log(parse_current, CIL_ERR, "Bad sensitivity declaration"); 3518 cil_destroy_sensitivity(sens); 3519 cil_clear_node(ast_node); 3520 return rc; 3521 } 3522 3523 void cil_destroy_sensitivity(struct cil_sens *sens) 3524 { 3525 if (sens == NULL) { 3526 return; 3527 } 3528 3529 cil_symtab_datum_destroy(&sens->datum); 3530 3531 cil_list_destroy(&sens->cats_list, CIL_FALSE); 3532 3533 free(sens); 3534 } 3535 3536 int cil_gen_category(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3537 { 3538 enum cil_syntax syntax[] = { 3539 CIL_SYN_STRING, 3540 CIL_SYN_STRING, 3541 CIL_SYN_END 3542 }; 3543 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3544 char *key = NULL; 3545 struct cil_cat *cat = NULL; 3546 int rc = SEPOL_ERR; 3547 3548 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3549 goto exit; 3550 } 3551 3552 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3553 if (rc != SEPOL_OK) { 3554 goto exit; 3555 } 3556 3557 cil_cat_init(&cat); 3558 3559 key = parse_current->next->data; 3560 3561 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)cat, (hashtab_key_t)key, CIL_SYM_CATS, CIL_CAT); 3562 if (rc != SEPOL_OK) { 3563 goto exit; 3564 } 3565 3566 return SEPOL_OK; 3567 3568 exit: 3569 cil_tree_log(parse_current, CIL_ERR, "Bad category declaration"); 3570 cil_destroy_category(cat); 3571 cil_clear_node(ast_node); 3572 return rc; 3573 } 3574 3575 void cil_destroy_category(struct cil_cat *cat) 3576 { 3577 if (cat == NULL) { 3578 return; 3579 } 3580 3581 cil_symtab_datum_destroy(&cat->datum); 3582 free(cat); 3583 } 3584 3585 int cil_gen_catset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3586 { 3587 enum cil_syntax syntax[] = { 3588 CIL_SYN_STRING, 3589 CIL_SYN_STRING, 3590 CIL_SYN_LIST, 3591 CIL_SYN_END 3592 }; 3593 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3594 char *key = NULL; 3595 struct cil_catset *catset = NULL; 3596 int rc = SEPOL_ERR; 3597 3598 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3599 goto exit; 3600 } 3601 3602 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3603 if (rc != SEPOL_OK) { 3604 goto exit; 3605 } 3606 3607 cil_catset_init(&catset); 3608 3609 key = parse_current->next->data; 3610 3611 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)catset, (hashtab_key_t)key, CIL_SYM_CATS, CIL_CATSET); 3612 if (rc != SEPOL_OK) { 3613 goto exit; 3614 } 3615 3616 rc = cil_fill_cats(parse_current->next->next, &catset->cats); 3617 if (rc != SEPOL_OK) { 3618 goto exit; 3619 } 3620 3621 return SEPOL_OK; 3622 3623 exit: 3624 cil_tree_log(parse_current, CIL_ERR, "Bad categoryset declaration"); 3625 cil_destroy_catset(catset); 3626 cil_clear_node(ast_node); 3627 return rc; 3628 } 3629 3630 void cil_destroy_catset(struct cil_catset *catset) 3631 { 3632 if (catset == NULL) { 3633 return; 3634 } 3635 3636 cil_symtab_datum_destroy(&catset->datum); 3637 3638 cil_destroy_cats(catset->cats); 3639 3640 free(catset); 3641 } 3642 3643 int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3644 { 3645 enum cil_syntax syntax[] = { 3646 CIL_SYN_STRING, 3647 CIL_SYN_LIST, 3648 CIL_SYN_END 3649 }; 3650 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3651 struct cil_catorder *catorder = NULL; 3652 struct cil_list_item *curr = NULL; 3653 int rc = SEPOL_ERR; 3654 3655 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3656 goto exit; 3657 } 3658 3659 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3660 if (rc != SEPOL_OK) { 3661 goto exit; 3662 } 3663 3664 cil_catorder_init(&catorder); 3665 3666 rc = cil_fill_list(parse_current->next->cl_head, CIL_CATORDER, &catorder->cat_list_str); 3667 if (rc != SEPOL_OK) { 3668 goto exit; 3669 } 3670 3671 cil_list_for_each(curr, catorder->cat_list_str) { 3672 if (curr->data == CIL_KEY_UNORDERED) { 3673 cil_log(CIL_ERR, "Category order cannot be unordered.\n"); 3674 rc = SEPOL_ERR; 3675 goto exit; 3676 } 3677 } 3678 3679 ast_node->data = catorder; 3680 ast_node->flavor = CIL_CATORDER; 3681 3682 return SEPOL_OK; 3683 3684 exit: 3685 cil_tree_log(parse_current, CIL_ERR, "Bad categoryorder declaration"); 3686 cil_destroy_catorder(catorder); 3687 return rc; 3688 } 3689 3690 void cil_destroy_catorder(struct cil_catorder *catorder) 3691 { 3692 if (catorder == NULL) { 3693 return; 3694 } 3695 3696 if (catorder->cat_list_str != NULL) { 3697 cil_list_destroy(&catorder->cat_list_str, 1); 3698 } 3699 3700 free(catorder); 3701 } 3702 3703 int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3704 { 3705 enum cil_syntax syntax[] = { 3706 CIL_SYN_STRING, 3707 CIL_SYN_LIST, 3708 CIL_SYN_END 3709 }; 3710 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3711 struct cil_sensorder *sensorder = NULL; 3712 struct cil_list_item *curr = NULL; 3713 int rc = SEPOL_ERR; 3714 3715 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3716 goto exit; 3717 } 3718 3719 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3720 if (rc != SEPOL_OK) { 3721 goto exit; 3722 } 3723 3724 cil_sensorder_init(&sensorder); 3725 3726 rc = cil_fill_list(parse_current->next->cl_head, CIL_SENSITIVITYORDER, &sensorder->sens_list_str); 3727 if (rc != SEPOL_OK) { 3728 goto exit; 3729 } 3730 3731 cil_list_for_each(curr, sensorder->sens_list_str) { 3732 if (curr->data == CIL_KEY_UNORDERED) { 3733 cil_log(CIL_ERR, "Sensitivy order cannot be unordered.\n"); 3734 rc = SEPOL_ERR; 3735 goto exit; 3736 } 3737 } 3738 3739 ast_node->data = sensorder; 3740 ast_node->flavor = CIL_SENSITIVITYORDER; 3741 3742 return SEPOL_OK; 3743 3744 exit: 3745 cil_tree_log(parse_current, CIL_ERR, "Bad sensitivityorder declaration"); 3746 cil_destroy_sensitivityorder(sensorder); 3747 return rc; 3748 } 3749 3750 void cil_destroy_sensitivityorder(struct cil_sensorder *sensorder) 3751 { 3752 if (sensorder == NULL) { 3753 return; 3754 } 3755 3756 if (sensorder->sens_list_str != NULL) { 3757 cil_list_destroy(&sensorder->sens_list_str, CIL_TRUE); 3758 } 3759 3760 free(sensorder); 3761 } 3762 3763 int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3764 { 3765 enum cil_syntax syntax[] = { 3766 CIL_SYN_STRING, 3767 CIL_SYN_STRING, 3768 CIL_SYN_STRING | CIL_SYN_LIST, 3769 CIL_SYN_END 3770 }; 3771 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3772 struct cil_senscat *senscat = NULL; 3773 int rc = SEPOL_ERR; 3774 3775 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3776 goto exit; 3777 } 3778 3779 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3780 if (rc != SEPOL_OK) { 3781 goto exit; 3782 } 3783 3784 cil_senscat_init(&senscat); 3785 3786 senscat->sens_str = parse_current->next->data; 3787 3788 rc = cil_fill_cats(parse_current->next->next, &senscat->cats); 3789 if (rc != SEPOL_OK) { 3790 goto exit; 3791 } 3792 3793 ast_node->data = senscat; 3794 ast_node->flavor = CIL_SENSCAT; 3795 3796 return SEPOL_OK; 3797 3798 exit: 3799 cil_tree_log(parse_current, CIL_ERR, "Bad sensitivitycategory declaration"); 3800 cil_destroy_senscat(senscat); 3801 return rc; 3802 } 3803 3804 void cil_destroy_senscat(struct cil_senscat *senscat) 3805 { 3806 if (senscat == NULL) { 3807 return; 3808 } 3809 3810 cil_destroy_cats(senscat->cats); 3811 3812 free(senscat); 3813 } 3814 3815 int cil_gen_level(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3816 { 3817 enum cil_syntax syntax[] = { 3818 CIL_SYN_STRING, 3819 CIL_SYN_STRING, 3820 CIL_SYN_LIST, 3821 CIL_SYN_END 3822 }; 3823 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3824 char *key = NULL; 3825 struct cil_level *level = NULL; 3826 int rc = SEPOL_ERR; 3827 3828 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3829 goto exit; 3830 } 3831 3832 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3833 if (rc != SEPOL_OK) { 3834 goto exit; 3835 } 3836 3837 cil_level_init(&level); 3838 3839 key = parse_current->next->data; 3840 3841 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)level, (hashtab_key_t)key, CIL_SYM_LEVELS, CIL_LEVEL); 3842 if (rc != SEPOL_OK) { 3843 goto exit; 3844 } 3845 3846 rc = cil_fill_level(parse_current->next->next->cl_head, level); 3847 if (rc != SEPOL_OK) { 3848 goto exit; 3849 } 3850 3851 return SEPOL_OK; 3852 3853 exit: 3854 cil_tree_log(parse_current, CIL_ERR, "Bad level declaration"); 3855 cil_destroy_level(level); 3856 cil_clear_node(ast_node); 3857 return rc; 3858 } 3859 3860 void cil_destroy_level(struct cil_level *level) 3861 { 3862 if (level == NULL) { 3863 return; 3864 } 3865 3866 cil_symtab_datum_destroy(&level->datum); 3867 3868 cil_destroy_cats(level->cats); 3869 3870 free(level); 3871 } 3872 3873 /* low should be pointing to either the name of the low level or to an open paren for an anonymous low level */ 3874 int cil_fill_levelrange(struct cil_tree_node *low, struct cil_levelrange *lvlrange) 3875 { 3876 enum cil_syntax syntax[] = { 3877 CIL_SYN_STRING | CIL_SYN_LIST, 3878 CIL_SYN_STRING | CIL_SYN_LIST, 3879 CIL_SYN_END 3880 }; 3881 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3882 int rc = SEPOL_ERR; 3883 3884 if (low == NULL || lvlrange == NULL) { 3885 goto exit; 3886 } 3887 3888 rc = __cil_verify_syntax(low, syntax, syntax_len); 3889 if (rc != SEPOL_OK) { 3890 3891 goto exit; 3892 } 3893 3894 if (low->cl_head == NULL) { 3895 lvlrange->low_str = low->data; 3896 } else { 3897 cil_level_init(&lvlrange->low); 3898 rc = cil_fill_level(low->cl_head, lvlrange->low); 3899 if (rc != SEPOL_OK) { 3900 goto exit; 3901 } 3902 } 3903 3904 if (low->next->cl_head == NULL) { 3905 lvlrange->high_str = low->next->data; 3906 } else { 3907 cil_level_init(&lvlrange->high); 3908 rc = cil_fill_level(low->next->cl_head, lvlrange->high); 3909 if (rc != SEPOL_OK) { 3910 goto exit; 3911 } 3912 } 3913 3914 return SEPOL_OK; 3915 3916 exit: 3917 cil_log(CIL_ERR, "Bad levelrange\n"); 3918 return rc; 3919 } 3920 3921 int cil_gen_levelrange(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 3922 { 3923 enum cil_syntax syntax[] = { 3924 CIL_SYN_STRING, 3925 CIL_SYN_STRING, 3926 CIL_SYN_LIST, 3927 CIL_SYN_END 3928 }; 3929 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3930 char *key = NULL; 3931 struct cil_levelrange *lvlrange = NULL; 3932 int rc = SEPOL_ERR; 3933 3934 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3935 goto exit; 3936 } 3937 3938 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 3939 if (rc != SEPOL_OK) { 3940 goto exit; 3941 } 3942 3943 cil_levelrange_init(&lvlrange); 3944 3945 key = parse_current->next->data; 3946 3947 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)lvlrange, (hashtab_key_t)key, CIL_SYM_LEVELRANGES, CIL_LEVELRANGE); 3948 if (rc != SEPOL_OK) { 3949 goto exit; 3950 } 3951 3952 rc = cil_fill_levelrange(parse_current->next->next->cl_head, lvlrange); 3953 if (rc != SEPOL_OK) { 3954 goto exit; 3955 } 3956 3957 return SEPOL_OK; 3958 3959 exit: 3960 cil_tree_log(parse_current, CIL_ERR, "Bad levelrange declaration"); 3961 cil_destroy_levelrange(lvlrange); 3962 cil_clear_node(ast_node); 3963 return rc; 3964 } 3965 3966 void cil_destroy_levelrange(struct cil_levelrange *lvlrange) 3967 { 3968 if (lvlrange == NULL) { 3969 return; 3970 } 3971 3972 cil_symtab_datum_destroy(&lvlrange->datum); 3973 3974 if (lvlrange->low_str == NULL) { 3975 cil_destroy_level(lvlrange->low); 3976 } 3977 3978 if (lvlrange->high_str == NULL) { 3979 cil_destroy_level(lvlrange->high); 3980 } 3981 3982 free(lvlrange); 3983 } 3984 3985 int cil_gen_constrain(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) 3986 { 3987 enum cil_syntax syntax[] = { 3988 CIL_SYN_STRING, 3989 CIL_SYN_STRING | CIL_SYN_LIST, 3990 CIL_SYN_LIST, 3991 CIL_SYN_END 3992 }; 3993 int syntax_len = sizeof(syntax)/sizeof(*syntax); 3994 struct cil_constrain *cons = NULL; 3995 int rc = SEPOL_ERR; 3996 3997 if (db == NULL || parse_current == NULL || ast_node == NULL) { 3998 goto exit; 3999 } 4000 4001 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4002 if (rc != SEPOL_OK) { 4003 goto exit; 4004 } 4005 4006 cil_constrain_init(&cons); 4007 4008 rc = cil_fill_classperms_list(parse_current->next, &cons->classperms); 4009 if (rc != SEPOL_OK) { 4010 goto exit; 4011 } 4012 4013 rc = cil_gen_constraint_expr(parse_current->next->next, flavor, &cons->str_expr); 4014 if (rc != SEPOL_OK) { 4015 goto exit; 4016 } 4017 4018 ast_node->data = cons; 4019 ast_node->flavor = flavor; 4020 4021 return SEPOL_OK; 4022 4023 exit: 4024 cil_tree_log(parse_current, CIL_ERR, "Bad constrain declaration"); 4025 cil_destroy_constrain(cons); 4026 return rc; 4027 } 4028 4029 void cil_destroy_constrain(struct cil_constrain *cons) 4030 { 4031 if (cons == NULL) { 4032 return; 4033 } 4034 4035 cil_destroy_classperms_list(&cons->classperms); 4036 cil_list_destroy(&cons->str_expr, CIL_TRUE); 4037 cil_list_destroy(&cons->datum_expr, CIL_FALSE); 4038 4039 free(cons); 4040 } 4041 4042 int cil_gen_validatetrans(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) 4043 { 4044 enum cil_syntax syntax[] = { 4045 CIL_SYN_STRING, 4046 CIL_SYN_STRING, 4047 CIL_SYN_LIST, 4048 CIL_SYN_END 4049 }; 4050 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4051 struct cil_validatetrans *validtrans = NULL; 4052 int rc = SEPOL_ERR; 4053 4054 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4055 goto exit; 4056 } 4057 4058 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4059 if (rc != SEPOL_OK) { 4060 goto exit; 4061 } 4062 4063 cil_validatetrans_init(&validtrans); 4064 4065 validtrans->class_str = parse_current->next->data; 4066 4067 rc = cil_gen_constraint_expr(parse_current->next->next, flavor, &validtrans->str_expr); 4068 if (rc != SEPOL_OK) { 4069 goto exit; 4070 } 4071 4072 ast_node->data = validtrans; 4073 ast_node->flavor = flavor; 4074 4075 return SEPOL_OK; 4076 4077 exit: 4078 cil_tree_log(parse_current, CIL_ERR, "Bad validatetrans declaration"); 4079 cil_destroy_validatetrans(validtrans); 4080 return rc; 4081 4082 4083 } 4084 4085 void cil_destroy_validatetrans(struct cil_validatetrans *validtrans) 4086 { 4087 if (validtrans == NULL) { 4088 return; 4089 } 4090 4091 cil_list_destroy(&validtrans->str_expr, CIL_TRUE); 4092 cil_list_destroy(&validtrans->datum_expr, CIL_FALSE); 4093 4094 free(validtrans); 4095 } 4096 4097 /* Fills in context starting from user */ 4098 int cil_fill_context(struct cil_tree_node *user_node, struct cil_context *context) 4099 { 4100 enum cil_syntax syntax[] = { 4101 CIL_SYN_STRING, 4102 CIL_SYN_STRING, 4103 CIL_SYN_STRING, 4104 CIL_SYN_STRING | CIL_SYN_LIST, 4105 CIL_SYN_END 4106 }; 4107 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4108 int rc = SEPOL_ERR; 4109 4110 if (user_node == NULL || context == NULL) { 4111 goto exit; 4112 } 4113 4114 rc = __cil_verify_syntax(user_node, syntax, syntax_len); 4115 if (rc != SEPOL_OK) { 4116 goto exit; 4117 } 4118 4119 context->user_str = user_node->data; 4120 context->role_str = user_node->next->data; 4121 context->type_str = user_node->next->next->data; 4122 4123 context->range_str = NULL; 4124 4125 if (user_node->next->next->next->cl_head == NULL) { 4126 context->range_str = user_node->next->next->next->data; 4127 } else { 4128 cil_levelrange_init(&context->range); 4129 4130 rc = cil_fill_levelrange(user_node->next->next->next->cl_head, context->range); 4131 if (rc != SEPOL_OK) { 4132 goto exit; 4133 } 4134 } 4135 4136 return SEPOL_OK; 4137 4138 exit: 4139 cil_log(CIL_ERR, "Bad context\n"); 4140 return rc; 4141 } 4142 4143 int cil_gen_context(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4144 { 4145 enum cil_syntax syntax[] = { 4146 CIL_SYN_STRING, 4147 CIL_SYN_STRING, 4148 CIL_SYN_LIST, 4149 CIL_SYN_END 4150 }; 4151 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4152 char *key = NULL; 4153 struct cil_context *context = NULL; 4154 int rc = SEPOL_ERR; 4155 4156 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4157 goto exit; 4158 } 4159 4160 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4161 if (rc != SEPOL_OK) { 4162 goto exit; 4163 } 4164 4165 cil_context_init(&context); 4166 4167 key = parse_current->next->data; 4168 4169 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)context, (hashtab_key_t)key, CIL_SYM_CONTEXTS, CIL_CONTEXT); 4170 if (rc != SEPOL_OK) { 4171 goto exit; 4172 } 4173 4174 rc = cil_fill_context(parse_current->next->next->cl_head, context); 4175 if (rc != SEPOL_OK) { 4176 goto exit; 4177 } 4178 4179 return SEPOL_OK; 4180 4181 exit: 4182 cil_tree_log(parse_current, CIL_ERR, "Bad context declaration"); 4183 cil_destroy_context(context); 4184 cil_clear_node(ast_node); 4185 return SEPOL_ERR; 4186 } 4187 4188 void cil_destroy_context(struct cil_context *context) 4189 { 4190 if (context == NULL) { 4191 return; 4192 } 4193 4194 cil_symtab_datum_destroy(&context->datum);; 4195 4196 if (context->range_str == NULL && context->range != NULL) { 4197 cil_destroy_levelrange(context->range); 4198 } 4199 4200 free(context); 4201 } 4202 4203 int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4204 { 4205 enum cil_syntax syntax[] = { 4206 CIL_SYN_STRING, 4207 CIL_SYN_STRING, 4208 CIL_SYN_STRING, 4209 CIL_SYN_STRING | CIL_SYN_LIST | CIL_SYN_EMPTY_LIST, 4210 CIL_SYN_END 4211 }; 4212 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4213 int rc = SEPOL_ERR; 4214 struct cil_filecon *filecon = NULL; 4215 char *type = NULL; 4216 4217 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4218 goto exit; 4219 } 4220 4221 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4222 if (rc != SEPOL_OK) { 4223 goto exit; 4224 } 4225 4226 type = parse_current->next->next->data; 4227 cil_filecon_init(&filecon); 4228 4229 filecon->path_str = parse_current->next->data; 4230 4231 if (type == CIL_KEY_FILE) { 4232 filecon->type = CIL_FILECON_FILE; 4233 } else if (type == CIL_KEY_DIR) { 4234 filecon->type = CIL_FILECON_DIR; 4235 } else if (type == CIL_KEY_CHAR) { 4236 filecon->type = CIL_FILECON_CHAR; 4237 } else if (type == CIL_KEY_BLOCK) { 4238 filecon->type = CIL_FILECON_BLOCK; 4239 } else if (type == CIL_KEY_SOCKET) { 4240 filecon->type = CIL_FILECON_SOCKET; 4241 } else if (type == CIL_KEY_PIPE) { 4242 filecon->type = CIL_FILECON_PIPE; 4243 } else if (type == CIL_KEY_SYMLINK) { 4244 filecon->type = CIL_FILECON_SYMLINK; 4245 } else if (type == CIL_KEY_ANY) { 4246 filecon->type = CIL_FILECON_ANY; 4247 } else { 4248 cil_log(CIL_ERR, "Invalid file type\n"); 4249 rc = SEPOL_ERR; 4250 goto exit; 4251 } 4252 4253 if (parse_current->next->next->next->cl_head == NULL) { 4254 filecon->context_str = parse_current->next->next->next->data; 4255 } else { 4256 if (parse_current->next->next->next->cl_head->next == NULL) { 4257 filecon->context = NULL; 4258 } else { 4259 cil_context_init(&filecon->context); 4260 4261 rc = cil_fill_context(parse_current->next->next->next->cl_head, filecon->context); 4262 if (rc != SEPOL_OK) { 4263 goto exit; 4264 } 4265 } 4266 } 4267 4268 ast_node->data = filecon; 4269 ast_node->flavor = CIL_FILECON; 4270 4271 return SEPOL_OK; 4272 4273 exit: 4274 cil_tree_log(parse_current, CIL_ERR, "Bad filecon declaration"); 4275 cil_destroy_filecon(filecon); 4276 return rc; 4277 } 4278 4279 //TODO: Should we be checking if the pointer is NULL when passed in? 4280 void cil_destroy_filecon(struct cil_filecon *filecon) 4281 { 4282 if (filecon == NULL) { 4283 return; 4284 } 4285 4286 if (filecon->context_str == NULL && filecon->context != NULL) { 4287 cil_destroy_context(filecon->context); 4288 } 4289 4290 free(filecon); 4291 } 4292 4293 int cil_gen_ibpkeycon(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4294 { 4295 enum cil_syntax syntax[] = { 4296 CIL_SYN_STRING, 4297 CIL_SYN_STRING, 4298 CIL_SYN_STRING | CIL_SYN_LIST, 4299 CIL_SYN_STRING | CIL_SYN_LIST, 4300 CIL_SYN_END 4301 }; 4302 int syntax_len = sizeof(syntax) / sizeof(*syntax); 4303 int rc = SEPOL_ERR; 4304 struct cil_ibpkeycon *ibpkeycon = NULL; 4305 4306 if (!parse_current || !ast_node) 4307 goto exit; 4308 4309 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4310 if (rc != SEPOL_OK) 4311 goto exit; 4312 4313 cil_ibpkeycon_init(&ibpkeycon); 4314 4315 ibpkeycon->subnet_prefix_str = parse_current->next->data; 4316 4317 if (parse_current->next->next->cl_head) { 4318 if (parse_current->next->next->cl_head->next && 4319 !parse_current->next->next->cl_head->next->next) { 4320 rc = cil_fill_integer(parse_current->next->next->cl_head, &ibpkeycon->pkey_low, 0); 4321 if (rc != SEPOL_OK) { 4322 cil_log(CIL_ERR, "Improper ibpkey specified\n"); 4323 goto exit; 4324 } 4325 rc = cil_fill_integer(parse_current->next->next->cl_head->next, &ibpkeycon->pkey_high, 0); 4326 if (rc != SEPOL_OK) { 4327 cil_log(CIL_ERR, "Improper ibpkey specified\n"); 4328 goto exit; 4329 } 4330 } else { 4331 cil_log(CIL_ERR, "Improper ibpkey range specified\n"); 4332 rc = SEPOL_ERR; 4333 goto exit; 4334 } 4335 } else { 4336 rc = cil_fill_integer(parse_current->next->next, &ibpkeycon->pkey_low, 0); 4337 if (rc != SEPOL_OK) { 4338 cil_log(CIL_ERR, "Improper ibpkey specified\n"); 4339 goto exit; 4340 } 4341 ibpkeycon->pkey_high = ibpkeycon->pkey_low; 4342 } 4343 4344 if (!parse_current->next->next->next->cl_head) { 4345 ibpkeycon->context_str = parse_current->next->next->next->data; 4346 } else { 4347 cil_context_init(&ibpkeycon->context); 4348 4349 rc = cil_fill_context(parse_current->next->next->next->cl_head, ibpkeycon->context); 4350 if (rc != SEPOL_OK) 4351 goto exit; 4352 } 4353 4354 ast_node->data = ibpkeycon; 4355 ast_node->flavor = CIL_IBPKEYCON; 4356 return SEPOL_OK; 4357 4358 exit: 4359 cil_tree_log(parse_current, CIL_ERR, "Bad ibpkeycon declaration"); 4360 cil_destroy_ibpkeycon(ibpkeycon); 4361 4362 return rc; 4363 } 4364 4365 void cil_destroy_ibpkeycon(struct cil_ibpkeycon *ibpkeycon) 4366 { 4367 if (!ibpkeycon) 4368 return; 4369 4370 if (!ibpkeycon->context_str && ibpkeycon->context) 4371 cil_destroy_context(ibpkeycon->context); 4372 4373 free(ibpkeycon); 4374 } 4375 4376 int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4377 { 4378 enum cil_syntax syntax[] = { 4379 CIL_SYN_STRING, 4380 CIL_SYN_STRING, 4381 CIL_SYN_STRING | CIL_SYN_LIST, 4382 CIL_SYN_STRING | CIL_SYN_LIST, 4383 CIL_SYN_END 4384 }; 4385 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4386 int rc = SEPOL_ERR; 4387 struct cil_portcon *portcon = NULL; 4388 char *proto; 4389 4390 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4391 goto exit; 4392 } 4393 4394 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4395 if (rc != SEPOL_OK) { 4396 goto exit; 4397 } 4398 4399 cil_portcon_init(&portcon); 4400 4401 proto = parse_current->next->data; 4402 if (proto == CIL_KEY_UDP) { 4403 portcon->proto = CIL_PROTOCOL_UDP; 4404 } else if (proto == CIL_KEY_TCP) { 4405 portcon->proto = CIL_PROTOCOL_TCP; 4406 } else if (proto == CIL_KEY_DCCP) { 4407 portcon->proto = CIL_PROTOCOL_DCCP; 4408 } else { 4409 cil_log(CIL_ERR, "Invalid protocol\n"); 4410 rc = SEPOL_ERR; 4411 goto exit; 4412 } 4413 4414 if (parse_current->next->next->cl_head != NULL) { 4415 if (parse_current->next->next->cl_head->next != NULL 4416 && parse_current->next->next->cl_head->next->next == NULL) { 4417 rc = cil_fill_integer(parse_current->next->next->cl_head, &portcon->port_low, 10); 4418 if (rc != SEPOL_OK) { 4419 cil_log(CIL_ERR, "Improper port specified\n"); 4420 goto exit; 4421 } 4422 rc = cil_fill_integer(parse_current->next->next->cl_head->next, &portcon->port_high, 10); 4423 if (rc != SEPOL_OK) { 4424 cil_log(CIL_ERR, "Improper port specified\n"); 4425 goto exit; 4426 } 4427 } else { 4428 cil_log(CIL_ERR, "Improper port range specified\n"); 4429 rc = SEPOL_ERR; 4430 goto exit; 4431 } 4432 } else { 4433 rc = cil_fill_integer(parse_current->next->next, &portcon->port_low, 10); 4434 if (rc != SEPOL_OK) { 4435 cil_log(CIL_ERR, "Improper port specified\n"); 4436 goto exit; 4437 } 4438 portcon->port_high = portcon->port_low; 4439 } 4440 4441 if (parse_current->next->next->next->cl_head == NULL ) { 4442 portcon->context_str = parse_current->next->next->next->data; 4443 } else { 4444 cil_context_init(&portcon->context); 4445 4446 rc = cil_fill_context(parse_current->next->next->next->cl_head, portcon->context); 4447 if (rc != SEPOL_OK) { 4448 goto exit; 4449 } 4450 } 4451 4452 ast_node->data = portcon; 4453 ast_node->flavor = CIL_PORTCON; 4454 4455 return SEPOL_OK; 4456 4457 exit: 4458 cil_tree_log(parse_current, CIL_ERR, "Bad portcon declaration"); 4459 cil_destroy_portcon(portcon); 4460 return rc; 4461 } 4462 4463 void cil_destroy_portcon(struct cil_portcon *portcon) 4464 { 4465 if (portcon == NULL) { 4466 return; 4467 } 4468 4469 if (portcon->context_str == NULL && portcon->context != NULL) { 4470 cil_destroy_context(portcon->context); 4471 } 4472 4473 free(portcon); 4474 } 4475 4476 int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4477 { 4478 enum cil_syntax syntax[] = { 4479 CIL_SYN_STRING, 4480 CIL_SYN_STRING | CIL_SYN_LIST, 4481 CIL_SYN_STRING | CIL_SYN_LIST, 4482 CIL_SYN_STRING | CIL_SYN_LIST, 4483 CIL_SYN_END 4484 }; 4485 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4486 int rc = SEPOL_ERR; 4487 struct cil_nodecon *nodecon = NULL; 4488 4489 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4490 goto exit; 4491 } 4492 4493 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4494 if (rc != SEPOL_OK) { 4495 goto exit; 4496 } 4497 4498 cil_nodecon_init(&nodecon); 4499 4500 if (parse_current->next->cl_head == NULL ) { 4501 nodecon->addr_str = parse_current->next->data; 4502 } else { 4503 cil_ipaddr_init(&nodecon->addr); 4504 4505 rc = cil_fill_ipaddr(parse_current->next->cl_head, nodecon->addr); 4506 if (rc != SEPOL_OK) { 4507 goto exit; 4508 } 4509 } 4510 4511 if (parse_current->next->next->cl_head == NULL ) { 4512 nodecon->mask_str = parse_current->next->next->data; 4513 } else { 4514 cil_ipaddr_init(&nodecon->mask); 4515 4516 rc = cil_fill_ipaddr(parse_current->next->next->cl_head, nodecon->mask); 4517 if (rc != SEPOL_OK) { 4518 goto exit; 4519 } 4520 } 4521 4522 if (parse_current->next->next->next->cl_head == NULL ) { 4523 nodecon->context_str = parse_current->next->next->next->data; 4524 } else { 4525 cil_context_init(&nodecon->context); 4526 4527 rc = cil_fill_context(parse_current->next->next->next->cl_head, nodecon->context); 4528 if (rc != SEPOL_OK) { 4529 goto exit; 4530 } 4531 } 4532 4533 ast_node->data = nodecon; 4534 ast_node->flavor = CIL_NODECON; 4535 4536 return SEPOL_OK; 4537 4538 exit: 4539 cil_tree_log(parse_current, CIL_ERR, "Bad nodecon declaration"); 4540 cil_destroy_nodecon(nodecon); 4541 return rc; 4542 } 4543 4544 void cil_destroy_nodecon(struct cil_nodecon *nodecon) 4545 { 4546 if (nodecon == NULL) { 4547 return; 4548 } 4549 4550 if (nodecon->addr_str == NULL && nodecon->addr != NULL) { 4551 cil_destroy_ipaddr(nodecon->addr); 4552 } 4553 4554 if (nodecon->mask_str == NULL && nodecon->mask != NULL) { 4555 cil_destroy_ipaddr(nodecon->mask); 4556 } 4557 4558 if (nodecon->context_str == NULL && nodecon->context != NULL) { 4559 cil_destroy_context(nodecon->context); 4560 } 4561 4562 free(nodecon); 4563 } 4564 4565 int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4566 { 4567 enum cil_syntax syntax[] = { 4568 CIL_SYN_STRING, 4569 CIL_SYN_STRING, 4570 CIL_SYN_STRING, 4571 CIL_SYN_STRING | CIL_SYN_LIST, 4572 CIL_SYN_END 4573 }; 4574 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4575 int rc = SEPOL_ERR; 4576 struct cil_genfscon *genfscon = NULL; 4577 4578 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4579 goto exit; 4580 } 4581 4582 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4583 if (rc != SEPOL_OK) { 4584 goto exit; 4585 } 4586 4587 cil_genfscon_init(&genfscon); 4588 4589 genfscon->fs_str = parse_current->next->data; 4590 genfscon->path_str = parse_current->next->next->data; 4591 4592 if (parse_current->next->next->next->cl_head == NULL ) { 4593 genfscon->context_str = parse_current->next->next->next->data; 4594 } else { 4595 cil_context_init(&genfscon->context); 4596 4597 rc = cil_fill_context(parse_current->next->next->next->cl_head, genfscon->context); 4598 if (rc != SEPOL_OK) { 4599 goto exit; 4600 } 4601 } 4602 4603 ast_node->data = genfscon; 4604 ast_node->flavor = CIL_GENFSCON; 4605 4606 return SEPOL_OK; 4607 4608 exit: 4609 cil_tree_log(parse_current, CIL_ERR, "Bad genfscon declaration"); 4610 cil_destroy_genfscon(genfscon); 4611 return SEPOL_ERR; 4612 } 4613 4614 void cil_destroy_genfscon(struct cil_genfscon *genfscon) 4615 { 4616 if (genfscon == NULL) { 4617 return; 4618 } 4619 4620 if (genfscon->context_str == NULL && genfscon->context != NULL) { 4621 cil_destroy_context(genfscon->context); 4622 } 4623 4624 free(genfscon); 4625 } 4626 4627 4628 int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4629 { 4630 enum cil_syntax syntax[] = { 4631 CIL_SYN_STRING, 4632 CIL_SYN_STRING, 4633 CIL_SYN_STRING | CIL_SYN_LIST, 4634 CIL_SYN_STRING | CIL_SYN_LIST, 4635 CIL_SYN_END 4636 }; 4637 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4638 int rc = SEPOL_ERR; 4639 struct cil_netifcon *netifcon = NULL; 4640 4641 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4642 goto exit; 4643 } 4644 4645 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4646 if (rc != SEPOL_OK) { 4647 goto exit; 4648 } 4649 4650 cil_netifcon_init(&netifcon); 4651 4652 netifcon->interface_str = parse_current->next->data; 4653 4654 if (parse_current->next->next->cl_head == NULL) { 4655 netifcon->if_context_str = parse_current->next->next->data; 4656 } else { 4657 cil_context_init(&netifcon->if_context); 4658 4659 rc = cil_fill_context(parse_current->next->next->cl_head, netifcon->if_context); 4660 if (rc != SEPOL_OK) { 4661 goto exit; 4662 } 4663 } 4664 4665 if (parse_current->next->next->next->cl_head == NULL) { 4666 netifcon->packet_context_str = parse_current->next->next->next->data; 4667 } else { 4668 cil_context_init(&netifcon->packet_context); 4669 4670 rc = cil_fill_context(parse_current->next->next->next->cl_head, netifcon->packet_context); 4671 if (rc != SEPOL_OK) { 4672 goto exit; 4673 } 4674 } 4675 4676 ast_node->data = netifcon; 4677 ast_node->flavor = CIL_NETIFCON; 4678 4679 return SEPOL_OK; 4680 4681 exit: 4682 cil_tree_log(parse_current, CIL_ERR, "Bad netifcon declaration"); 4683 cil_destroy_netifcon(netifcon); 4684 return SEPOL_ERR; 4685 } 4686 4687 void cil_destroy_netifcon(struct cil_netifcon *netifcon) 4688 { 4689 if (netifcon == NULL) { 4690 return; 4691 } 4692 4693 if (netifcon->if_context_str == NULL && netifcon->if_context != NULL) { 4694 cil_destroy_context(netifcon->if_context); 4695 } 4696 4697 if (netifcon->packet_context_str == NULL && netifcon->packet_context != NULL) { 4698 cil_destroy_context(netifcon->packet_context); 4699 } 4700 4701 free(netifcon); 4702 } 4703 4704 int cil_gen_ibendportcon(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4705 { 4706 enum cil_syntax syntax[] = { 4707 CIL_SYN_STRING, 4708 CIL_SYN_STRING, 4709 CIL_SYN_STRING, 4710 CIL_SYN_STRING | CIL_SYN_LIST, 4711 CIL_SYN_END 4712 }; 4713 int syntax_len = sizeof(syntax) / sizeof(*syntax); 4714 int rc = SEPOL_ERR; 4715 struct cil_ibendportcon *ibendportcon = NULL; 4716 4717 if (!parse_current || !ast_node) 4718 goto exit; 4719 4720 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4721 if (rc != SEPOL_OK) 4722 goto exit; 4723 4724 cil_ibendportcon_init(&ibendportcon); 4725 4726 ibendportcon->dev_name_str = parse_current->next->data; 4727 4728 rc = cil_fill_integer(parse_current->next->next, &ibendportcon->port, 10); 4729 if (rc != SEPOL_OK) { 4730 cil_log(CIL_ERR, "Improper ibendport port specified\n"); 4731 goto exit; 4732 } 4733 4734 if (!parse_current->next->next->next->cl_head) { 4735 ibendportcon->context_str = parse_current->next->next->next->data; 4736 } else { 4737 cil_context_init(&ibendportcon->context); 4738 4739 rc = cil_fill_context(parse_current->next->next->next->cl_head, ibendportcon->context); 4740 if (rc != SEPOL_OK) 4741 goto exit; 4742 } 4743 4744 ast_node->data = ibendportcon; 4745 ast_node->flavor = CIL_IBENDPORTCON; 4746 4747 return SEPOL_OK; 4748 4749 exit: 4750 cil_tree_log(parse_current, CIL_ERR, "Bad ibendportcon declaration"); 4751 cil_destroy_ibendportcon(ibendportcon); 4752 return SEPOL_ERR; 4753 } 4754 4755 void cil_destroy_ibendportcon(struct cil_ibendportcon *ibendportcon) 4756 { 4757 if (!ibendportcon) 4758 return; 4759 4760 if (!ibendportcon->context_str && ibendportcon->context) 4761 cil_destroy_context(ibendportcon->context); 4762 4763 free(ibendportcon); 4764 } 4765 4766 int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4767 { 4768 enum cil_syntax syntax[] = { 4769 CIL_SYN_STRING, 4770 CIL_SYN_STRING, 4771 CIL_SYN_STRING | CIL_SYN_LIST, 4772 CIL_SYN_END 4773 }; 4774 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4775 int rc = SEPOL_ERR; 4776 struct cil_pirqcon *pirqcon = NULL; 4777 4778 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4779 goto exit; 4780 } 4781 4782 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4783 if (rc != SEPOL_OK) { 4784 goto exit; 4785 } 4786 4787 cil_pirqcon_init(&pirqcon); 4788 4789 rc = cil_fill_integer(parse_current->next, &pirqcon->pirq, 10); 4790 if (rc != SEPOL_OK) { 4791 goto exit; 4792 } 4793 4794 if (parse_current->next->next->cl_head == NULL) { 4795 pirqcon->context_str = parse_current->next->next->data; 4796 } else { 4797 cil_context_init(&pirqcon->context); 4798 4799 rc = cil_fill_context(parse_current->next->next->cl_head, pirqcon->context); 4800 if (rc != SEPOL_OK) { 4801 goto exit; 4802 } 4803 } 4804 4805 ast_node->data = pirqcon; 4806 ast_node->flavor = CIL_PIRQCON; 4807 4808 return SEPOL_OK; 4809 4810 exit: 4811 cil_tree_log(parse_current, CIL_ERR, "Bad pirqcon declaration"); 4812 cil_destroy_pirqcon(pirqcon); 4813 return rc; 4814 } 4815 4816 void cil_destroy_pirqcon(struct cil_pirqcon *pirqcon) 4817 { 4818 if (pirqcon == NULL) { 4819 return; 4820 } 4821 4822 if (pirqcon->context_str == NULL && pirqcon->context != NULL) { 4823 cil_destroy_context(pirqcon->context); 4824 } 4825 4826 free(pirqcon); 4827 } 4828 4829 int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4830 { 4831 enum cil_syntax syntax[] = { 4832 CIL_SYN_STRING, 4833 CIL_SYN_STRING | CIL_SYN_LIST, 4834 CIL_SYN_STRING | CIL_SYN_LIST, 4835 CIL_SYN_END 4836 }; 4837 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4838 int rc = SEPOL_ERR; 4839 struct cil_iomemcon *iomemcon = NULL; 4840 4841 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4842 goto exit; 4843 } 4844 4845 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4846 if (rc != SEPOL_OK) { 4847 goto exit; 4848 } 4849 4850 cil_iomemcon_init(&iomemcon); 4851 4852 if (parse_current->next->cl_head != NULL) { 4853 if (parse_current->next->cl_head->next != NULL && 4854 parse_current->next->cl_head->next->next == NULL) { 4855 rc = cil_fill_integer64(parse_current->next->cl_head, &iomemcon->iomem_low, 0); 4856 if (rc != SEPOL_OK) { 4857 cil_log(CIL_ERR, "Improper iomem specified\n"); 4858 goto exit; 4859 } 4860 rc = cil_fill_integer64(parse_current->next->cl_head->next, &iomemcon->iomem_high, 0); 4861 if (rc != SEPOL_OK) { 4862 cil_log(CIL_ERR, "Improper iomem specified\n"); 4863 goto exit; 4864 } 4865 } else { 4866 cil_log(CIL_ERR, "Improper iomem range specified\n"); 4867 rc = SEPOL_ERR; 4868 goto exit; 4869 } 4870 } else { 4871 rc = cil_fill_integer64(parse_current->next, &iomemcon->iomem_low, 0); 4872 if (rc != SEPOL_OK) { 4873 cil_log(CIL_ERR, "Improper iomem specified\n"); 4874 goto exit; 4875 } 4876 iomemcon->iomem_high = iomemcon->iomem_low; 4877 } 4878 4879 if (parse_current->next->next->cl_head == NULL ) { 4880 iomemcon->context_str = parse_current->next->next->data; 4881 } else { 4882 cil_context_init(&iomemcon->context); 4883 4884 rc = cil_fill_context(parse_current->next->next->cl_head, iomemcon->context); 4885 if (rc != SEPOL_OK) { 4886 goto exit; 4887 } 4888 } 4889 4890 ast_node->data = iomemcon; 4891 ast_node->flavor = CIL_IOMEMCON; 4892 4893 return SEPOL_OK; 4894 4895 exit: 4896 cil_tree_log(parse_current, CIL_ERR, "Bad iomemcon declaration"); 4897 cil_destroy_iomemcon(iomemcon); 4898 return rc; 4899 } 4900 4901 void cil_destroy_iomemcon(struct cil_iomemcon *iomemcon) 4902 { 4903 if (iomemcon == NULL) { 4904 return; 4905 } 4906 4907 if (iomemcon->context_str == NULL && iomemcon->context != NULL) { 4908 cil_destroy_context(iomemcon->context); 4909 } 4910 4911 free(iomemcon); 4912 } 4913 4914 int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 4915 { 4916 enum cil_syntax syntax[] = { 4917 CIL_SYN_STRING, 4918 CIL_SYN_STRING | CIL_SYN_LIST, 4919 CIL_SYN_STRING | CIL_SYN_LIST, 4920 CIL_SYN_END 4921 }; 4922 int syntax_len = sizeof(syntax)/sizeof(*syntax); 4923 int rc = SEPOL_ERR; 4924 struct cil_ioportcon *ioportcon = NULL; 4925 4926 if (db == NULL || parse_current == NULL || ast_node == NULL) { 4927 goto exit; 4928 } 4929 4930 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 4931 if (rc != SEPOL_OK) { 4932 goto exit; 4933 } 4934 4935 cil_ioportcon_init(&ioportcon); 4936 4937 if (parse_current->next->cl_head != NULL) { 4938 if (parse_current->next->cl_head->next != NULL && 4939 parse_current->next->cl_head->next->next == NULL) { 4940 rc = cil_fill_integer(parse_current->next->cl_head, &ioportcon->ioport_low, 0); 4941 if (rc != SEPOL_OK) { 4942 cil_log(CIL_ERR, "Improper ioport specified\n"); 4943 goto exit; 4944 } 4945 rc = cil_fill_integer(parse_current->next->cl_head->next, &ioportcon->ioport_high, 0); 4946 if (rc != SEPOL_OK) { 4947 cil_log(CIL_ERR, "Improper ioport specified\n"); 4948 goto exit; 4949 } 4950 } else { 4951 cil_log(CIL_ERR, "Improper ioport range specified\n"); 4952 rc = SEPOL_ERR; 4953 goto exit; 4954 } 4955 } else { 4956 rc = cil_fill_integer(parse_current->next, &ioportcon->ioport_low, 0); 4957 if (rc != SEPOL_OK) { 4958 cil_log(CIL_ERR, "Improper ioport specified\n"); 4959 goto exit; 4960 } 4961 ioportcon->ioport_high = ioportcon->ioport_low; 4962 } 4963 4964 if (parse_current->next->next->cl_head == NULL ) { 4965 ioportcon->context_str = parse_current->next->next->data; 4966 } else { 4967 cil_context_init(&ioportcon->context); 4968 4969 rc = cil_fill_context(parse_current->next->next->cl_head, ioportcon->context); 4970 if (rc != SEPOL_OK) { 4971 goto exit; 4972 } 4973 } 4974 4975 ast_node->data = ioportcon; 4976 ast_node->flavor = CIL_IOPORTCON; 4977 4978 return SEPOL_OK; 4979 4980 exit: 4981 cil_tree_log(parse_current, CIL_ERR, "Bad ioportcon declaration"); 4982 cil_destroy_ioportcon(ioportcon); 4983 return rc; 4984 } 4985 4986 void cil_destroy_ioportcon(struct cil_ioportcon *ioportcon) 4987 { 4988 if (ioportcon == NULL) { 4989 return; 4990 } 4991 4992 if (ioportcon->context_str == NULL && ioportcon->context != NULL) { 4993 cil_destroy_context(ioportcon->context); 4994 } 4995 4996 free(ioportcon); 4997 } 4998 4999 int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5000 { 5001 enum cil_syntax syntax[] = { 5002 CIL_SYN_STRING, 5003 CIL_SYN_STRING, 5004 CIL_SYN_STRING | CIL_SYN_LIST, 5005 CIL_SYN_END 5006 }; 5007 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5008 int rc = SEPOL_ERR; 5009 struct cil_pcidevicecon *pcidevicecon = NULL; 5010 5011 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5012 goto exit; 5013 } 5014 5015 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5016 if (rc != SEPOL_OK) { 5017 goto exit; 5018 } 5019 5020 cil_pcidevicecon_init(&pcidevicecon); 5021 5022 rc = cil_fill_integer(parse_current->next, &pcidevicecon->dev, 0); 5023 if (rc != SEPOL_OK) { 5024 goto exit; 5025 } 5026 5027 if (parse_current->next->next->cl_head == NULL) { 5028 pcidevicecon->context_str = parse_current->next->next->data; 5029 } else { 5030 cil_context_init(&pcidevicecon->context); 5031 5032 rc = cil_fill_context(parse_current->next->next->cl_head, pcidevicecon->context); 5033 if (rc != SEPOL_OK) { 5034 goto exit; 5035 } 5036 } 5037 5038 ast_node->data = pcidevicecon; 5039 ast_node->flavor = CIL_PCIDEVICECON; 5040 5041 return SEPOL_OK; 5042 5043 exit: 5044 cil_tree_log(parse_current, CIL_ERR, "Bad pcidevicecon declaration"); 5045 cil_destroy_pcidevicecon(pcidevicecon); 5046 return rc; 5047 } 5048 5049 void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon) 5050 { 5051 if (pcidevicecon == NULL) { 5052 return; 5053 } 5054 5055 if (pcidevicecon->context_str == NULL && pcidevicecon->context != NULL) { 5056 cil_destroy_context(pcidevicecon->context); 5057 } 5058 5059 free(pcidevicecon); 5060 } 5061 5062 int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5063 { 5064 enum cil_syntax syntax[] = { 5065 CIL_SYN_STRING, 5066 CIL_SYN_STRING, 5067 CIL_SYN_STRING | CIL_SYN_LIST, 5068 CIL_SYN_END 5069 }; 5070 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5071 int rc = SEPOL_ERR; 5072 struct cil_devicetreecon *devicetreecon = NULL; 5073 5074 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5075 goto exit; 5076 } 5077 5078 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5079 if (rc != SEPOL_OK) { 5080 goto exit; 5081 } 5082 5083 cil_devicetreecon_init(&devicetreecon); 5084 5085 devicetreecon->path = parse_current->next->data; 5086 5087 if (parse_current->next->next->cl_head == NULL) { 5088 devicetreecon->context_str = parse_current->next->next->data; 5089 } else { 5090 cil_context_init(&devicetreecon->context); 5091 5092 rc = cil_fill_context(parse_current->next->next->cl_head, devicetreecon->context); 5093 if (rc != SEPOL_OK) { 5094 goto exit; 5095 } 5096 } 5097 5098 ast_node->data = devicetreecon; 5099 ast_node->flavor = CIL_DEVICETREECON; 5100 5101 return SEPOL_OK; 5102 5103 exit: 5104 cil_tree_log(parse_current, CIL_ERR, "Bad devicetreecon declaration"); 5105 cil_destroy_devicetreecon(devicetreecon); 5106 return rc; 5107 } 5108 5109 void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon) 5110 { 5111 if (devicetreecon == NULL) { 5112 return; 5113 } 5114 5115 if (devicetreecon->context_str == NULL && devicetreecon->context != NULL) { 5116 cil_destroy_context(devicetreecon->context); 5117 } 5118 5119 free(devicetreecon); 5120 } 5121 5122 int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5123 { 5124 enum cil_syntax syntax[] = { 5125 CIL_SYN_STRING, 5126 CIL_SYN_STRING, 5127 CIL_SYN_STRING, 5128 CIL_SYN_STRING | CIL_SYN_LIST, 5129 CIL_SYN_END 5130 }; 5131 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5132 char *type = NULL; 5133 struct cil_fsuse *fsuse = NULL; 5134 int rc = SEPOL_ERR; 5135 5136 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5137 goto exit; 5138 } 5139 5140 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5141 if (rc != SEPOL_OK) { 5142 goto exit; 5143 } 5144 5145 type = parse_current->next->data; 5146 5147 cil_fsuse_init(&fsuse); 5148 5149 if (type == CIL_KEY_XATTR) { 5150 fsuse->type = CIL_FSUSE_XATTR; 5151 } else if (type == CIL_KEY_TASK) { 5152 fsuse->type = CIL_FSUSE_TASK; 5153 } else if (type == CIL_KEY_TRANS) { 5154 fsuse->type = CIL_FSUSE_TRANS; 5155 } else { 5156 cil_log(CIL_ERR, "Invalid fsuse type\n"); 5157 goto exit; 5158 } 5159 5160 fsuse->fs_str = parse_current->next->next->data; 5161 5162 if (parse_current->next->next->next->cl_head == NULL) { 5163 fsuse->context_str = parse_current->next->next->next->data; 5164 } else { 5165 cil_context_init(&fsuse->context); 5166 5167 rc = cil_fill_context(parse_current->next->next->next->cl_head, fsuse->context); 5168 if (rc != SEPOL_OK) { 5169 goto exit; 5170 } 5171 } 5172 5173 ast_node->data = fsuse; 5174 ast_node->flavor = CIL_FSUSE; 5175 5176 return SEPOL_OK; 5177 5178 exit: 5179 cil_tree_log(parse_current, CIL_ERR, "Bad fsuse declaration"); 5180 cil_destroy_fsuse(fsuse); 5181 return SEPOL_ERR; 5182 } 5183 5184 void cil_destroy_fsuse(struct cil_fsuse *fsuse) 5185 { 5186 if (fsuse == NULL) { 5187 return; 5188 } 5189 5190 if (fsuse->context_str == NULL && fsuse->context != NULL) { 5191 cil_destroy_context(fsuse->context); 5192 } 5193 5194 free(fsuse); 5195 } 5196 5197 void cil_destroy_param(struct cil_param *param) 5198 { 5199 if (param == NULL) { 5200 return; 5201 } 5202 5203 free(param); 5204 } 5205 5206 int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5207 { 5208 int rc = SEPOL_ERR; 5209 char *key = NULL; 5210 struct cil_macro *macro = NULL; 5211 struct cil_tree_node *macro_content = NULL; 5212 enum cil_syntax syntax[] = { 5213 CIL_SYN_STRING, 5214 CIL_SYN_STRING, 5215 CIL_SYN_LIST | CIL_SYN_EMPTY_LIST, 5216 CIL_SYN_N_LISTS | CIL_SYN_END, 5217 CIL_SYN_END 5218 }; 5219 int syntax_len = sizeof(syntax)/ sizeof(*syntax); 5220 5221 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5222 goto exit; 5223 } 5224 5225 rc =__cil_verify_syntax(parse_current, syntax, syntax_len); 5226 if (rc != SEPOL_OK) { 5227 goto exit; 5228 } 5229 5230 cil_macro_init(¯o); 5231 5232 key = parse_current->next->data; 5233 5234 struct cil_tree_node *current_item = parse_current->next->next->cl_head; 5235 while (current_item != NULL) { 5236 enum cil_syntax param_syntax[] = { 5237 CIL_SYN_STRING, 5238 CIL_SYN_STRING, 5239 CIL_SYN_END 5240 }; 5241 int param_syntax_len = sizeof(param_syntax)/sizeof(*param_syntax); 5242 char *kind = NULL; 5243 struct cil_param *param = NULL; 5244 5245 rc =__cil_verify_syntax(current_item->cl_head, param_syntax, param_syntax_len); 5246 if (rc != SEPOL_OK) { 5247 goto exit; 5248 } 5249 5250 if (macro->params == NULL) { 5251 cil_list_init(¯o->params, CIL_LIST_ITEM); 5252 } 5253 5254 kind = current_item->cl_head->data; 5255 cil_param_init(¶m); 5256 5257 if (kind == CIL_KEY_TYPE) { 5258 param->flavor = CIL_TYPE; 5259 } else if (kind == CIL_KEY_ROLE) { 5260 param->flavor = CIL_ROLE; 5261 } else if (kind == CIL_KEY_USER) { 5262 param->flavor = CIL_USER; 5263 } else if (kind == CIL_KEY_SENSITIVITY) { 5264 param->flavor = CIL_SENS; 5265 } else if (kind == CIL_KEY_CATEGORY) { 5266 param->flavor = CIL_CAT; 5267 } else if (kind == CIL_KEY_CATSET) { 5268 param->flavor = CIL_CATSET; 5269 } else if (kind == CIL_KEY_LEVEL) { 5270 param->flavor = CIL_LEVEL; 5271 } else if (kind == CIL_KEY_LEVELRANGE) { 5272 param->flavor = CIL_LEVELRANGE; 5273 } else if (kind == CIL_KEY_CLASS) { 5274 param->flavor = CIL_CLASS; 5275 } else if (kind == CIL_KEY_IPADDR) { 5276 param->flavor = CIL_IPADDR; 5277 } else if (kind == CIL_KEY_MAP_CLASS) { 5278 param->flavor = CIL_MAP_CLASS; 5279 } else if (kind == CIL_KEY_CLASSPERMISSION) { 5280 param->flavor = CIL_CLASSPERMISSION; 5281 } else if (kind == CIL_KEY_BOOL) { 5282 param->flavor = CIL_BOOL; 5283 } else if (kind == CIL_KEY_STRING) { 5284 param->flavor = CIL_NAME; 5285 } else if (kind == CIL_KEY_NAME) { 5286 param->flavor = CIL_NAME; 5287 } else { 5288 cil_log(CIL_ERR, "The kind %s is not allowed as a parameter\n",kind); 5289 cil_destroy_param(param); 5290 goto exit; 5291 } 5292 5293 param->str = current_item->cl_head->next->data; 5294 5295 rc = __cil_verify_name(param->str); 5296 if (rc != SEPOL_OK) { 5297 cil_destroy_param(param); 5298 goto exit; 5299 } 5300 5301 //walk current list and check for duplicate parameters 5302 struct cil_list_item *curr_param; 5303 cil_list_for_each(curr_param, macro->params) { 5304 if (param->str == ((struct cil_param*)curr_param->data)->str) { 5305 if (param->flavor == ((struct cil_param*)curr_param->data)->flavor) { 5306 cil_log(CIL_ERR, "Duplicate parameter\n"); 5307 cil_destroy_param(param); 5308 goto exit; 5309 } 5310 } 5311 } 5312 5313 cil_list_append(macro->params, CIL_PARAM, param); 5314 5315 current_item = current_item->next; 5316 } 5317 5318 /* we don't want the tree walker to walk the macro parameters (they were just handled above), so the subtree is deleted, and the next pointer of the 5319 node containing the macro name is updated to point to the start of the macro content */ 5320 macro_content = parse_current->next->next->next; 5321 cil_tree_subtree_destroy(parse_current->next->next); 5322 parse_current->next->next = macro_content; 5323 if (macro_content == NULL) { 5324 /* No statements in macro and macro parameter list was last node */ 5325 parse_current->parent->cl_tail = parse_current->next; 5326 } 5327 5328 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)macro, (hashtab_key_t)key, CIL_SYM_BLOCKS, CIL_MACRO); 5329 if (rc != SEPOL_OK) { 5330 goto exit; 5331 } 5332 5333 return SEPOL_OK; 5334 5335 exit: 5336 cil_tree_log(parse_current, CIL_ERR, "Bad macro declaration"); 5337 cil_destroy_macro(macro); 5338 cil_clear_node(ast_node); 5339 return SEPOL_ERR; 5340 } 5341 5342 void cil_destroy_macro(struct cil_macro *macro) 5343 { 5344 if (macro == NULL) { 5345 return; 5346 } 5347 5348 cil_symtab_datum_destroy(¯o->datum); 5349 cil_symtab_array_destroy(macro->symtab); 5350 5351 if (macro->params != NULL) { 5352 cil_list_destroy(¯o->params, 1); 5353 } 5354 5355 free(macro); 5356 } 5357 5358 int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5359 { 5360 enum cil_syntax syntax[] = { 5361 CIL_SYN_STRING, 5362 CIL_SYN_STRING, 5363 CIL_SYN_LIST | CIL_SYN_EMPTY_LIST | CIL_SYN_END, 5364 CIL_SYN_END 5365 }; 5366 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5367 struct cil_call *call = NULL; 5368 int rc = SEPOL_ERR; 5369 5370 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5371 goto exit; 5372 } 5373 5374 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5375 if (rc != SEPOL_OK) { 5376 goto exit; 5377 } 5378 5379 cil_call_init(&call); 5380 5381 call->macro_str = parse_current->next->data; 5382 5383 if (parse_current->next->next != NULL) { 5384 cil_tree_init(&call->args_tree); 5385 cil_copy_ast(db, parse_current->next->next, call->args_tree->root); 5386 } 5387 5388 ast_node->data = call; 5389 ast_node->flavor = CIL_CALL; 5390 5391 return SEPOL_OK; 5392 5393 exit: 5394 cil_tree_log(parse_current, CIL_ERR, "Bad macro call"); 5395 cil_destroy_call(call); 5396 return rc; 5397 } 5398 5399 void cil_destroy_call(struct cil_call *call) 5400 { 5401 if (call == NULL) { 5402 return; 5403 } 5404 5405 call->macro = NULL; 5406 5407 if (call->args_tree != NULL) { 5408 cil_tree_destroy(&call->args_tree); 5409 } 5410 5411 if (call->args != NULL) { 5412 cil_list_destroy(&call->args, 1); 5413 } 5414 5415 free(call); 5416 } 5417 5418 void cil_destroy_args(struct cil_args *args) 5419 { 5420 if (args == NULL) { 5421 return; 5422 } 5423 5424 if (args->arg_str != NULL) { 5425 args->arg_str = NULL; 5426 } else if (args->arg != NULL) { 5427 struct cil_tree_node *node = args->arg->nodes->head->data; 5428 switch (args->flavor) { 5429 case CIL_NAME: 5430 break; 5431 case CIL_CATSET: 5432 cil_destroy_catset((struct cil_catset *)args->arg); 5433 free(node); 5434 break; 5435 case CIL_LEVEL: 5436 cil_destroy_level((struct cil_level *)args->arg); 5437 free(node); 5438 break; 5439 case CIL_LEVELRANGE: 5440 cil_destroy_levelrange((struct cil_levelrange *)args->arg); 5441 free(node); 5442 break; 5443 case CIL_IPADDR: 5444 cil_destroy_ipaddr((struct cil_ipaddr *)args->arg); 5445 free(node); 5446 break; 5447 case CIL_CLASSPERMISSION: 5448 cil_destroy_classpermission((struct cil_classpermission *)args->arg); 5449 free(node); 5450 break; 5451 default: 5452 cil_log(CIL_ERR, "Destroying arg with the unexpected flavor=%d\n",args->flavor); 5453 break; 5454 } 5455 } 5456 5457 args->param_str = NULL; 5458 args->arg = NULL; 5459 5460 free(args); 5461 } 5462 5463 int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5464 { 5465 enum cil_syntax syntax[] = { 5466 CIL_SYN_STRING, 5467 CIL_SYN_STRING, 5468 CIL_SYN_N_LISTS | CIL_SYN_END, 5469 CIL_SYN_END 5470 }; 5471 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5472 char *key = NULL; 5473 struct cil_optional *optional = NULL; 5474 int rc = SEPOL_ERR; 5475 5476 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5477 goto exit; 5478 } 5479 5480 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5481 if (rc != SEPOL_OK) { 5482 goto exit; 5483 } 5484 5485 cil_optional_init(&optional); 5486 5487 key = parse_current->next->data; 5488 5489 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)optional, (hashtab_key_t)key, CIL_SYM_BLOCKS, CIL_OPTIONAL); 5490 if (rc != SEPOL_OK) 5491 goto exit; 5492 5493 return SEPOL_OK; 5494 5495 exit: 5496 cil_tree_log(parse_current, CIL_ERR, "Bad optional"); 5497 cil_destroy_optional(optional); 5498 cil_clear_node(ast_node); 5499 return rc; 5500 } 5501 5502 void cil_destroy_optional(struct cil_optional *optional) 5503 { 5504 if (optional == NULL) { 5505 return; 5506 } 5507 5508 cil_symtab_datum_destroy(&optional->datum); 5509 free(optional); 5510 } 5511 5512 int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5513 { 5514 enum cil_syntax syntax[] = { 5515 CIL_SYN_STRING, 5516 CIL_SYN_STRING, 5517 CIL_SYN_END 5518 }; 5519 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5520 char *key = NULL; 5521 struct cil_policycap *polcap = NULL; 5522 int rc = SEPOL_ERR; 5523 5524 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5525 goto exit; 5526 } 5527 5528 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5529 if (rc != SEPOL_OK) { 5530 goto exit; 5531 } 5532 5533 cil_policycap_init(&polcap); 5534 5535 key = parse_current->next->data; 5536 5537 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)polcap, (hashtab_key_t)key, CIL_SYM_POLICYCAPS, CIL_POLICYCAP); 5538 if (rc != SEPOL_OK) 5539 goto exit; 5540 5541 return SEPOL_OK; 5542 5543 exit: 5544 cil_tree_log(parse_current, CIL_ERR, "Bad policycap statement"); 5545 cil_destroy_policycap(polcap); 5546 cil_clear_node(ast_node); 5547 return rc; 5548 } 5549 5550 void cil_destroy_policycap(struct cil_policycap *polcap) 5551 { 5552 if (polcap == NULL) { 5553 return; 5554 } 5555 5556 cil_symtab_datum_destroy(&polcap->datum); 5557 free(polcap); 5558 } 5559 5560 int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5561 { 5562 enum cil_syntax syntax[] = { 5563 CIL_SYN_STRING, 5564 CIL_SYN_STRING, 5565 CIL_SYN_STRING, 5566 CIL_SYN_END 5567 }; 5568 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5569 char *key = NULL; 5570 struct cil_ipaddr *ipaddr = NULL; 5571 int rc = SEPOL_ERR; 5572 5573 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5574 goto exit; 5575 } 5576 5577 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5578 if (rc != SEPOL_OK) { 5579 goto exit; 5580 } 5581 5582 cil_ipaddr_init(&ipaddr); 5583 5584 key = parse_current->next->data; 5585 5586 rc = cil_fill_ipaddr(parse_current->next->next, ipaddr); 5587 if (rc != SEPOL_OK) { 5588 goto exit; 5589 } 5590 5591 rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)ipaddr, (hashtab_key_t)key, CIL_SYM_IPADDRS, CIL_IPADDR); 5592 if (rc != SEPOL_OK) { 5593 goto exit; 5594 } 5595 5596 return SEPOL_OK; 5597 5598 exit: 5599 cil_tree_log(parse_current, CIL_ERR, "Bad ipaddr statement"); 5600 cil_destroy_ipaddr(ipaddr); 5601 cil_clear_node(ast_node); 5602 return rc; 5603 } 5604 5605 void cil_destroy_ipaddr(struct cil_ipaddr *ipaddr) 5606 { 5607 if (ipaddr == NULL) { 5608 return; 5609 } 5610 5611 cil_symtab_datum_destroy(&ipaddr->datum); 5612 free(ipaddr); 5613 } 5614 5615 int cil_fill_integer(struct cil_tree_node *int_node, uint32_t *integer, int base) 5616 { 5617 int rc = SEPOL_ERR; 5618 char *endptr = NULL; 5619 int val; 5620 5621 if (int_node == NULL || integer == NULL) { 5622 goto exit; 5623 } 5624 5625 errno = 0; 5626 val = strtol(int_node->data, &endptr, base); 5627 if (errno != 0 || endptr == int_node->data || *endptr != '\0') { 5628 rc = SEPOL_ERR; 5629 goto exit; 5630 } 5631 5632 *integer = val; 5633 5634 return SEPOL_OK; 5635 5636 exit: 5637 cil_log(CIL_ERR, "Failed to create integer from string\n"); 5638 return rc; 5639 } 5640 5641 int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer, int base) 5642 { 5643 int rc = SEPOL_ERR; 5644 char *endptr = NULL; 5645 uint64_t val; 5646 5647 if (int_node == NULL || integer == NULL) { 5648 goto exit; 5649 } 5650 5651 errno = 0; 5652 val = strtoull(int_node->data, &endptr, base); 5653 if (errno != 0 || endptr == int_node->data || *endptr != '\0') { 5654 rc = SEPOL_ERR; 5655 goto exit; 5656 } 5657 5658 *integer = val; 5659 5660 return SEPOL_OK; 5661 5662 exit: 5663 cil_log(CIL_ERR, "Failed to create integer from string\n"); 5664 return rc; 5665 } 5666 5667 int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr) 5668 { 5669 int rc = SEPOL_ERR; 5670 5671 if (addr_node == NULL || addr == NULL) { 5672 goto exit; 5673 } 5674 5675 if (addr_node->cl_head != NULL || addr_node->next != NULL) { 5676 goto exit; 5677 } 5678 5679 if (strchr(addr_node->data, '.') != NULL) { 5680 addr->family = AF_INET; 5681 } else { 5682 addr->family = AF_INET6; 5683 } 5684 5685 rc = inet_pton(addr->family, addr_node->data, &addr->ip); 5686 if (rc != 1) { 5687 rc = SEPOL_ERR; 5688 goto exit; 5689 } 5690 5691 return SEPOL_OK; 5692 5693 exit: 5694 cil_log(CIL_ERR, "Bad ip address or netmask\n"); 5695 return rc; 5696 } 5697 5698 int cil_fill_level(struct cil_tree_node *curr, struct cil_level *level) 5699 { 5700 int rc = SEPOL_ERR; 5701 enum cil_syntax syntax[] = { 5702 CIL_SYN_STRING, 5703 CIL_SYN_STRING | CIL_SYN_LIST | CIL_SYN_END, 5704 CIL_SYN_END 5705 }; 5706 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5707 5708 if (curr == NULL) { 5709 goto exit; 5710 } 5711 5712 rc = __cil_verify_syntax(curr, syntax, syntax_len); 5713 if (rc != SEPOL_OK) { 5714 goto exit; 5715 } 5716 5717 level->sens_str = curr->data; 5718 if (curr->next != NULL) { 5719 rc = cil_fill_cats(curr->next, &level->cats); 5720 if (rc != SEPOL_OK) { 5721 goto exit; 5722 } 5723 } 5724 5725 return SEPOL_OK; 5726 5727 exit: 5728 cil_log(CIL_ERR, "Bad level\n"); 5729 return rc; 5730 } 5731 5732 int cil_fill_cats(struct cil_tree_node *curr, struct cil_cats **cats) 5733 { 5734 int rc = SEPOL_ERR; 5735 5736 cil_cats_init(cats); 5737 5738 rc = cil_gen_expr(curr, CIL_CAT, &(*cats)->str_expr); 5739 if (rc != SEPOL_OK) { 5740 cil_destroy_cats(*cats); 5741 *cats = NULL; 5742 } 5743 5744 return rc; 5745 } 5746 5747 void cil_destroy_cats(struct cil_cats *cats) 5748 { 5749 if (cats == NULL) { 5750 return; 5751 } 5752 5753 cil_list_destroy(&cats->str_expr, CIL_TRUE); 5754 5755 cil_list_destroy(&cats->datum_expr, CIL_FALSE); 5756 5757 free(cats); 5758 } 5759 int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) 5760 { 5761 enum cil_syntax syntax[] = { 5762 CIL_SYN_STRING, 5763 CIL_SYN_STRING, 5764 CIL_SYN_STRING, 5765 CIL_SYN_END 5766 }; 5767 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5768 struct cil_bounds *bounds = NULL; 5769 int rc = SEPOL_ERR; 5770 5771 if (db == NULL || parse_current == NULL || ast_node == NULL) { 5772 goto exit; 5773 } 5774 5775 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5776 if (rc != SEPOL_OK) { 5777 goto exit; 5778 } 5779 5780 cil_bounds_init(&bounds); 5781 5782 bounds->parent_str = parse_current->next->data; 5783 bounds->child_str = parse_current->next->next->data; 5784 5785 ast_node->data = bounds; 5786 5787 switch (flavor) { 5788 case CIL_USER: 5789 ast_node->flavor = CIL_USERBOUNDS; 5790 break; 5791 case CIL_ROLE: 5792 ast_node->flavor = CIL_ROLEBOUNDS; 5793 break; 5794 case CIL_TYPE: 5795 ast_node->flavor = CIL_TYPEBOUNDS; 5796 break; 5797 default: 5798 break; 5799 } 5800 5801 return SEPOL_OK; 5802 5803 exit: 5804 cil_tree_log(parse_current, CIL_ERR, "Bad bounds declaration"); 5805 cil_destroy_bounds(bounds); 5806 return rc; 5807 } 5808 5809 void cil_destroy_bounds(struct cil_bounds *bounds) 5810 { 5811 if (bounds == NULL) { 5812 return; 5813 } 5814 5815 free(bounds); 5816 } 5817 5818 int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) 5819 { 5820 int rc = SEPOL_ERR; 5821 struct cil_default *def = NULL; 5822 char *object; 5823 enum cil_syntax syntax[] = { 5824 CIL_SYN_STRING, 5825 CIL_SYN_STRING | CIL_SYN_LIST, 5826 CIL_SYN_STRING, 5827 CIL_SYN_END 5828 }; 5829 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5830 5831 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5832 if (rc != SEPOL_OK) { 5833 goto exit; 5834 } 5835 5836 cil_default_init(&def); 5837 5838 def->flavor = flavor; 5839 5840 if (parse_current->next->cl_head == NULL) { 5841 cil_list_init(&def->class_strs, CIL_CLASS); 5842 cil_list_append(def->class_strs, CIL_STRING, parse_current->next->data); 5843 } else { 5844 rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASS, &def->class_strs); 5845 if (rc != SEPOL_OK) { 5846 goto exit; 5847 } 5848 } 5849 5850 object = parse_current->next->next->data; 5851 if (object == CIL_KEY_SOURCE) { 5852 def->object = CIL_DEFAULT_SOURCE; 5853 } else if (object == CIL_KEY_TARGET) { 5854 def->object = CIL_DEFAULT_TARGET; 5855 } else { 5856 cil_log(CIL_ERR,"Expected either 'source' or 'target'\n"); 5857 rc = SEPOL_ERR; 5858 goto exit; 5859 } 5860 5861 ast_node->data = def; 5862 ast_node->flavor = flavor; 5863 5864 return SEPOL_OK; 5865 5866 exit: 5867 cil_tree_log(parse_current, CIL_ERR, "Bad %s declaration", cil_node_to_string(parse_current)); 5868 cil_destroy_default(def); 5869 return rc; 5870 } 5871 5872 void cil_destroy_default(struct cil_default *def) 5873 { 5874 if (def == NULL) { 5875 return; 5876 } 5877 5878 cil_list_destroy(&def->class_strs, CIL_TRUE); 5879 5880 cil_list_destroy(&def->class_datums, CIL_FALSE); 5881 5882 free(def); 5883 } 5884 5885 int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5886 { 5887 int rc = SEPOL_ERR; 5888 struct cil_defaultrange *def = NULL; 5889 char *object; 5890 char *range; 5891 enum cil_syntax syntax[] = { 5892 CIL_SYN_STRING, 5893 CIL_SYN_STRING | CIL_SYN_LIST, 5894 CIL_SYN_STRING, 5895 CIL_SYN_STRING, 5896 CIL_SYN_END 5897 }; 5898 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5899 5900 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5901 if (rc != SEPOL_OK) { 5902 goto exit; 5903 } 5904 5905 cil_defaultrange_init(&def); 5906 5907 if (parse_current->next->cl_head == NULL) { 5908 cil_list_init(&def->class_strs, CIL_CLASS); 5909 cil_list_append(def->class_strs, CIL_STRING, parse_current->next->data); 5910 } else { 5911 rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASS, &def->class_strs); 5912 if (rc != SEPOL_OK) { 5913 goto exit; 5914 } 5915 } 5916 5917 object = parse_current->next->next->data; 5918 range = parse_current->next->next->next->data; 5919 if (object == CIL_KEY_SOURCE) { 5920 if (range == CIL_KEY_LOW) { 5921 def->object_range = CIL_DEFAULT_SOURCE_LOW; 5922 } else if (range == CIL_KEY_HIGH) { 5923 def->object_range = CIL_DEFAULT_SOURCE_HIGH; 5924 } else if (range == CIL_KEY_LOW_HIGH) { 5925 def->object_range = CIL_DEFAULT_SOURCE_LOW_HIGH; 5926 } else { 5927 cil_log(CIL_ERR,"Expected 'low', 'high', or 'low-high'\n"); 5928 rc = SEPOL_ERR; 5929 goto exit; 5930 } 5931 } else if (parse_current->next->next->data == CIL_KEY_TARGET) { 5932 if (range == CIL_KEY_LOW) { 5933 def->object_range = CIL_DEFAULT_TARGET_LOW; 5934 } else if (range == CIL_KEY_HIGH) { 5935 def->object_range = CIL_DEFAULT_TARGET_HIGH; 5936 } else if (range == CIL_KEY_LOW_HIGH) { 5937 def->object_range = CIL_DEFAULT_TARGET_LOW_HIGH; 5938 } else { 5939 cil_log(CIL_ERR,"Expected 'low', 'high', or 'low-high'\n"); 5940 rc = SEPOL_ERR; 5941 goto exit; 5942 } 5943 } else { 5944 cil_log(CIL_ERR,"Expected either \'source\' or \'target\'\n"); 5945 rc = SEPOL_ERR; 5946 goto exit; 5947 } 5948 5949 ast_node->data = def; 5950 ast_node->flavor = CIL_DEFAULTRANGE; 5951 5952 return SEPOL_OK; 5953 5954 exit: 5955 cil_tree_log(parse_current, CIL_ERR, "Bad defaultrange declaration"); 5956 cil_destroy_defaultrange(def); 5957 return rc; 5958 } 5959 5960 void cil_destroy_defaultrange(struct cil_defaultrange *def) 5961 { 5962 if (def == NULL) { 5963 return; 5964 } 5965 5966 cil_list_destroy(&def->class_strs, CIL_TRUE); 5967 5968 cil_list_destroy(&def->class_datums, CIL_FALSE); 5969 5970 free(def); 5971 } 5972 5973 int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 5974 { 5975 int rc = SEPOL_ERR; 5976 enum cil_syntax syntax[] = { 5977 CIL_SYN_STRING, 5978 CIL_SYN_STRING, 5979 CIL_SYN_END 5980 }; 5981 int syntax_len = sizeof(syntax)/sizeof(*syntax); 5982 struct cil_handleunknown *unknown = NULL; 5983 char *unknown_key; 5984 5985 if (parse_current == NULL || ast_node == NULL) { 5986 goto exit; 5987 } 5988 5989 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 5990 if (rc != SEPOL_OK) { 5991 goto exit; 5992 } 5993 5994 cil_handleunknown_init(&unknown); 5995 5996 unknown_key = parse_current->next->data; 5997 if (unknown_key == CIL_KEY_HANDLEUNKNOWN_ALLOW) { 5998 unknown->handle_unknown = SEPOL_ALLOW_UNKNOWN; 5999 } else if (unknown_key == CIL_KEY_HANDLEUNKNOWN_DENY) { 6000 unknown->handle_unknown = SEPOL_DENY_UNKNOWN; 6001 } else if (unknown_key == CIL_KEY_HANDLEUNKNOWN_REJECT) { 6002 unknown->handle_unknown = SEPOL_REJECT_UNKNOWN; 6003 } else { 6004 cil_log(CIL_ERR, "Expected either \'%s\', \'%s\', or \'%s\'\n", CIL_KEY_HANDLEUNKNOWN_ALLOW, CIL_KEY_HANDLEUNKNOWN_DENY, CIL_KEY_HANDLEUNKNOWN_REJECT); 6005 rc = SEPOL_ERR; 6006 goto exit; 6007 } 6008 6009 ast_node->data = unknown; 6010 ast_node->flavor = CIL_HANDLEUNKNOWN; 6011 6012 return SEPOL_OK; 6013 6014 exit: 6015 cil_tree_log(parse_current, CIL_ERR, "Bad handleunknown"); 6016 cil_destroy_handleunknown(unknown); 6017 return rc; 6018 } 6019 6020 void cil_destroy_handleunknown(struct cil_handleunknown *unk) 6021 { 6022 free(unk); 6023 } 6024 6025 int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 6026 { 6027 int rc = SEPOL_ERR; 6028 enum cil_syntax syntax[] = { 6029 CIL_SYN_STRING, 6030 CIL_SYN_STRING, 6031 CIL_SYN_END 6032 }; 6033 int syntax_len = sizeof(syntax)/sizeof(*syntax); 6034 struct cil_mls *mls = NULL; 6035 6036 if (parse_current == NULL || ast_node == NULL) { 6037 goto exit; 6038 } 6039 6040 rc = __cil_verify_syntax(parse_current, syntax, syntax_len); 6041 if (rc != SEPOL_OK) { 6042 goto exit; 6043 } 6044 6045 cil_mls_init(&mls); 6046 6047 if (parse_current->next->data == CIL_KEY_CONDTRUE) { 6048 mls->value = CIL_TRUE; 6049 } else if (parse_current->next->data == CIL_KEY_CONDFALSE) { 6050 mls->value = CIL_FALSE; 6051 } else { 6052 cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); 6053 rc = SEPOL_ERR; 6054 goto exit; 6055 } 6056 6057 ast_node->data = mls; 6058 ast_node->flavor = CIL_MLS; 6059 6060 return SEPOL_OK; 6061 6062 exit: 6063 cil_tree_log(parse_current, CIL_ERR, "Bad mls"); 6064 cil_destroy_mls(mls); 6065 return rc; 6066 } 6067 6068 void cil_destroy_mls(struct cil_mls *mls) 6069 { 6070 free(mls); 6071 } 6072 6073 int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) 6074 { 6075 /* No need to check syntax, because this is auto generated */ 6076 struct cil_src_info *info = NULL; 6077 6078 cil_src_info_init(&info); 6079 6080 info->is_cil = (parse_current->next->data == CIL_KEY_SRC_CIL) ? CIL_TRUE : CIL_FALSE; 6081 info->path = parse_current->next->next->data; 6082 6083 ast_node->data = info; 6084 ast_node->flavor = CIL_SRC_INFO; 6085 6086 return SEPOL_OK; 6087 } 6088 6089 void cil_destroy_src_info(struct cil_src_info *info) 6090 { 6091 free(info); 6092 } 6093 6094 int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) 6095 { 6096 struct cil_args_build *args = NULL; 6097 struct cil_tree_node *ast_current = NULL; 6098 struct cil_db *db = NULL; 6099 struct cil_tree_node *ast_node = NULL; 6100 struct cil_tree_node *macro = NULL; 6101 struct cil_tree_node *boolif = NULL; 6102 struct cil_tree_node *tunif = NULL; 6103 struct cil_tree_node *in = NULL; 6104 int rc = SEPOL_ERR; 6105 6106 if (parse_current == NULL || finished == NULL || extra_args == NULL) { 6107 goto exit; 6108 } 6109 6110 args = extra_args; 6111 ast_current = args->ast; 6112 db = args->db; 6113 macro = args->macro; 6114 boolif = args->boolif; 6115 tunif = args->tunif; 6116 in = args->in; 6117 6118 if (parse_current->parent->cl_head != parse_current) { 6119 /* ignore anything that isn't following a parenthesis */ 6120 rc = SEPOL_OK; 6121 goto exit; 6122 } else if (parse_current->data == NULL) { 6123 /* the only time parenthsis can immediately following parenthesis is if 6124 * the parent is the root node */ 6125 if (parse_current->parent->parent == NULL) { 6126 rc = SEPOL_OK; 6127 } else { 6128 cil_tree_log(parse_current, CIL_ERR, "Keyword expected after open parenthesis"); 6129 } 6130 goto exit; 6131 } 6132 6133 if (macro != NULL) { 6134 if (parse_current->data == CIL_KEY_MACRO || 6135 parse_current->data == CIL_KEY_TUNABLE || 6136 parse_current->data == CIL_KEY_IN || 6137 parse_current->data == CIL_KEY_BLOCK || 6138 parse_current->data == CIL_KEY_BLOCKINHERIT || 6139 parse_current->data == CIL_KEY_BLOCKABSTRACT) { 6140 rc = SEPOL_ERR; 6141 cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macros", (char *)parse_current->data); 6142 goto exit; 6143 } 6144 } 6145 6146 if (boolif != NULL) { 6147 if (parse_current->data != CIL_KEY_CONDTRUE && 6148 parse_current->data != CIL_KEY_CONDFALSE && 6149 parse_current->data != CIL_KEY_AUDITALLOW && 6150 parse_current->data != CIL_KEY_TUNABLEIF && 6151 parse_current->data != CIL_KEY_ALLOW && 6152 parse_current->data != CIL_KEY_DONTAUDIT && 6153 parse_current->data != CIL_KEY_TYPETRANSITION && 6154 parse_current->data != CIL_KEY_TYPECHANGE && 6155 parse_current->data != CIL_KEY_CALL) { 6156 rc = SEPOL_ERR; 6157 cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data); 6158 if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { 6159 cil_log(CIL_ERR, "%s cannot be defined within tunableif statement (treated as a booleanif due to preserve-tunables)\n", 6160 (char*)parse_current->data); 6161 } else { 6162 cil_log(CIL_ERR, "%s cannot be defined within booleanif statement\n", 6163 (char*)parse_current->data); 6164 } 6165 goto exit; 6166 } 6167 } 6168 6169 if (tunif != NULL) { 6170 if (parse_current->data == CIL_KEY_TUNABLE) { 6171 rc = SEPOL_ERR; 6172 cil_tree_log(parse_current, CIL_ERR, "Found tunable"); 6173 cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); 6174 goto exit; 6175 } 6176 } 6177 6178 if (in != NULL) { 6179 if (parse_current->data == CIL_KEY_IN) { 6180 rc = SEPOL_ERR; 6181 cil_tree_log(parse_current, CIL_ERR, "Found in-statement"); 6182 cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); 6183 goto exit; 6184 } 6185 } 6186 6187 cil_tree_node_init(&ast_node); 6188 6189 ast_node->parent = ast_current; 6190 ast_node->line = parse_current->line; 6191 ast_node->hll_line = parse_current->hll_line; 6192 6193 if (parse_current->data == CIL_KEY_BLOCK) { 6194 rc = cil_gen_block(db, parse_current, ast_node, 0); 6195 } else if (parse_current->data == CIL_KEY_BLOCKINHERIT) { 6196 rc = cil_gen_blockinherit(db, parse_current, ast_node); 6197 } else if (parse_current->data == CIL_KEY_BLOCKABSTRACT) { 6198 rc = cil_gen_blockabstract(db, parse_current, ast_node); 6199 } else if (parse_current->data == CIL_KEY_IN) { 6200 rc = cil_gen_in(db, parse_current, ast_node); 6201 } else if (parse_current->data == CIL_KEY_CLASS) { 6202 rc = cil_gen_class(db, parse_current, ast_node); 6203 // To avoid parsing list of perms again 6204 *finished = CIL_TREE_SKIP_NEXT; 6205 } else if (parse_current->data == CIL_KEY_CLASSORDER) { 6206 rc = cil_gen_classorder(db, parse_current, ast_node); 6207 *finished = CIL_TREE_SKIP_NEXT; 6208 } else if (parse_current->data == CIL_KEY_MAP_CLASS) { 6209 rc = cil_gen_map_class(db, parse_current, ast_node); 6210 *finished = CIL_TREE_SKIP_NEXT; 6211 } else if (parse_current->data == CIL_KEY_CLASSMAPPING) { 6212 rc = cil_gen_classmapping(db, parse_current, ast_node); 6213 *finished = CIL_TREE_SKIP_NEXT; 6214 } else if (parse_current->data == CIL_KEY_CLASSPERMISSION) { 6215 rc = cil_gen_classpermission(db, parse_current, ast_node); 6216 *finished = CIL_TREE_SKIP_NEXT; 6217 } else if (parse_current->data == CIL_KEY_CLASSPERMISSIONSET) { 6218 rc = cil_gen_classpermissionset(db, parse_current, ast_node); 6219 *finished = CIL_TREE_SKIP_NEXT; 6220 } else if (parse_current->data == CIL_KEY_COMMON) { 6221 rc = cil_gen_common(db, parse_current, ast_node); 6222 *finished = CIL_TREE_SKIP_NEXT; 6223 } else if (parse_current->data == CIL_KEY_CLASSCOMMON) { 6224 rc = cil_gen_classcommon(db, parse_current, ast_node); 6225 } else if (parse_current->data == CIL_KEY_SID) { 6226 rc = cil_gen_sid(db, parse_current, ast_node); 6227 *finished = CIL_TREE_SKIP_NEXT; 6228 } else if (parse_current->data == CIL_KEY_SIDCONTEXT) { 6229 rc = cil_gen_sidcontext(db, parse_current, ast_node); 6230 *finished = CIL_TREE_SKIP_NEXT; 6231 } else if (parse_current->data == CIL_KEY_SIDORDER) { 6232 rc = cil_gen_sidorder(db, parse_current, ast_node); 6233 *finished = CIL_TREE_SKIP_NEXT; 6234 } else if (parse_current->data == CIL_KEY_USER) { 6235 rc = cil_gen_user(db, parse_current, ast_node); 6236 } else if (parse_current->data == CIL_KEY_USERATTRIBUTE) { 6237 rc = cil_gen_userattribute(db, parse_current, ast_node); 6238 } else if (parse_current->data == CIL_KEY_USERATTRIBUTESET) { 6239 rc = cil_gen_userattributeset(db, parse_current, ast_node); 6240 *finished = CIL_TREE_SKIP_NEXT; 6241 } else if (parse_current->data == CIL_KEY_USERLEVEL) { 6242 rc = cil_gen_userlevel(db, parse_current, ast_node); 6243 *finished = CIL_TREE_SKIP_NEXT; 6244 } else if (parse_current->data == CIL_KEY_USERRANGE) { 6245 rc = cil_gen_userrange(db, parse_current, ast_node); 6246 *finished = CIL_TREE_SKIP_NEXT; 6247 } else if (parse_current->data == CIL_KEY_USERBOUNDS) { 6248 rc = cil_gen_bounds(db, parse_current, ast_node, CIL_USER); 6249 } else if (parse_current->data == CIL_KEY_USERPREFIX) { 6250 rc = cil_gen_userprefix(db, parse_current, ast_node); 6251 } else if (parse_current->data == CIL_KEY_SELINUXUSER) { 6252 rc = cil_gen_selinuxuser(db, parse_current, ast_node); 6253 *finished = CIL_TREE_SKIP_NEXT; 6254 } else if (parse_current->data == CIL_KEY_SELINUXUSERDEFAULT) { 6255 rc = cil_gen_selinuxuserdefault(db, parse_current, ast_node); 6256 *finished = CIL_TREE_SKIP_NEXT; 6257 } else if (parse_current->data == CIL_KEY_TYPE) { 6258 rc = cil_gen_type(db, parse_current, ast_node); 6259 } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTE) { 6260 rc = cil_gen_typeattribute(db, parse_current, ast_node); 6261 } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTESET) { 6262 rc = cil_gen_typeattributeset(db, parse_current, ast_node); 6263 *finished = CIL_TREE_SKIP_NEXT; 6264 } else if (parse_current->data == CIL_KEY_EXPANDTYPEATTRIBUTE) { 6265 rc = cil_gen_expandtypeattribute(db, parse_current, ast_node); 6266 *finished = CIL_TREE_SKIP_NEXT; 6267 } else if (parse_current->data == CIL_KEY_TYPEALIAS) { 6268 rc = cil_gen_alias(db, parse_current, ast_node, CIL_TYPEALIAS); 6269 } else if (parse_current->data == CIL_KEY_TYPEALIASACTUAL) { 6270 rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_TYPEALIASACTUAL); 6271 } else if (parse_current->data == CIL_KEY_TYPEBOUNDS) { 6272 rc = cil_gen_bounds(db, parse_current, ast_node, CIL_TYPE); 6273 } else if (parse_current->data == CIL_KEY_TYPEPERMISSIVE) { 6274 rc = cil_gen_typepermissive(db, parse_current, ast_node); 6275 } else if (parse_current->data == CIL_KEY_RANGETRANSITION) { 6276 rc = cil_gen_rangetransition(db, parse_current, ast_node); 6277 *finished = CIL_TREE_SKIP_NEXT; 6278 } else if (parse_current->data == CIL_KEY_ROLE) { 6279 rc = cil_gen_role(db, parse_current, ast_node); 6280 } else if (parse_current->data == CIL_KEY_USERROLE) { 6281 rc = cil_gen_userrole(db, parse_current, ast_node); 6282 } else if (parse_current->data == CIL_KEY_ROLETYPE) { 6283 rc = cil_gen_roletype(db, parse_current, ast_node); 6284 } else if (parse_current->data == CIL_KEY_ROLETRANSITION) { 6285 rc = cil_gen_roletransition(parse_current, ast_node); 6286 } else if (parse_current->data == CIL_KEY_ROLEALLOW) { 6287 rc = cil_gen_roleallow(db, parse_current, ast_node); 6288 } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTE) { 6289 rc = cil_gen_roleattribute(db, parse_current, ast_node); 6290 } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTESET) { 6291 rc = cil_gen_roleattributeset(db, parse_current, ast_node); 6292 *finished = CIL_TREE_SKIP_NEXT; 6293 } else if (parse_current->data == CIL_KEY_ROLEBOUNDS) { 6294 rc = cil_gen_bounds(db, parse_current, ast_node, CIL_ROLE); 6295 } else if (parse_current->data == CIL_KEY_BOOL) { 6296 rc = cil_gen_bool(db, parse_current, ast_node, CIL_FALSE); 6297 } else if (parse_current->data == CIL_KEY_BOOLEANIF) { 6298 rc = cil_gen_boolif(db, parse_current, ast_node, CIL_FALSE); 6299 } else if(parse_current->data == CIL_KEY_TUNABLE) { 6300 if (db->preserve_tunables) { 6301 rc = cil_gen_bool(db, parse_current, ast_node, CIL_TRUE); 6302 } else { 6303 rc = cil_gen_tunable(db, parse_current, ast_node); 6304 } 6305 } else if (parse_current->data == CIL_KEY_TUNABLEIF) { 6306 if (db->preserve_tunables) { 6307 rc = cil_gen_boolif(db, parse_current, ast_node, CIL_TRUE); 6308 } else { 6309 rc = cil_gen_tunif(db, parse_current, ast_node); 6310 } 6311 } else if (parse_current->data == CIL_KEY_CONDTRUE) { 6312 rc = cil_gen_condblock(db, parse_current, ast_node, CIL_CONDTRUE); 6313 } else if (parse_current->data == CIL_KEY_CONDFALSE) { 6314 rc = cil_gen_condblock(db, parse_current, ast_node, CIL_CONDFALSE); 6315 } else if (parse_current->data == CIL_KEY_ALLOW) { 6316 rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_ALLOWED); 6317 // So that the object and perms lists do not get parsed again 6318 *finished = CIL_TREE_SKIP_NEXT; 6319 } else if (parse_current->data == CIL_KEY_AUDITALLOW) { 6320 rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_AUDITALLOW); 6321 *finished = CIL_TREE_SKIP_NEXT; 6322 } else if (parse_current->data == CIL_KEY_DONTAUDIT) { 6323 rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_DONTAUDIT); 6324 *finished = CIL_TREE_SKIP_NEXT; 6325 } else if (parse_current->data == CIL_KEY_NEVERALLOW) { 6326 rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_NEVERALLOW); 6327 *finished = CIL_TREE_SKIP_NEXT; 6328 } else if (parse_current->data == CIL_KEY_ALLOWX) { 6329 rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_ALLOWED); 6330 *finished = CIL_TREE_SKIP_NEXT; 6331 } else if (parse_current->data == CIL_KEY_AUDITALLOWX) { 6332 rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_AUDITALLOW); 6333 *finished = CIL_TREE_SKIP_NEXT; 6334 } else if (parse_current->data == CIL_KEY_DONTAUDITX) { 6335 rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_DONTAUDIT); 6336 *finished = CIL_TREE_SKIP_NEXT; 6337 } else if (parse_current->data == CIL_KEY_NEVERALLOWX) { 6338 rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_NEVERALLOW); 6339 *finished = CIL_TREE_SKIP_NEXT; 6340 } else if (parse_current->data == CIL_KEY_PERMISSIONX) { 6341 rc = cil_gen_permissionx(db, parse_current, ast_node); 6342 *finished = CIL_TREE_SKIP_NEXT; 6343 } else if (parse_current->data == CIL_KEY_TYPETRANSITION) { 6344 rc = cil_gen_typetransition(db, parse_current, ast_node); 6345 } else if (parse_current->data == CIL_KEY_TYPECHANGE) { 6346 rc = cil_gen_type_rule(parse_current, ast_node, CIL_TYPE_CHANGE); 6347 } else if (parse_current->data == CIL_KEY_TYPEMEMBER) { 6348 rc = cil_gen_type_rule(parse_current, ast_node, CIL_TYPE_MEMBER); 6349 } else if (parse_current->data == CIL_KEY_SENSITIVITY) { 6350 rc = cil_gen_sensitivity(db, parse_current, ast_node); 6351 } else if (parse_current->data == CIL_KEY_SENSALIAS) { 6352 rc = cil_gen_alias(db, parse_current, ast_node, CIL_SENSALIAS); 6353 } else if (parse_current->data == CIL_KEY_SENSALIASACTUAL) { 6354 rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_SENSALIASACTUAL); 6355 } else if (parse_current->data == CIL_KEY_CATEGORY) { 6356 rc = cil_gen_category(db, parse_current, ast_node); 6357 } else if (parse_current->data == CIL_KEY_CATALIAS) { 6358 rc = cil_gen_alias(db, parse_current, ast_node, CIL_CATALIAS); 6359 } else if (parse_current->data == CIL_KEY_CATALIASACTUAL) { 6360 rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_CATALIASACTUAL); 6361 } else if (parse_current->data == CIL_KEY_CATSET) { 6362 rc = cil_gen_catset(db, parse_current, ast_node); 6363 *finished = CIL_TREE_SKIP_NEXT; 6364 } else if (parse_current->data == CIL_KEY_CATORDER) { 6365 rc = cil_gen_catorder(db, parse_current, ast_node); 6366 *finished = CIL_TREE_SKIP_NEXT; 6367 } else if (parse_current->data == CIL_KEY_SENSITIVITYORDER) { 6368 rc = cil_gen_sensitivityorder(db, parse_current, ast_node); 6369 *finished = CIL_TREE_SKIP_NEXT; 6370 } else if (parse_current->data == CIL_KEY_SENSCAT) { 6371 rc = cil_gen_senscat(db, parse_current, ast_node); 6372 *finished = CIL_TREE_SKIP_NEXT; 6373 } else if (parse_current->data == CIL_KEY_LEVEL) { 6374 rc = cil_gen_level(db, parse_current, ast_node); 6375 *finished = CIL_TREE_SKIP_NEXT; 6376 } else if (parse_current->data == CIL_KEY_LEVELRANGE) { 6377 rc = cil_gen_levelrange(db, parse_current, ast_node); 6378 *finished = CIL_TREE_SKIP_NEXT; 6379 } else if (parse_current->data == CIL_KEY_CONSTRAIN) { 6380 rc = cil_gen_constrain(db, parse_current, ast_node, CIL_CONSTRAIN); 6381 *finished = CIL_TREE_SKIP_NEXT; 6382 } else if (parse_current->data == CIL_KEY_MLSCONSTRAIN) { 6383 rc = cil_gen_constrain(db, parse_current, ast_node, CIL_MLSCONSTRAIN); 6384 *finished = CIL_TREE_SKIP_NEXT; 6385 } else if (parse_current->data == CIL_KEY_VALIDATETRANS) { 6386 rc = cil_gen_validatetrans(db, parse_current, ast_node, CIL_VALIDATETRANS); 6387 *finished = CIL_TREE_SKIP_NEXT; 6388 } else if (parse_current->data == CIL_KEY_MLSVALIDATETRANS) { 6389 rc = cil_gen_validatetrans(db, parse_current, ast_node, CIL_MLSVALIDATETRANS); 6390 *finished = CIL_TREE_SKIP_NEXT; 6391 } else if (parse_current->data == CIL_KEY_CONTEXT) { 6392 rc = cil_gen_context(db, parse_current, ast_node); 6393 *finished = CIL_TREE_SKIP_NEXT; 6394 } else if (parse_current->data == CIL_KEY_FILECON) { 6395 rc = cil_gen_filecon(db, parse_current, ast_node); 6396 *finished = CIL_TREE_SKIP_NEXT; 6397 } else if (parse_current->data == CIL_KEY_IBPKEYCON) { 6398 rc = cil_gen_ibpkeycon(db, parse_current, ast_node); 6399 *finished = CIL_TREE_SKIP_NEXT; 6400 } else if (parse_current->data == CIL_KEY_IBENDPORTCON) { 6401 rc = cil_gen_ibendportcon(db, parse_current, ast_node); 6402 *finished = CIL_TREE_SKIP_NEXT; 6403 } else if (parse_current->data == CIL_KEY_PORTCON) { 6404 rc = cil_gen_portcon(db, parse_current, ast_node); 6405 *finished = CIL_TREE_SKIP_NEXT; 6406 } else if (parse_current->data == CIL_KEY_NODECON) { 6407 rc = cil_gen_nodecon(db, parse_current, ast_node); 6408 *finished = CIL_TREE_SKIP_NEXT; 6409 } else if (parse_current->data == CIL_KEY_GENFSCON) { 6410 rc = cil_gen_genfscon(db, parse_current, ast_node); 6411 *finished = CIL_TREE_SKIP_NEXT; 6412 } else if (parse_current->data == CIL_KEY_NETIFCON) { 6413 rc = cil_gen_netifcon(db, parse_current, ast_node); 6414 *finished = CIL_TREE_SKIP_NEXT; 6415 } else if (parse_current->data == CIL_KEY_PIRQCON) { 6416 rc = cil_gen_pirqcon(db, parse_current, ast_node); 6417 *finished = CIL_TREE_SKIP_NEXT; 6418 } else if (parse_current->data == CIL_KEY_IOMEMCON) { 6419 rc = cil_gen_iomemcon(db, parse_current, ast_node); 6420 *finished = CIL_TREE_SKIP_NEXT; 6421 } else if (parse_current->data == CIL_KEY_IOPORTCON) { 6422 rc = cil_gen_ioportcon(db, parse_current, ast_node); 6423 *finished = CIL_TREE_SKIP_NEXT; 6424 } else if (parse_current->data == CIL_KEY_PCIDEVICECON) { 6425 rc = cil_gen_pcidevicecon(db, parse_current, ast_node); 6426 *finished = CIL_TREE_SKIP_NEXT; 6427 } else if (parse_current->data == CIL_KEY_DEVICETREECON) { 6428 rc = cil_gen_devicetreecon(db, parse_current, ast_node); 6429 *finished = CIL_TREE_SKIP_NEXT; 6430 } else if (parse_current->data == CIL_KEY_FSUSE) { 6431 rc = cil_gen_fsuse(db, parse_current, ast_node); 6432 *finished = CIL_TREE_SKIP_NEXT; 6433 } else if (parse_current->data == CIL_KEY_MACRO) { 6434 rc = cil_gen_macro(db, parse_current, ast_node); 6435 } else if (parse_current->data == CIL_KEY_CALL) { 6436 rc = cil_gen_call(db, parse_current, ast_node); 6437 *finished = 1; 6438 } else if (parse_current->data == CIL_KEY_POLICYCAP) { 6439 rc = cil_gen_policycap(db, parse_current, ast_node); 6440 *finished = 1; 6441 } else if (parse_current->data == CIL_KEY_OPTIONAL) { 6442 rc = cil_gen_optional(db, parse_current, ast_node); 6443 } else if (parse_current->data == CIL_KEY_IPADDR) { 6444 rc = cil_gen_ipaddr(db, parse_current, ast_node); 6445 } else if (parse_current->data == CIL_KEY_DEFAULTUSER) { 6446 rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTUSER); 6447 *finished = CIL_TREE_SKIP_NEXT; 6448 } else if (parse_current->data == CIL_KEY_DEFAULTROLE) { 6449 rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTROLE); 6450 *finished = CIL_TREE_SKIP_NEXT; 6451 } else if (parse_current->data == CIL_KEY_DEFAULTTYPE) { 6452 rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTTYPE); 6453 *finished = CIL_TREE_SKIP_NEXT; 6454 } else if (parse_current->data == CIL_KEY_DEFAULTRANGE) { 6455 rc = cil_gen_defaultrange(parse_current, ast_node); 6456 *finished = CIL_TREE_SKIP_NEXT; 6457 } else if (parse_current->data == CIL_KEY_HANDLEUNKNOWN) { 6458 rc = cil_gen_handleunknown(parse_current, ast_node); 6459 *finished = CIL_TREE_SKIP_NEXT; 6460 } else if (parse_current->data == CIL_KEY_MLS) { 6461 rc = cil_gen_mls(parse_current, ast_node); 6462 *finished = CIL_TREE_SKIP_NEXT; 6463 } else if (parse_current->data == CIL_KEY_SRC_INFO) { 6464 rc = cil_gen_src_info(parse_current, ast_node); 6465 } else { 6466 cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char *)parse_current->data); 6467 rc = SEPOL_ERR; 6468 } 6469 6470 if (rc == SEPOL_OK) { 6471 if (ast_current->cl_head == NULL) { 6472 if (ast_current->flavor == CIL_MACRO) { 6473 args->macro = ast_current; 6474 } 6475 6476 if (ast_current->flavor == CIL_BOOLEANIF) { 6477 args->boolif = ast_current; 6478 } 6479 6480 if (ast_current->flavor == CIL_TUNABLEIF) { 6481 args->tunif = ast_current; 6482 } 6483 6484 if (ast_current->flavor == CIL_IN) { 6485 args->in = ast_current; 6486 } 6487 6488 ast_current->cl_head = ast_node; 6489 } else { 6490 ast_current->cl_tail->next = ast_node; 6491 } 6492 ast_current->cl_tail = ast_node; 6493 ast_current = ast_node; 6494 args->ast = ast_current; 6495 } else { 6496 cil_tree_node_destroy(&ast_node); 6497 } 6498 6499 exit: 6500 return rc; 6501 } 6502 6503 int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args) 6504 { 6505 int rc = SEPOL_ERR; 6506 struct cil_tree_node *ast = NULL; 6507 struct cil_args_build *args = NULL; 6508 6509 if (extra_args == NULL) { 6510 goto exit; 6511 } 6512 6513 args = extra_args; 6514 ast = args->ast; 6515 6516 if (ast->flavor == CIL_ROOT) { 6517 rc = SEPOL_OK; 6518 goto exit; 6519 } 6520 6521 args->ast = ast->parent; 6522 6523 if (ast->flavor == CIL_MACRO) { 6524 args->macro = NULL; 6525 } 6526 6527 if (ast->flavor == CIL_BOOLEANIF) { 6528 args->boolif = NULL; 6529 } 6530 6531 if (ast->flavor == CIL_TUNABLEIF) { 6532 args->tunif = NULL; 6533 } 6534 6535 if (ast->flavor == CIL_IN) { 6536 args->in = NULL; 6537 } 6538 6539 // At this point we no longer have any need for parse_current or any of its 6540 // siblings; they have all been converted to the appropriate AST node. The 6541 // full parse tree will get deleted elsewhere, but in an attempt to 6542 // minimize memory useage (of which the parse tree uses alot), start 6543 // deleting the parts we don't need now. 6544 cil_tree_children_destroy(parse_current->parent); 6545 6546 return SEPOL_OK; 6547 6548 exit: 6549 return rc; 6550 } 6551 6552 int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct cil_tree_node *ast) 6553 { 6554 int rc = SEPOL_ERR; 6555 struct cil_args_build extra_args; 6556 6557 if (db == NULL || parse_tree == NULL || ast == NULL) { 6558 goto exit; 6559 } 6560 6561 extra_args.ast = ast; 6562 extra_args.db = db; 6563 extra_args.macro = NULL; 6564 extra_args.boolif = NULL; 6565 extra_args.tunif = NULL; 6566 extra_args.in = NULL; 6567 6568 rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, NULL, __cil_build_ast_last_child_helper, &extra_args); 6569 if (rc != SEPOL_OK) { 6570 goto exit; 6571 } 6572 6573 return SEPOL_OK; 6574 6575 exit: 6576 return rc; 6577 } 6578